1 /*
   2  * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25  * @test
  26  * @bug 6952519
  27  * @compile -XDignore.symbol.file TcpTimeout.java
  28  * @run main/othervm -Dsun.net.spi.nameservice.provider.1=ns,mock TcpTimeout
  29  * @summary kdc_timeout is not being honoured when using TCP
  30  */
  31 
  32 import java.io.*;
  33 import java.net.ServerSocket;
  34 import sun.security.krb5.Config;
  35 
  36 public class TcpTimeout {
  37     public static void main(String[] args)
  38             throws Exception {
  39 
  40         // Set debug to grab debug output like ">>> KDCCommunication"
  41         System.setProperty("sun.security.krb5.debug", "true");
  42 
  43         // Called before new ServerSocket on p1 and p2 to make sure
  44         // customized nameservice is used
  45         KDC k = new KDC(OneKDC.REALM, OneKDC.KDCHOST, 0, true);
  46         int p3 = k.getPort();
  47         k.addPrincipal(OneKDC.USER, OneKDC.PASS);
  48         k.addPrincipalRandKey("krbtgt/" + OneKDC.REALM);
  49 
  50         // Start two listener that does not communicate, simulate timeout
  51         ServerSocket ss1 = null;
  52         ServerSocket ss2 = null;
  53 
  54         try {
  55             ss1 = new ServerSocket(0);
  56             ss2 = new ServerSocket(0);
  57             int p1 = ss1.getLocalPort();
  58             int p2 = ss2.getLocalPort();
  59 
  60             FileWriter fw = new FileWriter("alternative-krb5.conf");
  61 
  62             fw.write("[libdefaults]\n" +
  63                     "udp_preference_limit = 1\n" +
  64                     "max_retries = 2\n" +
  65                     "default_realm = " + OneKDC.REALM + "\n" +
  66                     "kdc_timeout = " + BadKdc.toReal(5000) + "\n");
  67             fw.write("[realms]\n" + OneKDC.REALM + " = {\n" +
  68                     "kdc = " + OneKDC.KDCHOST + ":" + p1 + "\n" +
  69                     "kdc = " + OneKDC.KDCHOST + ":" + p2 + "\n" +
  70                     "kdc = " + OneKDC.KDCHOST + ":" + p3 + "\n" +
  71                     "}\n");
  72 
  73             fw.close();
  74             System.setProperty("java.security.krb5.conf",
  75                     "alternative-krb5.conf");
  76             Config.refresh();
  77 
  78             System.out.println("Ports opened on " + p1 + ", " + p2 + ", " + p3);
  79 
  80             // The correct behavior should be:
  81             // 5 sec on p1, 5 sec on p1, fail
  82             // 5 sec on p2, 5 sec on p2, fail
  83             // p3 ok, p3 ok again for preauth.
  84             int count = 6;
  85 
  86             ByteArrayOutputStream bo = new ByteArrayOutputStream();
  87             PrintStream oldout = System.out;
  88             System.setOut(new PrintStream(bo));
  89             Context c = Context.fromUserPass(OneKDC.USER, OneKDC.PASS, false);
  90             System.setOut(oldout);
  91 
  92             String[] lines = new String(bo.toByteArray()).split("\n");
  93             for (String line: lines) {
  94                 if (line.startsWith(">>> KDCCommunication")) {
  95                     System.out.println(line);
  96                     count--;
  97                 }
  98             }
  99             if (count != 0) {
 100                 throw new Exception("Retry count is " + count + " less");
 101             }
 102         } finally {
 103             if (ss1 != null) ss1.close();
 104             if (ss2 != null) ss2.close();
 105         }
 106     }
 107 }