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