Home | History | Annotate | Download | only in module
      1 /*
      2  *  Licensed to the Apache Software Foundation (ASF) under one or more
      3  *  contributor license agreements.  See the NOTICE file distributed with
      4  *  this work for additional information regarding copyright ownership.
      5  *  The ASF licenses this file to You under the Apache License, Version 2.0
      6  *  (the "License"); you may not use this file except in compliance with
      7  *  the License.  You may obtain a copy of the License at
      8  *
      9  *     http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  */
     17 
     18 package org.apache.harmony.auth.tests.module;
     19 
     20 import java.io.IOException;
     21 import java.net.DatagramPacket;
     22 import java.net.DatagramSocket;
     23 import java.util.TreeMap;
     24 
     25 import javax.security.auth.callback.Callback;
     26 import javax.security.auth.callback.CallbackHandler;
     27 import javax.security.auth.login.LoginException;
     28 
     29 import junit.framework.TestCase;
     30 
     31 import org.apache.harmony.auth.module.Krb5LoginModule;
     32 import org.apache.harmony.auth.tests.internal.kerberos.v5.KerberosErrorMessageTest;
     33 import org.apache.harmony.auth.tests.support.TestUtils;
     34 
     35 public class Krb5LoginModuleTest extends TestCase {
     36 
     37     // default kdc server
     38     private static final String ENV_KDC = "java.security.krb5.kdc";
     39 
     40     // default realm
     41     private static final String ENV_REALM = "java.security.krb5.realm";
     42 
     43     // old value of 'java.security.krb5.kdc' system property
     44     private String kdc;
     45 
     46     // old value of 'java.security.krb5.realm' system property
     47     private String realm;
     48 
     49     // embedded server
     50     private KrbServer server;
     51 
     52     // module options
     53     private final TreeMap<String, String> options = new TreeMap<String, String>();
     54 
     55     /**
     56      * Sets system env. properties and optionally starts local mock server
     57      */
     58     @Override
     59     protected void setUp() throws Exception {
     60 
     61         // save old system properties
     62         kdc = System.getProperty(ENV_KDC);
     63         realm = System.getProperty(ENV_REALM);
     64 
     65         if (kdc == null) {
     66             // run test with embedded server
     67             server = new KrbServer();
     68 
     69             server.start();
     70             while (server.port == 0) {
     71                 // wait until server open datagram socket
     72             }
     73 
     74             System.setProperty(ENV_KDC, "localhost:" + server.port);
     75         } // else: run test with external server
     76 
     77         System.setProperty(ENV_REALM, "MY.REALM");
     78     }
     79 
     80     /**
     81      * Shuts down local server and restore system env. properties
     82      */
     83     @Override
     84     protected void tearDown() throws Exception {
     85         if (server != null) {
     86             // shut down local server
     87             server.interrupt();
     88         }
     89 
     90         // restore env. variables
     91         TestUtils.setSystemProperty(ENV_KDC, kdc);
     92         TestUtils.setSystemProperty(ENV_REALM, realm);
     93     }
     94 
     95     /**
     96      * TODO
     97      */
     98     public void test_Config() throws Exception {
     99 
    100         // create login module for testing
    101         Krb5LoginModule module = new Krb5LoginModule();
    102         module.initialize(null, new MockCallbackHandler(), null, options);
    103 
    104         // case 1: unset 'kdc' and set 'real' sys.props
    105         TestUtils.setSystemProperty(ENV_KDC, null);
    106         TestUtils.setSystemProperty(ENV_REALM, "some_value");
    107         try {
    108             module.login();
    109             fail("No expected LoginException");
    110         } catch (LoginException e) {
    111         }
    112 
    113         // case 2: set 'kdc' and unset 'real' sys.props
    114         TestUtils.setSystemProperty(ENV_KDC, "some_value");
    115         TestUtils.setSystemProperty(ENV_REALM, null);
    116         try {
    117             module.login();
    118             fail("No expected LoginException");
    119         } catch (LoginException e) {
    120         }
    121 
    122         //TODO: test reading config from configuration file 'krb5.conf'
    123     }
    124 
    125     /**
    126      * @tests request ticket for absent user
    127      */
    128     public void test_login() throws Exception {
    129 
    130         if (server != null) {
    131             server.respond = KerberosErrorMessageTest.err_resp;
    132         }
    133 
    134         Krb5LoginModule module = new Krb5LoginModule();
    135 
    136         options.put("principal", "no_such_user");
    137 
    138         module.initialize(null, null, null, options);
    139         try {
    140             module.login();
    141             fail("No expected LoginException");
    142         } catch (LoginException e) {
    143             System.out.println(e);
    144         }
    145     }
    146 
    147     /**
    148      * Mock callback handler
    149      */
    150     static class MockCallbackHandler implements CallbackHandler {
    151 
    152         public MockCallbackHandler() {
    153         }
    154 
    155         public void handle(Callback[] callbacks) {
    156         }
    157     }
    158 
    159     /**
    160      * Embedded test server
    161      */
    162     static class KrbServer extends Thread {
    163 
    164         private static boolean debug = false;
    165 
    166         private static final int BUF_SIZE = 1024;
    167 
    168         public int port;
    169 
    170         public byte[] respond;
    171 
    172         @Override
    173         public void run() {
    174 
    175             try {
    176                 DatagramSocket socket = new DatagramSocket();
    177 
    178                 port = socket.getLocalPort();
    179 
    180                 byte[] request = new byte[BUF_SIZE];
    181                 DatagramPacket packet = new DatagramPacket(request,
    182                         request.length);
    183 
    184                 int bytesRead = BUF_SIZE;
    185                 while (bytesRead == BUF_SIZE) {
    186                     socket.receive(packet);
    187                     bytesRead = packet.getLength();
    188                 }
    189 
    190                 printAsHex(10, "(byte)", ",", request);
    191 
    192                 if (respond != null) {
    193                     packet = new DatagramPacket(respond, respond.length, packet
    194                             .getAddress(), packet.getPort());
    195                     socket.send(packet);
    196                 }
    197             } catch (IOException e) {
    198                 e.printStackTrace();
    199             }
    200         }
    201 
    202         public static void printAsHex(int perLine, String prefix,
    203                 String delimiter, byte[] data) {
    204 
    205             if (!debug) {
    206                 return;
    207             }
    208 
    209             for (int i = 0; i < data.length; i++) {
    210                 String tail = Integer.toHexString(0x000000ff & data[i]);
    211                 if (tail.length() == 1) {
    212                     tail = "0" + tail;
    213                 }
    214                 System.out.print(prefix + "0x" + tail + delimiter);
    215 
    216                 if (((i + 1) % perLine) == 0) {
    217                     System.out.println("");
    218                 }
    219             }
    220             System.out.println("");
    221         }
    222     }
    223 }
    224