Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/Java/Openjdk/test/jdk/sun/security/krb5/auto/   (Sun/Oracle ©)  Datei vom 13.11.2022 mit Größe 13 kB image not shown  

Quelle  HttpsCB.java   Sprache: JAVA

 
/*
 * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */


/*
 * @test
 * @bug 8279842 8282293
 * @modules java.base/sun.security.util
 *          java.security.jgss/sun.security.jgss
 *          java.security.jgss/sun.security.jgss.krb5
 *          java.security.jgss/sun.security.jgss.krb5.internal
 *          java.security.jgss/sun.security.krb5.internal:+open
 *          java.security.jgss/sun.security.krb5:+open
 *          java.security.jgss/sun.security.krb5.internal.ccache
 *          java.security.jgss/sun.security.krb5.internal.crypto
 *          java.security.jgss/sun.security.krb5.internal.ktab
 *          jdk.security.auth
 *          jdk.security.jgss
 *          jdk.httpserver
 * @summary HTTPS Channel Binding support for Java GSS/Kerberos
 * @library /test/lib
 * @run main jdk.test.lib.FileInstaller TestHosts TestHosts
 * @run main/othervm -Djdk.net.hosts.file=TestHosts
 *          -Djdk.https.negotiate.cbt=always HttpsCB true true
 * @run main/othervm -Djdk.net.hosts.file=TestHosts
 *          -Djdk.https.negotiate.cbt=never HttpsCB false true
 * @run main/othervm -Djdk.net.hosts.file=TestHosts
 *          -Djdk.https.negotiate.cbt=invalid HttpsCB false true
 * @run main/othervm -Djdk.net.hosts.file=TestHosts
 *          HttpsCB false true
 * @run main/othervm -Djdk.net.hosts.file=TestHosts
 *          -Djdk.https.negotiate.cbt=domain:other.com HttpsCB false true
 * @run main/othervm -Djdk.net.hosts.file=TestHosts
 *          -Djdk.https.negotiate.cbt=domain:host.web.domain HttpsCB true true
 * @run main/othervm -Djdk.net.hosts.file=TestHosts
 *          -Djdk.https.negotiate.cbt=domain:HOST.WEB.DOMAIN HttpsCB true true
 * @run main/othervm -Djdk.net.hosts.file=TestHosts
 *          -Djdk.https.negotiate.cbt=domain:*.web.domain HttpsCB true true
 * @run main/othervm -Djdk.net.hosts.file=TestHosts
 *          -Djdk.https.negotiate.cbt=domain:*.WEB.Domain HttpsCB true true
 * @run main/othervm -Djdk.net.hosts.file=TestHosts
 *          -Djdk.https.negotiate.cbt=domain:*.Invalid,*.WEB.Domain HttpsCB true true
 */


import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
import com.sun.net.httpserver.HttpPrincipal;
import com.sun.net.httpserver.HttpsConfigurator;
import com.sun.net.httpserver.HttpsExchange;
import com.sun.net.httpserver.HttpsServer;
import com.sun.security.auth.module.Krb5LoginModule;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.PasswordAuthentication;
import java.net.Proxy;
import java.net.Socket;
import java.net.URL;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.Map;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509ExtendedTrustManager;
import javax.security.auth.Subject;

import jdk.test.lib.Asserts;
import jdk.test.lib.net.SimpleSSLContext;
import org.ietf.jgss.GSSContext;
import org.ietf.jgss.GSSCredential;
import org.ietf.jgss.GSSManager;
import sun.security.jgss.GSSUtil;
import sun.security.jgss.krb5.internal.TlsChannelBindingImpl;
import sun.security.krb5.Config;
import sun.security.util.TlsChannelBinding;

import java.util.Base64;
import java.util.concurrent.Callable;

public class HttpsCB {

    final static String REALM_WEB = "WEB.DOMAIN";
    final static String KRB5_CONF = "web.conf";
    final static String KRB5_TAB = "web.ktab";

