コード例 #1
1
  public static void go0(String... expected) throws Exception {
    System.setProperty("sun.security.krb5.debug", "true");

    // Make sure KDCs' ports starts with 1 and 2 and 3,
    // useful for checking debug output.
    int p1 = 10000 + new java.util.Random().nextInt(10000);
    int p2 = 20000 + new java.util.Random().nextInt(10000);
    int p3 = 30000 + new java.util.Random().nextInt(10000);

    FileWriter fw = new FileWriter("alternative-krb5.conf");

    fw.write(
        "[libdefaults]\n"
            + "default_realm = "
            + OneKDC.REALM
            + "\n"
            + "kdc_timeout = "
            + toReal(2000)
            + "\n");
    fw.write(
        "[realms]\n"
            + OneKDC.REALM
            + " = {\n"
            + "kdc = "
            + OneKDC.KDCHOST
            + ":"
            + p1
            + "\n"
            + "kdc = "
            + OneKDC.KDCHOST
            + ":"
            + p2
            + "\n"
            + "kdc = "
            + OneKDC.KDCHOST
            + ":"
            + p3
            + "\n"
            + "}\n");

    fw.close();
    System.setProperty("java.security.krb5.conf", "alternative-krb5.conf");
    Config.refresh();

    // Turn on k3 only
    KDC k3 = on(p3);

    test(expected[0]);
    test(expected[1]);
    Config.refresh();
    test(expected[2]);

    k3.terminate(); // shutdown k3
    on(p2); // k2 is on
    test(expected[3]);
    on(p1); // k1 and k2 is on
    test(expected[4]);
  }
コード例 #2
0
 private static KDC on(int p) throws Exception {
   KDC k = new KDC(OneKDC.REALM, OneKDC.KDCHOST, p, true);
   k.addPrincipal(OneKDC.USER, OneKDC.PASS);
   k.addPrincipalRandKey("krbtgt/" + OneKDC.REALM);
   // Feed a packet to newly started KDC to warm it up
   System.err.println("-------- IGNORE THIS ERROR MESSAGE --------");
   new DatagramSocket()
       .send(new DatagramPacket("Hello".getBytes(), 5, InetAddress.getByName(OneKDC.KDCHOST), p));
   return k;
 }
コード例 #3
0
 /**
  * Start a KDC server: - create a KDC instance - create Kerberos principals - save Kerberos
  * configuration - save keys to keytab file - no pre-auth is required
  */
 private static void startKDC(String realm, Map<String, String> principals, String ktab) {
   try {
     KDC kdc = KDC.create(realm, HOST, 0, true);
     kdc.setOption(KDC.Option.PREAUTH_REQUIRED, Boolean.FALSE);
     if (principals != null) {
       principals
           .entrySet()
           .stream()
           .forEach(
               (entry) -> {
                 String name = entry.getKey();
                 String password = entry.getValue();
                 if (password == null || password.isEmpty()) {
                   System.out.println(
                       "KDC: add a principal '" + name + "' with a random password");
                   kdc.addPrincipalRandKey(name);
                 } else {
                   System.out.println(
                       "KDC: add a principal '" + name + "' with '" + password + "' password");
                   kdc.addPrincipal(name, password.toCharArray());
                 }
               });
     }
     KDC.saveConfig(KRB5_CONF_FILENAME, kdc);
     if (ktab != null) {
       File ktabFile = new File(ktab);
       if (ktabFile.exists()) {
         System.out.println("KDC: append keys to an exising " + "keytab file " + ktab);
         kdc.appendKtab(ktab);
       } else {
         System.out.println("KDC: create a new keytab file " + ktab);
         kdc.writeKtab(ktab);
       }
     }
     System.out.println(
         "KDC: started on " + HOST + ":" + kdc.getPort() + " with '" + realm + "' realm");
   } catch (Exception e) {
     throw new RuntimeException("KDC: unexpected exception", e);
   }
 }