    final static String WEB_USER = "web";
    final static char[] WEB_PASS = "webby".toCharArray();
    final static String WEB_HOST = "host.web.domain";
    final static String CONTENT = "Hello, World!";

    static int webPort;
    static URL cbtURL;
    static URL normalURL;

    public static void main(String[] args)
            throws Exception {

        boolean expectCBT = Boolean.parseBoolean(args[0]);
        boolean expectNoCBT = Boolean.parseBoolean(args[1]);

        System.setProperty("sun.security.krb5.debug""true");

        KDC kdcw = KDC.create(REALM_WEB);
        kdcw.addPrincipal(WEB_USER, WEB_PASS);
        kdcw.addPrincipalRandKey("krbtgt/" + REALM_WEB);
        kdcw.addPrincipalRandKey("HTTP/" + WEB_HOST);

        KDC.saveConfig(KRB5_CONF, kdcw,
                "default_keytab_name = " + KRB5_TAB,
                "[domain_realm]",
                "",
                ".web.domain="+REALM_WEB);

        System.setProperty("java.security.krb5.conf", KRB5_CONF);
        Config.refresh();
        KDC.writeMultiKtab(KRB5_TAB, kdcw);

        // Write a customized JAAS conf file, so that any kinit cache
        // will be ignored.
        System.setProperty("java.security.auth.login.config", OneKDC.JAAS_CONF);
        File f = new File(OneKDC.JAAS_CONF);
        FileOutputStream fos = new FileOutputStream(f);
        fos.write((
                "com.sun.security.jgss.krb5.initiate {\n" +
                " com.sun.security.auth.module.Krb5LoginModule required;\n};\n"
                ).getBytes());
        fos.close();

        HttpServer h1 = httpd("Negotiate",
                "HTTP/" + WEB_HOST + "@" + REALM_WEB, KRB5_TAB);
        webPort = h1.getAddress().getPort();

        cbtURL = new URL("https://" + WEB_HOST +":" + webPort + "/cbt");
        normalURL = new URL("https://" + WEB_HOST +":" + webPort + "/normal");

        java.net.Authenticator.setDefault(new java.net.Authenticator() {
            public PasswordAuthentication getPasswordAuthentication () {
                return new PasswordAuthentication(
                        WEB_USER+"@"+REALM_WEB, WEB_PASS);
            }
        });

        // Client-side SSLContext needs to ignore hostname mismatch
        // and untrusted certificate.
        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(nullnew TrustManager[] {
                new X509ExtendedTrustManager() {
                    public X509Certificate[] getAcceptedIssuers() {
                        return null;
                    }
                    public void checkClientTrusted(X509Certificate[] chain,
                            String authType, Socket socket) { }
                    public void checkServerTrusted(X509Certificate[] chain,
                            String authType, Socket socket) { }
                    public void checkClientTrusted(X509Certificate[] chain,
                            String authType, SSLEngine engine) { }
                    public void checkServerTrusted(X509Certificate[] chain,
                            String authType, SSLEngine engine) { }
                    public void checkClientTrusted(X509Certificate[] certs,
                            String authType) { }
                    public void checkServerTrusted(X509Certificate[] certs,
                            String authType) { }
                }
        }, null);

        Asserts.assertEQ(visit(sc, cbtURL), expectCBT);
        Asserts.assertEQ(visit(sc, normalURL), expectNoCBT);
    }

    static boolean visit(SSLContext sc, URL url) {
        try {
            HttpsURLConnection conn = (HttpsURLConnection)
                    url.openConnection(Proxy.NO_PROXY);
            conn.setSSLSocketFactory(sc.getSocketFactory());
            BufferedReader reader;
            reader = new BufferedReader(new InputStreamReader(
                    conn.getInputStream()));
            return reader.readLine().equals(CONTENT);
        } catch (IOException e) {
            e.printStackTrace(System.out);
            return false;
        }
    }

    static HttpServer httpd(String scheme, String principal, String ktab)
            throws Exception {
        MyHttpHandler h = new MyHttpHandler();
        HttpsServer server = HttpsServer.create(new InetSocketAddress(0), 0);
        server.setHttpsConfigurator(
                new HttpsConfigurator(new SimpleSSLContext().get()));
        server.createContext("/", h).setAuthenticator(
                new MyServerAuthenticator(scheme, principal, ktab));
        server.start();
        return server;
    }

    static class MyHttpHandler implements HttpHandler {
        public void handle(HttpExchange t) throws IOException {
            t.sendResponseHeaders(200, 0);
            t.getResponseBody().write(CONTENT.getBytes());
            t.close();
        }
    }

    static class MyServerAuthenticator
            extends com.sun.net.httpserver.Authenticator {
        Subject s = new Subject();
        GSSManager m;
        GSSCredential cred;
        String scheme = null;
        String reqHdr = "WWW-Authenticate";
        String respHdr = "Authorization";
        int err = HttpURLConnection.HTTP_UNAUTHORIZED;

        public MyServerAuthenticator(String scheme,
                String principal, String ktab) throws Exception {

            this.scheme = scheme;
            Krb5LoginModule krb5 = new Krb5LoginModule();
            Map<String, String> map = new HashMap<>();
            Map<String, Object> shared = new HashMap<>();

            map.put("storeKey""true");
            map.put("isInitiator""false");
            map.put("useKeyTab""true");
            map.put("keyTab", ktab);
            map.put("principal", principal);
            krb5.initialize(s, null, shared, map);
            krb5.login();
            krb5.commit();
            m = GSSManager.getInstance();
            cred = Subject.callAs(s, new Callable<GSSCredential>() {
                @Override
                public GSSCredential call() throws Exception {
                    System.err.println("Creating GSSCredential");
                    return m.createCredential(
                            null,
                            GSSCredential.INDEFINITE_LIFETIME,
                            MyServerAuthenticator.this.scheme
                                        .equalsIgnoreCase("Negotiate") ?
                                    GSSUtil.GSS_SPNEGO_MECH_OID :
                                    GSSUtil.GSS_KRB5_MECH_OID,
                            GSSCredential.ACCEPT_ONLY);
                }
            });
        }

        @Override
        public Result authenticate(HttpExchange exch) {
            // The GSContext is stored in an HttpContext attribute named
            // "GSSContext" and is created at the first request.
            GSSContext c = null;
            String auth = exch.getRequestHeaders().getFirst(respHdr);
            try {
                c = (GSSContext)exch.getHttpContext()
                        .getAttributes().get("GSSContext");
                if (auth == null) {                 // First request
                    Headers map = exch.getResponseHeaders();
                    map.set (reqHdr, scheme);        // Challenge!
                    c = Subject.callAs(s, () -> m.createContext(cred));
                    // CBT is required for cbtURL
                    if (exch instanceof HttpsExchange sexch
                            && exch.getRequestURI().toString().equals("/cbt")) {
                        TlsChannelBinding b = TlsChannelBinding.create(
                                (X509Certificate) sexch.getSSLSession()
                                        .getLocalCertificates()[0]);
                        c.setChannelBinding(
                                new TlsChannelBindingImpl(b.getData()));
                    }
                    exch.getHttpContext().getAttributes().put("GSSContext", c);
                    return new com.sun.net.httpserver.Authenticator.Retry(err);
                } else {                            // Later requests
                    byte[] token = Base64.getMimeDecoder()
                            .decode(auth.split(" ")[1]);
                    token = c.acceptSecContext(token, 0, token.length);
                    Headers map = exch.getResponseHeaders();
                    map.set (reqHdr, scheme + " " + Base64.getMimeEncoder()
                            .encodeToString(token).replaceAll("\\s"""));
                    if (c.isEstablished()) {
                        return new com.sun.net.httpserver.Authenticator.Success(
                                new HttpPrincipal(c.getSrcName().toString(), ""));
                    } else {
                        return new com.sun.net.httpserver.Authenticator.Retry(err);
                    }
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    }
}

Messung V0.5
C=91 H=95 G=92

¤ Dauer der Verarbeitung: 0.17 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.