コード例 #4
0
  /**
   * Creates the KDC and starts it.
   *
   * @param etype Encryption type, null if not specified
   * @throws java.lang.Exception if there's anything wrong
   */
  public OneKDC(String etype) throws Exception {
    super(REALM, KDCHOST, 0, true);
    addPrincipal(USER, PASS);
    addPrincipalRandKey("krbtgt/" + REALM);
    addPrincipalRandKey(SERVER);
    addPrincipalRandKey(BACKEND);
    KDC.saveConfig(
        KRB5_CONF,
        this,
        "forwardable = true",
        "default_keytab_name = " + KTAB,
        etype == null ? "" : "default_tkt_enctypes=" + etype + "\ndefault_tgs_enctypes=" + etype);
    System.setProperty("java.security.krb5.conf", KRB5_CONF);
    // Whatever krb5.conf had been loaded before, we reload ours now.
    Config.refresh();

    writeKtab(KTAB);
    new File(KRB5_CONF).deleteOnExit();
    new File(KTAB).deleteOnExit();
  }
コード例 #5
0
  void go() throws Exception {
    OneKDC k = new OneKDC(null);
    k.writeJAASConf();

    Files.delete(Paths.get(OneKDC.KTAB));

    // Starts with no keytab
    c = Context.fromJAAS("client");
    s = Context.fromJAAS("com.sun.security.jgss.krb5.accept");

    // Test 1: read new key 1 from keytab
    k.addPrincipal(OneKDC.SERVER, "pass1".toCharArray());
    k.writeKtab(OneKDC.KTAB);
    connect();

    // Test 2: service key cached, find 1 in keytab (now contains 1 and 2)
    k.addPrincipal(OneKDC.SERVER, "pass2".toCharArray());
    k.appendKtab(OneKDC.KTAB);
    connect();

    // Test 3: re-login. Now find 2 in keytab
    c = Context.fromJAAS("client");
    connect();

    // Test 4: re-login, KDC use 3 this time.
    c = Context.fromJAAS("client");
    // Put 3 and 4 into keytab but keep the real key back to 3.
    k.addPrincipal(OneKDC.SERVER, "pass3".toCharArray());
    k.appendKtab(OneKDC.KTAB);
    k.addPrincipal(OneKDC.SERVER, "pass4".toCharArray());
    k.appendKtab(OneKDC.KTAB);
    k.addPrincipal(OneKDC.SERVER, "pass3".toCharArray());
    connect();

    // Test 5: invalid keytab file, should ignore
    try (FileOutputStream fos = new FileOutputStream(OneKDC.KTAB)) {
      fos.write("BADBADBAD".getBytes());
    }
    connect();

    // Test 6: delete keytab file, identical to revoke all
    Files.delete(Paths.get(OneKDC.KTAB));
    try {
      connect();
      throw new Exception("Should not success");
    } catch (GSSException gsse) {
      System.out.println(gsse);
      KrbException ke = (KrbException) gsse.getCause();
      // KrbApReq.authenticate(*) if (dkey == null)...
      // This should have been Krb5.KRB_AP_ERR_NOKEY
      if (ke.returnCode() != Krb5.API_INVALID_ARG) {
        throw new Exception("Not expected failure code: " + ke.returnCode());
      }
    }

    // Test 7: 3 revoked, should fail (now contains only 5)
    k.addPrincipal(OneKDC.SERVER, "pass5".toCharArray());
    k.writeKtab(OneKDC.KTAB); // overwrite keytab, which means
    // old key is revoked
    try {
      connect();
      throw new Exception("Should not success");
    } catch (GSSException gsse) {
      System.out.println(gsse);
      // Since 7197159, different kvno is accepted, this return code
      // will never be thrown out again.
      // KrbException ke = (KrbException)gsse.getCause();
      // if (ke.returnCode() != Krb5.KRB_AP_ERR_BADKEYVER) {
      //    throw new Exception("Not expected failure code: " +
      //            ke.returnCode());
      // }
    }

    // Test 8: an empty KDC means revoke all
    KDC.create("EMPTY.REALM").writeKtab(OneKDC.KTAB);
    try {
      connect();
      throw new Exception("Should not success");
    } catch (GSSException gsse) {
      System.out.println(gsse);
      KrbException ke = (KrbException) gsse.getCause();
      // KrbApReq.authenticate(*) if (dkey == null)...
      // This should have been Krb5.KRB_AP_ERR_NOKEY
      if (ke.returnCode() != Krb5.API_INVALID_ARG) {
        throw new Exception("Not expected failure code: " + ke.returnCode());
      }
    }
  }