├── .gitignore ├── JavaBuild.sh ├── README ├── README.md ├── build.xml ├── docs └── kerberos_gssapi_wrapper.pdf ├── examples ├── GssUtil.java ├── Util.java ├── client.java ├── client.sh ├── gssClient.java ├── gssClient.sh ├── gssServer.java ├── gssServer.sh ├── server.java └── server.sh ├── gsswrapper.i ├── native └── gsswrapper_wrap.h └── src ├── java ├── edu │ └── mit │ │ └── jgss │ │ ├── ChannelBindingImpl.java │ │ ├── DerHeader.java │ │ ├── DerUtil.java │ │ ├── GSSContextImpl.java │ │ ├── GSSCredentialImpl.java │ │ ├── GSSExceptionImpl.java │ │ ├── GSSManagerImpl.java │ │ ├── GSSNameImpl.java │ │ ├── OidImpl.java │ │ ├── OidUtil.java │ │ └── swig │ │ └── .gitignore └── org │ └── ietf │ └── jgss │ ├── ChannelBinding.java │ ├── GSSContext.java │ ├── GSSCredential.java │ ├── GSSException.java │ ├── GSSManager.java │ ├── GSSName.java │ ├── MessageProp.java │ └── Oid.java └── test ├── junit-4.10.jar └── org └── ietf └── jgss ├── ChannelBindingTest.java ├── GSSNameTest.java ├── JUnit4Suite.java ├── MessagePropTest.java └── OidTest.java /.gitignore: -------------------------------------------------------------------------------- 1 | src/java/edu/mit/jgss/swig/* 2 | native/gsswrapper_wrap.c 3 | -------------------------------------------------------------------------------- /JavaBuild.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 4 | # Description: This shell script generates the Java GSS-API interface for 5 | # the MIT Kerberos libraries. 6 | 7 | # Notes: The paths to Java and Kerberos locations should be updated to match 8 | # the setup of the development machine which this script is being run 9 | # on. 10 | # 11 | # If building on OS X: 12 | # 13 | # 1) The Java include directory is usually similar to: 14 | # /System/Library/Frameworks/JavaVM.framework/Versions/A/Headers 15 | 16 | # 2) The shared library extension should be .dylib (libgsswrapper.dylib) 17 | # instead of .so. 18 | # 19 | # Original source developed by wolfSSL (http://www.wolfssl.com) 20 | # 21 | 22 | # Generate the SWIG GSS-API interface 23 | swig -java -package edu.mit.jgss.swig -outdir ./src/java/edu/mit/jgss/swig -o ./native/gsswrapper_wrap.c gsswrapper.i 24 | 25 | # Compile and link libgsswrapper.so (.dylib) 26 | gcc -c ./native/gsswrapper_wrap.c -I/usr/lib/jvm/java-6-openjdk/include -I/usr/local/include/gssapi -o ./native/gsswrapper_wrap.o 27 | gcc -shared ./native/gsswrapper_wrap.o -L/usr/local/lib -lgssapi_krb5 -lkrb5 -lk5crypto -lcom_err -lkrb5support -o ./native/libgsswrapper.so 28 | 29 | 30 | -------------------------------------------------------------------------------- /build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 92 | 93 | 94 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 121 | 122 | 123 | 124 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | -------------------------------------------------------------------------------- /docs/kerberos_gssapi_wrapper.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cconlon/kerberos-java-gssapi/1a70d4c68d2b59a3b61a70fb299753d4fbacc0cf/docs/kerberos_gssapi_wrapper.pdf -------------------------------------------------------------------------------- /examples/GssUtil.java: -------------------------------------------------------------------------------- 1 | /* GssUtil.java - Example GSS-API Utility functions*/ 2 | /* 3 | * Copyright (C) 2012 by the Massachusetts Institute of Technology. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * * Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 13 | * * Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in 15 | * the documentation and/or other materials provided with the 16 | * distribution. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 21 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 22 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 27 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 29 | * OF THE POSSIBILITY OF SUCH DAMAGE. 30 | */ 31 | 32 | /* 33 | * Original source developed by wolfSSL (http://www.wolfssl.com) 34 | * 35 | * Description: 36 | * 37 | * Java MIT Kerberos GSS-API interface utility functions. This class 38 | * is used by the example GSS-API client and server (gssClient.java, 39 | * gssServer.java). It has some duplicate functionality of Util.java, 40 | * but doesn't directly import any of the edu.mit.jgss.swig classes 41 | * like Util.java does. 42 | * 43 | */ 44 | import java.io.*; 45 | import java.net.*; 46 | 47 | public class GssUtil { 48 | 49 | private static boolean DEBUG = false; 50 | 51 | /* 52 | * Write a token byte[] to OutputStream. 53 | * Return: 0 on success, -1 on failure 54 | */ 55 | public static int WriteToken(OutputStream outStream, byte[] outputToken) 56 | { 57 | if (DEBUG) 58 | System.out.println("Entered WriteToken..."); 59 | 60 | try { 61 | 62 | /* First send the size of our byte array */ 63 | byte[] size = Util.intToByteArray(outputToken.length); 64 | 65 | if (DEBUG) 66 | System.out.println("... sending byte array size: " + 67 | Util.byteArrayToInt(size)); 68 | outStream.write(size); 69 | 70 | /* Now send our actual byte array */ 71 | if (DEBUG) { 72 | System.out.println("... sending byte array: "); 73 | printByteArray(outputToken); 74 | System.out.println("... outputToken.length = " + 75 | outputToken.length); 76 | } 77 | outStream.write(outputToken); 78 | 79 | return 0; 80 | 81 | } catch (IOException e) { 82 | 83 | e.printStackTrace(); 84 | return -1; 85 | 86 | } 87 | } 88 | 89 | /* 90 | * Read a token byte[] from InputStream. 91 | * Return byte[] on success, null on failure 92 | */ 93 | public static byte[] ReadToken(InputStream inStream) 94 | { 95 | if (DEBUG) 96 | System.out.println("Entered ReadToken..."); 97 | 98 | byte[] inputTokenBuffer = null; 99 | 100 | try { 101 | 102 | int data; 103 | ByteArrayOutputStream out = new ByteArrayOutputStream(); 104 | 105 | /* First read the incomming array size (first 4 bytes) */ 106 | int array_size = 0; 107 | byte[] temp = null; 108 | for (int i = 0; i < 4; i++) { 109 | data = inStream.read(); 110 | if (DEBUG) 111 | System.out.println("ReadToken... read() returned: " + data); 112 | out.write(data); 113 | } 114 | temp = out.toByteArray(); 115 | array_size = Util.byteArrayToInt(temp); 116 | out.reset(); 117 | 118 | if (DEBUG) 119 | System.out.println("... got byte array size = " + array_size); 120 | 121 | if (array_size < 0) 122 | return null; 123 | 124 | /* Now read our full array */ 125 | for (int j = 0; j < array_size; j++) { 126 | data = inStream.read(); 127 | out.write(data); 128 | } 129 | 130 | if (DEBUG) { 131 | System.out.println("... got data: "); 132 | Util.printByteArray(out.toByteArray()); 133 | System.out.println("... returning from ReadToken, success"); 134 | } 135 | 136 | return out.toByteArray(); 137 | 138 | } catch (IOException e) { 139 | e.printStackTrace(); 140 | return null; 141 | } 142 | } 143 | 144 | /* 145 | * Print a byte[], for debug purposes. 146 | */ 147 | public static void printByteArray(byte[] input) 148 | { 149 | for (int i = 0; i < input.length; i++ ) { 150 | System.out.format("%02X ", input[i]); 151 | } 152 | System.out.println(); 153 | } 154 | 155 | /* Based on http://snippets.dzone.com/posts/show/93 */ 156 | public static byte[] intToByteArray(int input) 157 | { 158 | byte[] out = new byte[4]; 159 | for (int i = 0; i < 4; i++) { 160 | int offset = (out.length - 1 - i) * 8; 161 | out[i] = (byte) ((input >>> offset) & 0xFF); 162 | } 163 | return out; 164 | } 165 | 166 | /* Based on http://snippets.dzone.com/posts/show/93 */ 167 | public static int byteArrayToInt(byte[] data) 168 | { 169 | if (data == null || data.length != 4) return 0x0; 170 | return (int)( 171 | (0xff & data[0]) << 24 | 172 | (0xff & data[1]) << 16 | 173 | (0xff & data[2]) << 8 | 174 | (0xff & data[3]) << 0 175 | ); 176 | } 177 | 178 | public static void printSubString(String first, String second) { 179 | System.out.printf(" | %-18s= %s\n", first, second); 180 | } 181 | public static void printSubString(String first, boolean second) { 182 | String s = new Boolean(second).toString(); 183 | printSubString(first, s); 184 | } 185 | public static void printSubString(String first, int second) { 186 | String s = new Integer(second).toString(); 187 | printSubString(first, s); 188 | } 189 | } 190 | -------------------------------------------------------------------------------- /examples/Util.java: -------------------------------------------------------------------------------- 1 | /* Util.java - Example GSS-API Utility functions*/ 2 | /* 3 | * Copyright (C) 2012 by the Massachusetts Institute of Technology. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * * Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 13 | * * Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in 15 | * the documentation and/or other materials provided with the 16 | * distribution. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 21 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 22 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 27 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 29 | * OF THE POSSIBILITY OF SUCH DAMAGE. 30 | */ 31 | 32 | /* 33 | * Original source developed by wolfSSL (http://www.wolfssl.com) 34 | * 35 | * Description: 36 | * Java MIT Kerberos GSS-API interface utility functions. 37 | * 38 | */ 39 | import java.io.*; 40 | import java.net.*; 41 | import edu.mit.jgss.swig.*; 42 | 43 | public class Util implements gsswrapperConstants{ 44 | 45 | private static boolean DEBUG = false; 46 | 47 | /* 48 | * Display error and exit program. 49 | */ 50 | public static void errorExit(String msg, long[] min_stat, long maj_stat) 51 | { 52 | System.out.println("Error: " + msg); 53 | System.out.println("maj_stat = " + maj_stat + ", min_stat = " 54 | + (int)min_stat[0]); 55 | display_status(min_stat, maj_stat); 56 | System.exit(1); 57 | } 58 | 59 | /* 60 | * Display error and continue. 61 | */ 62 | public static void displayError(String msg, long[] min_stat, long maj_stat) 63 | { 64 | System.out.println("Error: " + msg); 65 | System.out.println("maj_stat = " + maj_stat + ", min_stat = " 66 | + (int)min_stat[0]); 67 | display_status(min_stat, maj_stat); 68 | } 69 | 70 | /* 71 | * Display status using minor and major status codes 72 | */ 73 | public static void display_status(long[] min_stat, long maj_stat) 74 | { 75 | long[] msg_ctx = {0}; 76 | long ret = 0; 77 | gss_buffer_desc storage_buffer = new gss_buffer_desc(); 78 | 79 | // Print GSS major status code error 80 | ret = gsswrapper.gss_display_status_wrap(min_stat[0], maj_stat, 81 | GSS_C_GSS_CODE, 82 | GSS_C_NO_OID, 83 | msg_ctx, storage_buffer); 84 | if (ret != GSS_S_COMPLETE) { 85 | System.out.println("gss_display_status failed"); 86 | System.exit(1); 87 | } 88 | System.out.println("Error message (major): " 89 | + storage_buffer.getValue()); 90 | 91 | // Print mechanism minor status code error 92 | ret = gsswrapper.gss_display_status_wrap(maj_stat, min_stat[0], 93 | GSS_C_MECH_CODE, 94 | GSS_C_NO_OID, msg_ctx, storage_buffer); 95 | if (ret != GSS_S_COMPLETE) { 96 | System.out.println("gss_display_status failed"); 97 | System.exit(1); 98 | } 99 | System.out.println("Error message (minor): " 100 | + storage_buffer.getValue()); 101 | } 102 | 103 | /* 104 | * Write a token byte[] to OutputStream. 105 | * Return: 0 on success, -1 on failure 106 | */ 107 | public static int WriteToken(OutputStream outStream, byte[] outputToken) 108 | { 109 | if (DEBUG) 110 | System.out.println("Entered WriteToken..."); 111 | 112 | try { 113 | 114 | /* First send the size of our byte array */ 115 | byte[] size = Util.intToByteArray(outputToken.length); 116 | 117 | if (DEBUG) 118 | System.out.println("... sending byte array size: " + 119 | Util.byteArrayToInt(size)); 120 | outStream.write(size); 121 | 122 | /* Now send our actual byte array */ 123 | if (DEBUG) { 124 | System.out.println("... sending byte array: "); 125 | printByteArray(outputToken); 126 | System.out.println("... outputToken.length = " + 127 | outputToken.length); 128 | } 129 | outStream.write(outputToken); 130 | 131 | return 0; 132 | 133 | } catch (IOException e) { 134 | 135 | e.printStackTrace(); 136 | return -1; 137 | 138 | } 139 | } 140 | 141 | /* 142 | * Read a token byte[] from InputStream. 143 | * Return byte[] on success, null on failure 144 | */ 145 | public static byte[] ReadToken(InputStream inStream) 146 | { 147 | if (DEBUG) 148 | System.out.println("Entered ReadToken..."); 149 | 150 | byte[] inputTokenBuffer = null; 151 | 152 | try { 153 | 154 | int data; 155 | ByteArrayOutputStream out = new ByteArrayOutputStream(); 156 | 157 | /* First read the incomming array size (first 4 bytes) */ 158 | int array_size = 0; 159 | byte[] temp = null; 160 | for (int i = 0; i < 4; i++) { 161 | data = inStream.read(); 162 | if (DEBUG) 163 | System.out.println("ReadToken... read() returned: " + data); 164 | out.write(data); 165 | } 166 | temp = out.toByteArray(); 167 | array_size = Util.byteArrayToInt(temp); 168 | out.reset(); 169 | 170 | if (DEBUG) 171 | System.out.println("... got byte array size = " + array_size); 172 | 173 | if (array_size < 0) 174 | return null; 175 | 176 | /* Now read our full array */ 177 | for (int j = 0; j < array_size; j++) { 178 | data = inStream.read(); 179 | out.write(data); 180 | } 181 | 182 | if (DEBUG) { 183 | System.out.println("... got data: "); 184 | Util.printByteArray(out.toByteArray()); 185 | System.out.println("... returning from ReadToken, success"); 186 | } 187 | 188 | return out.toByteArray(); 189 | 190 | } catch (IOException e) { 191 | e.printStackTrace(); 192 | return null; 193 | } 194 | } 195 | 196 | /* 197 | * Print a byte[], for debug purposes. 198 | */ 199 | public static void printByteArray(byte[] input) 200 | { 201 | for (int i = 0; i < input.length; i++ ) { 202 | System.out.format("%02X ", input[i]); 203 | } 204 | System.out.println(); 205 | } 206 | 207 | /* Based on http://snippets.dzone.com/posts/show/93 */ 208 | public static byte[] intToByteArray(int input) 209 | { 210 | byte[] out = new byte[4]; 211 | for (int i = 0; i < 4; i++) { 212 | int offset = (out.length - 1 - i) * 8; 213 | out[i] = (byte) ((input >>> offset) & 0xFF); 214 | } 215 | return out; 216 | } 217 | 218 | /* Based on http://snippets.dzone.com/posts/show/93 */ 219 | public static int byteArrayToInt(byte[] data) 220 | { 221 | if (data == null || data.length != 4) return 0x0; 222 | return (int)( 223 | (0xff & data[0]) << 24 | 224 | (0xff & data[1]) << 16 | 225 | (0xff & data[2]) << 8 | 226 | (0xff & data[3]) << 0 227 | ); 228 | } 229 | 230 | public static void printSubString(String first, String second) { 231 | System.out.printf(" | %-18s= %s\n", first, second); 232 | } 233 | public static void printSubString(String first, boolean second) { 234 | String s = new Boolean(second).toString(); 235 | printSubString(first, s); 236 | } 237 | public static void printSubString(String first, int second) { 238 | String s = new Integer(second).toString(); 239 | printSubString(first, s); 240 | } 241 | } 242 | -------------------------------------------------------------------------------- /examples/client.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd ./examples/build 4 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:../../native/:/usr/local/lib 5 | java -classpath ../../lib/kerberos-java-gssapi.jar:./ client $@ 6 | 7 | -------------------------------------------------------------------------------- /examples/gssClient.java: -------------------------------------------------------------------------------- 1 | /* gssClient.java - Example GSS-API Java client */ 2 | /* 3 | * Copyright (C) 2012 by the Massachusetts Institute of Technology. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * * Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 13 | * * Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in 15 | * the documentation and/or other materials provided with the 16 | * distribution. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 21 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 22 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 27 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 29 | * OF THE POSSIBILITY OF SUCH DAMAGE. 30 | */ 31 | 32 | /* 33 | * Original source developed by wolfSSL (http://www.wolfssl.com) 34 | * 35 | * Description: 36 | * 37 | * A simple client application which uses the MIT Kerberos Java GSS-API. 38 | * The following actions are taken by the client: 39 | * a) Establish a GSSAPI context with the example server. 40 | * b) Sign, encrypt, and send a message to the server. 41 | * c) Verify the signature block returned by the server. 42 | * 43 | * Before running the client example, the client principal credentials must 44 | * be acquired using kinit. 45 | * 46 | * This class uses the utility class, GssUtil.java. 47 | * 48 | */ 49 | 50 | import java.io.*; 51 | import java.net.*; 52 | import org.ietf.jgss.*; 53 | 54 | public class gssClient { 55 | 56 | /* set these to match your environment and principal names */ 57 | private static int port = 11115; 58 | private static String server = "127.0.0.1"; 59 | private static String serviceName = "service@host"; 60 | private static String clientPrincipal = "clientname"; 61 | 62 | private static GSSCredential clientCred = null; 63 | private static GSSContext context = null; 64 | private static GSSManager mgr = GSSManager.getInstance(); 65 | 66 | /* using null to request default mech, krb5 */ 67 | private static Oid mech = null; 68 | 69 | private static Socket clientSocket = null; 70 | private static OutputStream serverOut = null; 71 | private static InputStream serverIn = null; 72 | 73 | public static void main(String args[]) { 74 | try { 75 | new gssClient().run(args); 76 | } catch (Exception e) { 77 | e.printStackTrace(); 78 | } 79 | } 80 | 81 | public void run(String args[]) throws Exception { 82 | 83 | /* pull in command line options from user */ 84 | for (int i = 0; i < args.length; i++) 85 | { 86 | String arg = args[i]; 87 | 88 | if (arg.equals("-?")) { 89 | printUsage(); 90 | } else if (arg.equals("-h")) { 91 | if (args.length < i+2) 92 | printUsage(); 93 | server = args[++i]; 94 | } else if (arg.equals("-p")) { 95 | if (args.length < i+2) 96 | printUsage(); 97 | port = Integer.parseInt(args[++i]); 98 | } else if (arg.equals("-s")) { 99 | if (args.length < i+2) 100 | printUsage(); 101 | serviceName = args[++i]; 102 | } else if (arg.equals("-c")) { 103 | if (args.length < i+2) 104 | printUsage(); 105 | clientPrincipal = args[++i]; 106 | } else { 107 | printUsage(); 108 | } 109 | } 110 | 111 | System.out.println("Starting GSS-API Client Example\n"); 112 | 113 | connectToServer(); 114 | initializeGSS(); 115 | establishContext(serverIn, serverOut); 116 | doCommunication(serverIn, serverOut); 117 | 118 | /* shutdown */ 119 | context.dispose(); 120 | clientCred.dispose(); 121 | serverIn.close(); 122 | serverOut.close(); 123 | clientSocket.close(); 124 | 125 | System.out.println("\nShut down GSS-API and closed connection to server"); 126 | } 127 | 128 | /** 129 | * Connect to example GSS-API server, using specified port and 130 | * service name. 131 | **/ 132 | public void connectToServer() { 133 | 134 | try { 135 | clientSocket = new Socket(server, port); 136 | System.out.println("Connected to " + server + " at port " 137 | + port + "\n"); 138 | 139 | /* get input and output streams */ 140 | serverOut = clientSocket.getOutputStream(); 141 | serverIn = clientSocket.getInputStream(); 142 | 143 | } catch (UnknownHostException e) { 144 | System.err.println("Unknown host: " + server); 145 | e.printStackTrace(); 146 | } catch (IOException e) { 147 | System.err.println("I/O error for the connection to " + server); 148 | e.printStackTrace(); 149 | } 150 | 151 | } 152 | 153 | /** 154 | * Set up GSS-API in preparation for context establishment. Creates 155 | * GSSName and GSSCredential for client principal. 156 | **/ 157 | public void initializeGSS() { 158 | 159 | try { 160 | GSSName clientName = mgr.createName(clientPrincipal, 161 | GSSName.NT_USER_NAME); 162 | 163 | /* create cred with max lifetime */ 164 | clientCred = mgr.createCredential(clientName, 165 | GSSCredential.INDEFINITE_LIFETIME, mech, 166 | GSSCredential.INITIATE_ONLY); 167 | 168 | System.out.println("GSSCredential created for " 169 | + clientCred.getName().toString()); 170 | System.out.println("Credential lifetime (sec) = " 171 | + clientCred.getRemainingLifetime() + "\n"); 172 | 173 | } catch (GSSException e) { 174 | System.out.println("GSS-API error in credential acquisition: " 175 | + e.getMessage()); 176 | System.exit(1); 177 | } 178 | } 179 | 180 | /** 181 | * Establish a GSS-API context with example server, calling 182 | * initSecContext() until context.isEstablished() is true. 183 | * 184 | * This method also tests exporting and re-importing the security 185 | * context. 186 | **/ 187 | public void establishContext(InputStream serverIn, 188 | OutputStream serverOut) { 189 | 190 | byte[] inToken = new byte[0]; 191 | byte[] outToken = null; 192 | int err = 0; 193 | 194 | try { 195 | GSSName peer = mgr.createName(serviceName, 196 | GSSName.NT_HOSTBASED_SERVICE); 197 | 198 | context = mgr.createContext(peer, mech, clientCred, 199 | GSSContext.INDEFINITE_LIFETIME); 200 | 201 | context.requestConf(true); 202 | context.requestReplayDet(true); 203 | context.requestMutualAuth(true); 204 | 205 | while (!context.isEstablished()) { 206 | 207 | System.out.println("Calling initSecContext"); 208 | outToken = context.initSecContext(inToken, 0, inToken.length); 209 | 210 | if (outToken != null && outToken.length > 0) { 211 | err = GssUtil.WriteToken(serverOut, outToken); 212 | if (err == 0) { 213 | System.out.println("Sent token to server..."); 214 | } else { 215 | System.out.println("Error sending token to server..."); 216 | } 217 | } 218 | 219 | if (!context.isEstablished()) { 220 | inToken = GssUtil.ReadToken(serverIn); 221 | System.out.println("Received token from server... "); 222 | } 223 | } 224 | 225 | GSSName peerName = context.getTargName(); 226 | GSSName srcName = context.getSrcName(); 227 | System.out.println("Security context established with " + peer); 228 | GssUtil.printSubString("Source Name", srcName.toString()); 229 | GssUtil.printSubString("Mechanism", context.getMech().toString()); 230 | GssUtil.printSubString("AnonymityState", context.getAnonymityState()); 231 | GssUtil.printSubString("ConfState", context.getConfState()); 232 | GssUtil.printSubString("CredDelegState", context.getCredDelegState()); 233 | GssUtil.printSubString("IntegState", context.getIntegState()); 234 | GssUtil.printSubString("Lifetime", context.getLifetime()); 235 | GssUtil.printSubString("MutualAuthState", context.getMutualAuthState()); 236 | GssUtil.printSubString("ReplayDetState", context.getReplayDetState()); 237 | GssUtil.printSubString("SequenceDetState", context.getSequenceDetState()); 238 | GssUtil.printSubString("Is initiator?", context.isInitiator()); 239 | GssUtil.printSubString("Is Prot Ready?", context.isProtReady()); 240 | 241 | /* Test exporting/importing established security context */ 242 | byte[] exportedContext = context.export(); 243 | context = mgr.createContext(exportedContext); 244 | GSSName serverInfo2 = context.getTargName(); 245 | 246 | } catch (GSSException e) { 247 | System.out.println("GSS-API error during context establishment: " 248 | + e.getMessage()); 249 | System.exit(1); 250 | } 251 | 252 | } 253 | 254 | /** 255 | * Communicate with the server. First send a message that has been 256 | * wrapped with context.wrap(), then verify the signature block which 257 | * the server sends back. 258 | **/ 259 | public void doCommunication(InputStream serverIn, 260 | OutputStream serverOut) { 261 | 262 | MessageProp messagInfo = new MessageProp(false); 263 | byte[] inToken = new byte[0]; 264 | byte[] outToken = null; 265 | byte[] buffer; 266 | int err = 0; 267 | 268 | try { 269 | 270 | String msg = "Hello Server, this is the client!"; 271 | buffer = msg.getBytes(); 272 | 273 | /* Set privacy to "true" and use the default QOP */ 274 | messagInfo.setPrivacy(true); 275 | 276 | outToken = context.wrap(buffer, 0, buffer.length, messagInfo); 277 | err = GssUtil.WriteToken(serverOut, outToken); 278 | if (err == 0) { 279 | System.out.println("Sent message to server ('" + 280 | msg + "')"); 281 | 282 | /* Read signature block from the server */ 283 | inToken = GssUtil.ReadToken(serverIn); 284 | System.out.println("Received sig block from server..."); 285 | 286 | GSSName serverInfo = context.getTargName(); 287 | System.out.println("Message from " + serverInfo.toString() + 288 | " arrived."); 289 | GssUtil.printSubString("Was it encrypted? ", messagInfo.getPrivacy()); 290 | GssUtil.printSubString("Duplicate Token? ", messagInfo.isDuplicateToken()); 291 | GssUtil.printSubString("Old Token? ", messagInfo.isOldToken()); 292 | GssUtil.printSubString("Gap Token? ", messagInfo.isGapToken()); 293 | 294 | /* Verify signature block */ 295 | context.verifyMIC(inToken, 0, inToken.length, buffer, 0, 296 | buffer.length, messagInfo); 297 | System.out.println("Verified MIC from server"); 298 | 299 | } else { 300 | System.out.println("Error sending message to server..."); 301 | } 302 | 303 | } catch (GSSException e) { 304 | System.out.println("GSS-API error in per-message calls: " + 305 | e.getMessage()); 306 | } 307 | } 308 | 309 | public void printUsage() { 310 | System.out.println("GSS-API example client usage:"); 311 | System.out.println("-?\t\tHelp, print this usage"); 312 | System.out.println("-h \tHost to connect to, default 127.0.0.1"); 313 | System.out.println("-p \tPort to connect on, default 11115"); 314 | System.out.println("-s \tService name to connect to, default 'service@host'"); 315 | System.out.println("-c \tClient principal name, default 'clientname"); 316 | System.exit(1); 317 | } 318 | } 319 | -------------------------------------------------------------------------------- /examples/gssClient.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd ./examples/build 4 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:../../native/:/usr/local/lib 5 | java -Xbootclasspath/p:../../lib/kerberos-java-gssapi.jar -classpath ../../lib/kerberos-java-gssapi.jar:./ -Dsun.boot.library.path=../../native/ gssClient $@ 6 | 7 | -------------------------------------------------------------------------------- /examples/gssServer.java: -------------------------------------------------------------------------------- 1 | /* gssServer.java - Example GSS-API Java server */ 2 | /* 3 | * Copyright (C) 2012 by the Massachusetts Institute of Technology. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * * Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 13 | * * Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in 15 | * the documentation and/or other materials provided with the 16 | * distribution. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 21 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 22 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 27 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 29 | * OF THE POSSIBILITY OF SUCH DAMAGE. 30 | */ 31 | 32 | /* 33 | * Original source developed by wolfSSL (http://www.wolfssl.com) 34 | * 35 | * Description: 36 | * 37 | * A simple server application which uses the MIT Kerberos Java GSS-API. 38 | * The following actions are taken by the server: 39 | * a) Establish a GSS-API context with the example client. 40 | * b) Unwrap a signed and encrypted message that the client sends. 41 | * c) Generate and send a signature block for the received message. 42 | * 43 | * Before starting the example server, there should be an entry in your 44 | * system keytab for the service principal. 45 | * 46 | * This class uses the utility class, GssUtil.java. 47 | * 48 | */ 49 | 50 | import java.io.*; 51 | import java.net.*; 52 | import org.ietf.jgss.*; 53 | 54 | public class gssServer { 55 | 56 | private static int server_port = 11115; 57 | private static String serviceName = "service@host"; 58 | 59 | private static GSSName name = null; 60 | private static GSSCredential cred = null; 61 | private static GSSManager mgr = GSSManager.getInstance(); 62 | 63 | public static void main(String args[]) { 64 | try { 65 | new gssServer().run(args); 66 | } catch (Exception e) { 67 | e.printStackTrace(); 68 | } 69 | } 70 | 71 | public void run(String args[]) throws Exception 72 | { 73 | /* pull in command line options from user */ 74 | for (int i = 0; i < args.length; i++) 75 | { 76 | String arg = args[i]; 77 | 78 | if (arg.equals("-?")) { 79 | printUsage(); 80 | } else if (arg.equals("-p")) { 81 | if (args.length < i+2) 82 | printUsage(); 83 | server_port = Integer.parseInt(args[++i]); 84 | } else if (arg.equals("-s")) { 85 | if (args.length < i+2) 86 | printUsage(); 87 | serviceName = args[++i]; 88 | } else { 89 | printUsage(); 90 | } 91 | } 92 | 93 | System.out.println("Starting GSS-API Server Example"); 94 | 95 | /* set up a shutdown hook to release GSSCredential storage 96 | when the user terminates the server with Ctrl+C */ 97 | Runtime.getRuntime().addShutdownHook(new Thread() { 98 | @Override 99 | public void run() { 100 | try { 101 | cred.dispose(); 102 | } catch (GSSException e) { 103 | System.out.println("Couldn't free GSSCredential storage"); 104 | } 105 | System.out.println("Freed GSSCredential storage"); 106 | } 107 | }); 108 | 109 | ServerSocket serverSocket = null; 110 | Socket clientSocket = null; 111 | OutputStream clientOut = null; 112 | InputStream clientIn = null; 113 | 114 | /* create server socket */ 115 | try { 116 | serverSocket = new ServerSocket(server_port); 117 | } catch (IOException e) { 118 | System.out.println("Error on port: " + server_port + ", " + e); 119 | System.exit(1); 120 | } 121 | 122 | /* set up GSS-API name, credential */ 123 | name = mgr.createName(serviceName, GSSName.NT_HOSTBASED_SERVICE); 124 | cred = mgr.createCredential(name, GSSCredential.INDEFINITE_LIFETIME, 125 | (Oid) null, GSSCredential.ACCEPT_ONLY); 126 | 127 | while(true) 128 | { 129 | byte[] inToken = null; 130 | byte[] outToken = null; 131 | byte[] buffer; 132 | int err = 0; 133 | 134 | GSSName peer; 135 | MessageProp supplInfo = new MessageProp(true); 136 | 137 | try { 138 | System.out.println("\nwaiting for client connection" 139 | + "-----------------------------"); 140 | clientSocket = serverSocket.accept(); 141 | 142 | /* get input and output streams */ 143 | clientOut = clientSocket.getOutputStream(); 144 | clientIn = clientSocket.getInputStream(); 145 | System.out.println("client connection received from " + 146 | clientSocket.getInetAddress().getHostAddress() + 147 | " at port " + clientSocket.getLocalPort() + "\n"); 148 | 149 | /* establish context with client */ 150 | GSSContext context = mgr.createContext(cred); 151 | 152 | while (!context.isEstablished()) { 153 | 154 | inToken = GssUtil.ReadToken(clientIn); 155 | System.out.println("Received token from client..."); 156 | 157 | System.out.println("Calling acceptSecContext"); 158 | outToken = context.acceptSecContext(inToken, 159 | 0, inToken.length); 160 | 161 | if (outToken != null && outToken.length > 0) { 162 | err = GssUtil.WriteToken(clientOut, outToken); 163 | if (err == 0) { 164 | System.out.println("Sent token to client..."); 165 | } else { 166 | System.out.println("Error sending token to client"); 167 | } 168 | } 169 | } 170 | 171 | GSSName peerName = context.getSrcName(); 172 | GSSName targetName = context.getTargName(); 173 | Oid mechName = context.getMech(); 174 | System.out.println("Security context established with " + 175 | peerName.toString()); 176 | GssUtil.printSubString("Target Name", targetName.toString()); 177 | GssUtil.printSubString("Mechanism", mechName.toString()); 178 | GssUtil.printSubString("AnonymityState", context.getAnonymityState()); 179 | GssUtil.printSubString("ConfState", context.getConfState()); 180 | GssUtil.printSubString("CredDelegState", context.getCredDelegState()); 181 | GssUtil.printSubString("IntegState", context.getIntegState()); 182 | GssUtil.printSubString("Lifetime", context.getLifetime()); 183 | GssUtil.printSubString("MutualAuthState", context.getMutualAuthState()); 184 | GssUtil.printSubString("ReplayDetState", context.getReplayDetState()); 185 | GssUtil.printSubString("SequenceDetState", context.getSequenceDetState()); 186 | GssUtil.printSubString("Is initiator?", context.isInitiator()); 187 | GssUtil.printSubString("Is Prot Ready?", context.isProtReady()); 188 | 189 | /* read message sent by the client */ 190 | inToken = Util.ReadToken(clientIn); 191 | System.out.println("Received token from client..."); 192 | 193 | /* unwrap the message */ 194 | buffer = context.unwrap(inToken, 0, inToken.length, supplInfo); 195 | System.out.println("Message received from client ('" + 196 | new String(buffer) + "')"); 197 | 198 | /* print other supplementary per-message status info */ 199 | System.out.println("Message from " + 200 | peerName.toString() + " arrived."); 201 | GssUtil.printSubString("Was it encrypted?", supplInfo.getPrivacy()); 202 | GssUtil.printSubString("Duplicate Token?", supplInfo.isDuplicateToken()); 203 | GssUtil.printSubString("Old Token?", supplInfo.isOldToken()); 204 | GssUtil.printSubString("Unsequenced Token?", supplInfo.isUnseqToken()); 205 | GssUtil.printSubString("Gap Token?", supplInfo.isGapToken()); 206 | 207 | supplInfo.setPrivacy(true); // privacy requested 208 | supplInfo.setQOP(0); // default QOP 209 | 210 | /* produce a signature block for the message */ 211 | buffer = context.getMIC(buffer, 0, buffer.length, supplInfo); 212 | 213 | /* send signature block to client */ 214 | err = GssUtil.WriteToken(clientOut, buffer); 215 | if (err == 0) { 216 | System.out.println("Sent sig block to client..."); 217 | } else { 218 | System.out.println("Error sending sig block to client..."); 219 | } 220 | 221 | context.dispose(); 222 | 223 | } catch (IOException e) { 224 | System.out.println("Server did not accept connection: " + e); 225 | } catch (GSSException e) { 226 | System.out.println("GSS-API Error: " + e.getMessage()); 227 | } 228 | 229 | clientOut.close(); 230 | clientIn.close(); 231 | clientSocket.close(); 232 | } 233 | } 234 | 235 | public void printUsage() { 236 | System.out.println("GSS-API example server usage:"); 237 | System.out.println("-?\t\tHelp, print this usage"); 238 | System.out.println("-p \tPort to listen on, default 11115"); 239 | System.out.println("-s \tService name, default 'service@host'"); 240 | System.exit(1); 241 | } 242 | } 243 | -------------------------------------------------------------------------------- /examples/gssServer.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd ./examples/build 4 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:../../native/:/usr/local/lib 5 | java -Xbootclasspath/p:../../lib/kerberos-java-gssapi.jar -classpath ../../lib/kerberos-java-gssapi.jar:./ -Dsun.boot.library.path=../../native/ gssServer $@ 6 | 7 | -------------------------------------------------------------------------------- /examples/server.java: -------------------------------------------------------------------------------- 1 | /* server.java - Example GSS-API Java server */ 2 | /* 3 | * Copyright (C) 2012 by the Massachusetts Institute of Technology. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 10 | * * Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 13 | * * Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in 15 | * the documentation and/or other materials provided with the 16 | * distribution. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 21 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 22 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 27 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 29 | * OF THE POSSIBILITY OF SUCH DAMAGE. 30 | */ 31 | 32 | /* 33 | * Original source developed by wolfSSL (http://www.wolfssl.com) 34 | * 35 | * Description: 36 | * A simple server application which uses the MIT Kerberos Java GSS-API 37 | * SWIG wrapper. The following actions are taken by the server: 38 | * a) Establish a GSS-API context with a client. 39 | * b) Unwraps a signed and encrypted message that the client sends, 40 | * using gss_unwrap. 41 | * c) Generates and sends a signature block for the received message 42 | * using gss_get_mic. 43 | * d) Repeats steps b) and c) using gss_unseal / gss_sign. 44 | * 45 | */ 46 | import java.io.*; 47 | import java.net.*; 48 | import edu.mit.jgss.swig.*; 49 | 50 | class server implements gsswrapperConstants 51 | { 52 | private static int server_port = 11115; 53 | private static String serviceName = "service@host"; 54 | private static gss_ctx_id_t_desc context = new gss_ctx_id_t_desc(); 55 | 56 | public static void main(String args[]) { 57 | try { 58 | new server().run(args); 59 | } catch (Exception e) { 60 | e.printStackTrace(); 61 | } 62 | } 63 | 64 | public void run(String args[]) throws Exception 65 | { 66 | int ret = 0; 67 | int authorizationError = 0; 68 | long maj_status = 0; 69 | long[] min_status = {0}; 70 | String clientMsg; 71 | gss_ctx_id_t_desc gssContext = GSS_C_NO_CONTEXT; 72 | gss_cred_id_t_desc serverCreds = new gss_cred_id_t_desc(); 73 | 74 | /* pull in command line options from user */ 75 | for (int i = 0; i < args.length; i++) 76 | { 77 | String arg = args[i]; 78 | 79 | if (arg.equals("-?")) { 80 | printUsage(); 81 | } else if (arg.equals("-p")) { 82 | if (args.length < i+2) 83 | printUsage(); 84 | server_port = Integer.parseInt(args[++i]); 85 | } else if (arg.equals("-s")) { 86 | if (args.length < i+2) 87 | printUsage(); 88 | serviceName = args[++i]; 89 | } else { 90 | printUsage(); 91 | } 92 | } 93 | 94 | /* create input and output streams */ 95 | ServerSocket serverSocket = null; 96 | Socket clientSocket = null; 97 | OutputStream clientOut = null; 98 | InputStream clientIn = null; 99 | 100 | /* create server socket */ 101 | try { 102 | serverSocket = new ServerSocket(server_port); 103 | } catch (IOException e) { 104 | System.out.println("Error on port: " + server_port + ", " + e); 105 | System.exit(1); 106 | } 107 | 108 | System.out.println("Started Java GSS-API server example, " + 109 | "waiting for client connection..."); 110 | 111 | while(true) 112 | { 113 | try { 114 | 115 | clientSocket = serverSocket.accept(); 116 | 117 | /* get input and output streams */ 118 | clientOut = clientSocket.getOutputStream(); 119 | clientIn = clientSocket.getInputStream(); 120 | System.out.println("Client connection received"); 121 | 122 | } catch (IOException e) { 123 | System.out.println("Server did not accept connection: " + e); 124 | } 125 | 126 | /* Import service name and acquire creds for it, 127 | * returns NULL on failure */ 128 | serverCreds = AcquireServerCreds(serviceName); 129 | 130 | if (serverCreds != null) { 131 | System.out.println("Finished acquiring server creds"); 132 | /* Stores created context in global static "context" */ 133 | ret = Authenticate(clientSocket, clientIn, clientOut); 134 | 135 | if (ret == 0) { 136 | System.out.println("Finished Authentication"); 137 | /* Using gss_unwrap / gss_get_mic */ 138 | ret = Communicate(clientSocket, clientIn, clientOut); 139 | 140 | if (ret == 0) { 141 | System.out.println("Finished first communication " + 142 | "with server"); 143 | /* Using gss_unseal / gss_sign */ 144 | ret = AltCommunicate(clientSocket, clientIn, 145 | clientOut); 146 | 147 | if (ret == 0) { 148 | System.out.println("Finished second " + 149 | "communication with server"); 150 | } else { 151 | System.out.println("Failed during second " + 152 | "communication with server"); 153 | } 154 | } else { 155 | System.out.println("Failed during first " + 156 | "communication with server"); 157 | } 158 | } else { 159 | System.out.println("Failed during Authentication"); 160 | } 161 | } else { 162 | System.out.println("Failed when acquiring server creds"); 163 | } 164 | 165 | if (ret == 0) { 166 | System.out.println("SUCCESS!"); 167 | gsswrapper.gss_release_cred(min_status, serverCreds); 168 | 169 | /* Delete established GSSAPI context */ 170 | gss_buffer_desc output_token = GSS_C_NO_BUFFER; 171 | gss_OID_desc tmp = context.getMech_type(); 172 | maj_status = gsswrapper.gss_delete_sec_context(min_status, 173 | context, output_token); 174 | if (maj_status != GSS_S_COMPLETE) { 175 | Util.displayError("deleting security context", 176 | min_status, maj_status); 177 | } 178 | } else { 179 | System.out.println("FAILURE!"); 180 | continue; 181 | } 182 | 183 | clientOut.close(); 184 | clientIn.close(); 185 | clientSocket.close(); 186 | } 187 | } 188 | 189 | public gss_cred_id_t_desc AcquireServerCreds(String serviceName) 190 | { 191 | gss_cred_id_t_desc server_creds = new gss_cred_id_t_desc(); 192 | gss_buffer_desc name_buf = new gss_buffer_desc(serviceName); 193 | gss_name_t_desc server_name = new gss_name_t_desc(); 194 | gss_OID_set_desc actual_mechs = GSS_C_NO_OID_SET; 195 | long maj_status = 0; 196 | long[] min_status = {0}; 197 | long[] time_rec = {0}; 198 | 199 | maj_status = gsswrapper.gss_import_name(min_status, name_buf, 200 | gsswrapper.getGSS_C_NT_HOSTBASED_SERVICE(), server_name); 201 | 202 | if (maj_status != GSS_S_COMPLETE) { 203 | Util.displayError("gss_import_name, serviceName", 204 | min_status, maj_status); 205 | return null; 206 | } 207 | 208 | maj_status = gsswrapper.gss_acquire_cred(min_status, server_name, 209 | 0, actual_mechs, 210 | GSS_C_ACCEPT, 211 | server_creds, null, time_rec); 212 | if (maj_status != GSS_S_COMPLETE) { 213 | Util.displayError("gss_acquire_cred(server_name)", 214 | min_status, maj_status); 215 | return null; 216 | } 217 | 218 | gsswrapper.gss_release_name(min_status, server_name); 219 | 220 | return server_creds; 221 | } 222 | 223 | public int Authenticate(Socket inSocket, 224 | InputStream clientIn, 225 | OutputStream clientOut) 226 | { 227 | int err = 0; 228 | long maj_status = 0; 229 | long[] min_status = {0}; 230 | gss_ctx_id_t_desc context_tmp = GSS_C_NO_CONTEXT; 231 | 232 | byte[] inputTokenBuffer = null; 233 | gss_buffer_desc inputToken = new gss_buffer_desc(); 234 | 235 | System.out.println("Authenticating..."); 236 | 237 | /* The main authentication loop. We need to loop reading "input 238 | * tokens" from the client, calling gss_accept_sec_context on the 239 | * "input tokens" and send the resulting "output tokens" back to 240 | * the client until we get GSS_S_COMPLETE or an error */ 241 | 242 | maj_status = GSS_S_CONTINUE_NEEDED; 243 | while ( (err == 0) && 244 | (maj_status != GSS_S_COMPLETE)) { 245 | 246 | /* Clean up old input buffer */ 247 | if (inputTokenBuffer != null) 248 | inputTokenBuffer = null; 249 | 250 | inputTokenBuffer = Util.ReadToken(clientIn); 251 | 252 | if (inputTokenBuffer != null) { 253 | /* Set up input buffers for the next run through the loop */ 254 | gsswrapper.setDescArray(inputToken, inputTokenBuffer); 255 | inputToken.setLength(inputTokenBuffer.length); 256 | 257 | System.out.println("inputToken.value = " 258 | + inputToken.getValue()); 259 | System.out.println("inputToken.length = " 260 | + inputToken.getLength()); 261 | } else { 262 | System.out.println("Got bad token from client, " + 263 | "check client for error description."); 264 | return -1; 265 | } 266 | 267 | if (inputTokenBuffer != null) { 268 | gss_buffer_desc outputToken = new gss_buffer_desc(); 269 | outputToken.setValue(null); 270 | outputToken.setLength(0); 271 | 272 | /* gss_accept_sec_context takes the client request and 273 | * generates an appropriate reply. Passing 274 | * GSS_C_NO_CREDENTIAL for the service principal causes 275 | * the server to accept any service princiapl in the 276 | * server's keytab. */ 277 | 278 | System.out.println("Calling gss_accept_sec_context..."); 279 | long[] req_flags = {0}; 280 | long[] time_rec = {0}; 281 | gss_cred_id_t_desc acceptor_cred_handle = GSS_C_NO_CREDENTIAL; 282 | gss_channel_bindings_struct input_chan_bindings = 283 | GSS_C_NO_CHANNEL_BINDINGS; 284 | maj_status = gsswrapper.gss_accept_sec_context( 285 | min_status, context_tmp, 286 | acceptor_cred_handle, 287 | inputToken, 288 | input_chan_bindings, 289 | null, null, outputToken, req_flags, time_rec, null); 290 | 291 | if ( (outputToken.getLength() > 0) && 292 | (outputToken.getValue() != null) ) { 293 | /* Send the output token to the client */ 294 | byte[] temp_token = new byte[(int)outputToken.getLength()]; 295 | temp_token = gsswrapper.getDescArray(outputToken); 296 | System.out.println("temp_token.length = " 297 | + temp_token.length); 298 | 299 | err = Util.WriteToken(clientOut, temp_token); 300 | if (err != 0) { 301 | System.out.println("Error sending token to client"); 302 | } 303 | 304 | System.out.println("outputToken.value = " 305 | + outputToken.getValue()); 306 | System.out.println("outputToken.length = " 307 | + outputToken.getLength()); 308 | 309 | /* free the output token */ 310 | gsswrapper.gss_release_buffer(min_status, outputToken); 311 | } 312 | } 313 | 314 | if ( (maj_status != GSS_S_COMPLETE) && 315 | (maj_status != GSS_S_CONTINUE_NEEDED)) 316 | { 317 | Util.displayError("gss_accept_sec_context", 318 | min_status, maj_status); 319 | return -1; 320 | } 321 | } 322 | 323 | if (err == 0) { 324 | context = context_tmp; 325 | } else { 326 | System.out.println("Authenticate failed!"); 327 | return -1; 328 | } 329 | 330 | return err; 331 | 332 | } /* end Authorize() */ 333 | 334 | public int Communicate(Socket inSocket, 335 | InputStream clientIn, 336 | OutputStream clientOut) 337 | { 338 | long maj_status = 0; 339 | long[] min_status = {0}; 340 | int[] conf_state = {0}; 341 | long[] qop_state = {0}; 342 | int err = 0; 343 | gss_buffer_desc in_buf = new gss_buffer_desc(); 344 | gss_buffer_desc out_buf = new gss_buffer_desc(); 345 | gss_buffer_desc mic_buf = new gss_buffer_desc(); 346 | byte[] messageBuffer = null; 347 | 348 | 349 | /* Receive the message token */ 350 | messageBuffer = Util.ReadToken(clientIn); 351 | 352 | if (messageBuffer != null) { 353 | gsswrapper.setDescArray(in_buf, messageBuffer); 354 | in_buf.setLength(messageBuffer.length); 355 | } 356 | 357 | /* Unwrap token */ 358 | maj_status = gsswrapper.gss_unwrap(min_status, context, 359 | in_buf, out_buf, conf_state, qop_state); 360 | 361 | if (maj_status != GSS_S_COMPLETE) { 362 | Util.displayError("unwrapping token, gss_unwrap", 363 | min_status, maj_status); 364 | return -1; 365 | } else if (conf_state[0] == 0) { 366 | System.out.println("Warning! Message not encrypted."); 367 | } 368 | 369 | System.out.println("Received message: " + out_buf.getValue()); 370 | 371 | /* Produce a signature block for the message */ 372 | maj_status = gsswrapper.gss_get_mic(min_status, context, 373 | GSS_C_QOP_DEFAULT, 374 | out_buf, mic_buf); 375 | 376 | if (maj_status != GSS_S_COMPLETE) { 377 | Util.displayError("producing signature block, gss_get_mic", 378 | min_status, maj_status); 379 | return -1; 380 | } 381 | 382 | /* Send signature block to client */ 383 | byte[] temp_token = new byte[(int)mic_buf.getLength()]; 384 | temp_token = gsswrapper.getDescArray(mic_buf); 385 | err = Util.WriteToken(clientOut, temp_token); 386 | 387 | if (err != 0) { 388 | System.out.println("Error sending signature block to client"); 389 | return -1; 390 | } 391 | 392 | gsswrapper.gss_release_buffer(min_status, in_buf); 393 | gsswrapper.gss_release_buffer(min_status, out_buf); 394 | gsswrapper.gss_release_buffer(min_status, mic_buf); 395 | 396 | return 0; 397 | 398 | } /* end Communicate() */ 399 | 400 | public int AltCommunicate(Socket inSocket, 401 | InputStream clientIn, 402 | OutputStream clientOut) 403 | { 404 | long maj_status = 0; 405 | long[] min_status = {0}; 406 | int[] conf_state = {0}; 407 | int[] qop_state = {0}; 408 | int err = 0; 409 | gss_buffer_desc in_buf = new gss_buffer_desc(); 410 | gss_buffer_desc out_buf = new gss_buffer_desc(); 411 | gss_buffer_desc mic_buf = new gss_buffer_desc(); 412 | byte[] messageBuffer = null; 413 | 414 | /* Receive the message token */ 415 | messageBuffer = Util.ReadToken(clientIn); 416 | 417 | if (messageBuffer != null) { 418 | gsswrapper.setDescArray(in_buf, messageBuffer); 419 | in_buf.setLength(messageBuffer.length); 420 | } 421 | 422 | /* Unwrap token */ 423 | maj_status = gsswrapper.gss_unseal(min_status, context, 424 | in_buf, out_buf, conf_state, qop_state); 425 | 426 | if (maj_status != GSS_S_COMPLETE) { 427 | Util.displayError("unwrapping token, gss_unseal", 428 | min_status, maj_status); 429 | return -1; 430 | } else if (conf_state[0] == 0) { 431 | System.out.println("Warning! Message not encrypted."); 432 | } 433 | 434 | System.out.println("Received message: " + out_buf.getValue()); 435 | 436 | /* Produce a signature block for the message */ 437 | maj_status = gsswrapper.gss_sign(min_status, context, 438 | GSS_C_QOP_DEFAULT, 439 | out_buf, mic_buf); 440 | 441 | if (maj_status != GSS_S_COMPLETE) { 442 | Util.displayError("producing signature block, gss_sign", 443 | min_status, maj_status); 444 | return -1; 445 | } 446 | 447 | /* Send signature block to client */ 448 | byte[] temp_token = new byte[(int)mic_buf.getLength()]; 449 | temp_token = gsswrapper.getDescArray(mic_buf); 450 | err = Util.WriteToken(clientOut, temp_token); 451 | 452 | if (err != 0) { 453 | System.out.println("Error sending signature block to client"); 454 | return -1; 455 | } 456 | 457 | gsswrapper.gss_release_buffer(min_status, in_buf); 458 | gsswrapper.gss_release_buffer(min_status, out_buf); 459 | gsswrapper.gss_release_buffer(min_status, mic_buf); 460 | 461 | return 0; 462 | 463 | } /* end AltCommunicate() */ 464 | 465 | public void printUsage() { 466 | System.out.println("SWIG Kerberos example server usage:"); 467 | System.out.println("-?\t\tHelp, print this usage"); 468 | System.out.println("-p \tPort to listen on, default 11115"); 469 | System.out.println("-s \tService name, default 'service@host'"); 470 | System.exit(1); 471 | } 472 | } 473 | 474 | -------------------------------------------------------------------------------- /examples/server.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd ./examples/build 4 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:../../native/:/usr/local/lib 5 | java -classpath ../../lib/kerberos-java-gssapi.jar:./ server $@ 6 | 7 | -------------------------------------------------------------------------------- /src/java/edu/mit/jgss/ChannelBindingImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 by the Massachusetts Institute of Technology. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 12 | * * Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in 14 | * the documentation and/or other materials provided with the 15 | * distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 20 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 21 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 22 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 | * OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package edu.mit.jgss; 31 | 32 | import java.net.InetAddress; 33 | import org.ietf.jgss.ChannelBinding; 34 | import org.ietf.jgss.GSSException; 35 | 36 | import edu.mit.jgss.swig.*; 37 | 38 | public class ChannelBindingImpl extends ChannelBinding { 39 | 40 | public ChannelBindingImpl(InetAddress initAddr, InetAddress acceptAddr, 41 | byte[] appData) throws GSSException { 42 | super(initAddr, acceptAddr, appData); 43 | } 44 | 45 | public ChannelBindingImpl(byte[] appData) { 46 | super(appData); 47 | } 48 | 49 | public gss_channel_bindings_struct getNativeChannelBindings() { 50 | return super.channelBindStruct; 51 | } 52 | } 53 | 54 | -------------------------------------------------------------------------------- /src/java/edu/mit/jgss/DerHeader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 by the Massachusetts Institute of Technology. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 12 | * * Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in 14 | * the documentation and/or other materials provided with the 15 | * distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 20 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 21 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 22 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 | * OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package edu.mit.jgss; 31 | 32 | /* 33 | * Simple class to hold information about DER headers 34 | */ 35 | public class DerHeader { 36 | 37 | private int length = 0; 38 | private byte[] headerBytes = null; 39 | 40 | public int getLength() { 41 | return length; 42 | } 43 | 44 | public byte[] getBytes() { 45 | byte[] tmp = headerBytes.clone(); 46 | return tmp; 47 | } 48 | 49 | public void setLength(int length) { 50 | this.length = length; 51 | } 52 | 53 | public void setBytes(byte[] hBytes) { 54 | headerBytes = new byte[hBytes.length]; 55 | System.arraycopy(hBytes, 0, headerBytes, 0, hBytes.length); 56 | } 57 | 58 | public void appendBytes(byte[] append) { 59 | 60 | if (headerBytes == null) { 61 | headerBytes = new byte[append.length]; 62 | System.arraycopy(append, 0, headerBytes, 0, append.length); 63 | } else { 64 | /* merge into tmp array */ 65 | byte[] tmp = new byte[headerBytes.length + append.length]; 66 | System.arraycopy(headerBytes, 0, tmp, 0, headerBytes.length); 67 | System.arraycopy(append, 0, tmp, headerBytes.length, append.length); 68 | 69 | /* copy back into object array */ 70 | headerBytes = new byte[headerBytes.length + append.length]; 71 | System.arraycopy(tmp, 0, headerBytes, 0, tmp.length); 72 | } 73 | 74 | } 75 | } 76 | 77 | 78 | -------------------------------------------------------------------------------- /src/java/edu/mit/jgss/DerUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 by the Massachusetts Institute of Technology. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 12 | * * Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in 14 | * the documentation and/or other materials provided with the 15 | * distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 20 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 21 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 22 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 | * OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package edu.mit.jgss; 31 | 32 | import org.ietf.jgss.GSSException; 33 | import edu.mit.jgss.swig.*; 34 | import java.io.*; 35 | 36 | /* 37 | * Utility functions for DER encodings 38 | */ 39 | public class DerUtil { 40 | 41 | /* 42 | * Remove the length header from a GSS token. Doing this removes 43 | * the bytes from our InputStream, so we save them in the DerHeader 44 | * object in order to be able to pass them back to the underlying 45 | * native GSSAPI implementation. 46 | */ 47 | public static DerHeader getHeader(InputStream in) 48 | throws GSSException, IOException { 49 | 50 | int length = 0; 51 | int tag, b; 52 | ByteArrayOutputStream headBytes = new ByteArrayOutputStream(); 53 | DerHeader header = new DerHeader(); 54 | 55 | try { 56 | tag = in.read(); 57 | headBytes.write(tag); 58 | if (tag != 0x60) { 59 | throw new GSSExceptionImpl(gsswrapper.GSS_S_DEFECTIVE_TOKEN, 0); 60 | } 61 | 62 | b = in.read(); 63 | headBytes.write(b); 64 | if (b >= 0x80) { 65 | int bytes = b & 0x7F; 66 | 67 | while ((bytes--) > 0) { 68 | b = in.read(); 69 | headBytes.write(b); 70 | length = (length << 8) | b; 71 | } 72 | } else { 73 | length = b; 74 | } 75 | 76 | } catch (IOException e) { 77 | throw new IOException("I/O Error occurred when reading InputStream"); 78 | } 79 | 80 | header.setLength(length); 81 | header.setBytes(headBytes.toByteArray()); 82 | 83 | return header; 84 | 85 | } 86 | 87 | /* 88 | * Print a byte[], for debug purposes. 89 | */ 90 | public static void printByteArray(byte[] input) 91 | { 92 | for (int i = 0; i < input.length; i++ ) { 93 | System.out.format("%02X ", input[i]); 94 | } 95 | System.out.println(); 96 | } 97 | 98 | } 99 | 100 | -------------------------------------------------------------------------------- /src/java/edu/mit/jgss/GSSCredentialImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 by the Massachusetts Institute of Technology. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 12 | * * Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in 14 | * the documentation and/or other materials provided with the 15 | * distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 20 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 21 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 22 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 | * OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package edu.mit.jgss; 31 | 32 | import org.ietf.jgss.GSSCredential; 33 | import org.ietf.jgss.GSSException; 34 | import org.ietf.jgss.Oid; 35 | import org.ietf.jgss.GSSName; 36 | 37 | import edu.mit.jgss.swig.*; 38 | 39 | public class GSSCredentialImpl implements GSSCredential { 40 | 41 | /* representing our underlying SWIG-wrapped gss_cred_id_t object */ 42 | private gss_cred_id_t_desc internGSSCred = new gss_cred_id_t_desc(); 43 | 44 | /* has this cred been destroyed? */ 45 | private boolean invalid = false; 46 | 47 | public void dispose() throws GSSException { 48 | 49 | if (!invalid) { 50 | long[] min_status = {0}; 51 | long ret = 0; 52 | 53 | ret = gsswrapper.gss_release_cred(min_status, this.internGSSCred); 54 | 55 | if (ret != gsswrapper.GSS_S_COMPLETE) { 56 | throw new GSSExceptionImpl(0, (int) min_status[0]); 57 | } 58 | this.invalid = true; 59 | } 60 | 61 | } 62 | 63 | public GSSName getName() throws GSSException { 64 | 65 | long maj_status = 0; 66 | long[] min_status = {0}; 67 | long[] lifetime = {0}; 68 | int[] cred_usage = {0}; 69 | int ret = 0; 70 | gss_name_t_desc name = new gss_name_t_desc(); 71 | gss_OID_set_desc temp_mech_set = new gss_OID_set_desc(); 72 | 73 | if(invalid) { 74 | throw new GSSException((int) gsswrapper.GSS_S_DEFECTIVE_CREDENTIAL, 75 | 0, "credential has been disposed, no longer valid"); 76 | } 77 | 78 | GSSNameImpl tmpName = new GSSNameImpl(); 79 | 80 | maj_status = gsswrapper.gss_inquire_cred(min_status, 81 | this.internGSSCred, name, lifetime, cred_usage, 82 | temp_mech_set); 83 | 84 | if (maj_status != gsswrapper.GSS_S_COMPLETE) { 85 | throw new GSSExceptionImpl((int) maj_status, (int) min_status[0]); 86 | } 87 | 88 | ret = tmpName.setInternGSSName(name); 89 | if (ret != 0) { 90 | throw new GSSExceptionImpl((int) maj_status, (int) min_status[0]); 91 | } 92 | 93 | return tmpName; 94 | 95 | } 96 | 97 | public GSSName getName(Oid mechOID) throws GSSException { 98 | 99 | if(invalid) { 100 | throw new GSSException((int)gsswrapper.GSS_S_DEFECTIVE_CREDENTIAL, 101 | 0, "credential has been disposed, no longer valid"); 102 | } 103 | 104 | GSSName name = getName(); 105 | GSSName canoniName = name.canonicalize(mechOID); 106 | 107 | return canoniName; 108 | } 109 | 110 | public int getRemainingLifetime() throws GSSException { 111 | 112 | long maj_status = 0; 113 | long[] min_status = {0}; 114 | long[] lifetime = {0}; 115 | int[] cred_usage = {0}; 116 | gss_name_t_desc name = new gss_name_t_desc(); 117 | gss_OID_set_desc temp_mech_set = new gss_OID_set_desc(); 118 | 119 | if(invalid) { 120 | throw new GSSException((int) gsswrapper.GSS_S_DEFECTIVE_CREDENTIAL, 121 | 0, "credential has been disposed, no longer valid"); 122 | } 123 | 124 | maj_status = gsswrapper.gss_inquire_cred(min_status, 125 | this.internGSSCred, name, lifetime, cred_usage, 126 | temp_mech_set); 127 | 128 | if (maj_status != gsswrapper.GSS_S_COMPLETE) { 129 | throw new GSSExceptionImpl((int) maj_status, (int) min_status[0]); 130 | } 131 | 132 | /* check for native INDEFINITE_LIFETIME and convert to Java 133 | RFC version (Integer.MAX_VALUE) */ 134 | if (lifetime[0] == 4294967295L) 135 | return GSSCredential.INDEFINITE_LIFETIME; 136 | return (int)lifetime[0]; 137 | 138 | } 139 | 140 | public int getRemainingInitLifetime(Oid mech) throws GSSException { 141 | 142 | long maj_status = 0; 143 | long[] min_status = {0}; 144 | long[] init_lifetime = {0}; 145 | long[] accept_lifetime = {0}; 146 | int[] cred_usage = {0}; 147 | gss_name_t_desc name = new gss_name_t_desc(); 148 | 149 | if(invalid) { 150 | throw new GSSException((int) gsswrapper.GSS_S_DEFECTIVE_CREDENTIAL, 151 | 0, "credential has been disposed, no longer valid"); 152 | } 153 | 154 | maj_status = gsswrapper.gss_inquire_cred_by_mech(min_status, 155 | this.internGSSCred, mech.getNativeOid(), name, init_lifetime, 156 | accept_lifetime, cred_usage); 157 | 158 | if (maj_status != gsswrapper.GSS_S_COMPLETE) { 159 | throw new GSSExceptionImpl((int) maj_status, (int) min_status[0]); 160 | } 161 | 162 | if (cred_usage[0] == GSSCredential.INITIATE_ONLY || 163 | cred_usage[0] == GSSCredential.INITIATE_AND_ACCEPT) { 164 | 165 | /* check for native INDEFINITE_LIFETIME and convert to Java 166 | RFC version (Integer.MAX_VALUE) */ 167 | if (init_lifetime[0] == 4294967295L) 168 | return GSSCredential.INDEFINITE_LIFETIME; 169 | return (int)init_lifetime[0]; 170 | } else { 171 | return 0; 172 | } 173 | } 174 | 175 | public int getRemainingAcceptLifetime(Oid mech) throws GSSException { 176 | 177 | long maj_status = 0; 178 | long[] min_status = {0}; 179 | long[] init_lifetime = {0}; 180 | long[] accept_lifetime = {0}; 181 | int[] cred_usage = {0}; 182 | gss_name_t_desc name = new gss_name_t_desc(); 183 | 184 | if(invalid) { 185 | throw new GSSException((int) gsswrapper.GSS_S_DEFECTIVE_CREDENTIAL, 186 | 0, "credential has been disposed, no longer valid"); 187 | } 188 | 189 | maj_status = gsswrapper.gss_inquire_cred_by_mech(min_status, 190 | this.internGSSCred, mech.getNativeOid(), name, init_lifetime, 191 | accept_lifetime, cred_usage); 192 | 193 | if (maj_status != gsswrapper.GSS_S_COMPLETE) { 194 | throw new GSSExceptionImpl((int) maj_status, (int) min_status[0]); 195 | } 196 | 197 | if (cred_usage[0] == GSSCredential.ACCEPT_ONLY || 198 | cred_usage[0] == GSSCredential.INITIATE_AND_ACCEPT) { 199 | 200 | /* check for native INDEFINITE_LIFETIME and convert to Java 201 | RFC version (Integer.MAX_VALUE) */ 202 | if (accept_lifetime[0] == 4294967295L) 203 | return GSSCredential.INDEFINITE_LIFETIME; 204 | return (int)accept_lifetime[0]; 205 | } else { 206 | return 0; 207 | } 208 | 209 | } 210 | 211 | public int getUsage() throws GSSException { 212 | 213 | long maj_status = 0; 214 | long[] min_status = {0}; 215 | long[] lifetime = {0}; 216 | int[] cred_usage = {0}; 217 | gss_name_t_desc name = new gss_name_t_desc(); 218 | gss_OID_set_desc temp_mech_set = new gss_OID_set_desc(); 219 | 220 | if(invalid) { 221 | throw new GSSException((int) gsswrapper.GSS_S_DEFECTIVE_CREDENTIAL, 222 | 0, "credential has been disposed, no longer valid"); 223 | } 224 | 225 | maj_status = gsswrapper.gss_inquire_cred(min_status, 226 | this.internGSSCred, name, lifetime, cred_usage, 227 | temp_mech_set); 228 | 229 | if (maj_status != gsswrapper.GSS_S_COMPLETE) { 230 | throw new GSSExceptionImpl((int) maj_status, (int) min_status[0]); 231 | } 232 | 233 | return cred_usage[0]; 234 | 235 | } 236 | 237 | public int getUsage(Oid mechOID) throws GSSException { 238 | 239 | long maj_status = 0; 240 | long[] min_status = {0}; 241 | long[] init_lifetime = {0}; 242 | long[] accept_lifetime = {0}; 243 | int[] cred_usage = {0}; 244 | gss_name_t_desc name = new gss_name_t_desc(); 245 | 246 | if(invalid) { 247 | throw new GSSException((int) gsswrapper.GSS_S_DEFECTIVE_CREDENTIAL, 248 | 0, "credential has been disposed, no longer valid"); 249 | } 250 | 251 | maj_status = gsswrapper.gss_inquire_cred_by_mech(min_status, 252 | this.internGSSCred, mechOID.getNativeOid(), name, 253 | init_lifetime, accept_lifetime, cred_usage); 254 | 255 | if (maj_status != gsswrapper.GSS_S_COMPLETE) { 256 | throw new GSSExceptionImpl((int) maj_status, (int) min_status[0]); 257 | } 258 | 259 | return cred_usage[0]; 260 | 261 | } 262 | 263 | public Oid[] getMechs() throws GSSException { 264 | 265 | long maj_status = 0; 266 | long[] min_status = {0}; 267 | long[] lifetime = {0}; 268 | int[] cred_usage = {0}; 269 | gss_name_t_desc name = new gss_name_t_desc(); 270 | gss_OID_set_desc temp_mech_set = new gss_OID_set_desc(); 271 | 272 | if(invalid) { 273 | throw new GSSException((int) gsswrapper.GSS_S_DEFECTIVE_CREDENTIAL, 274 | 0, "credential has been disposed, no longer valid"); 275 | } 276 | 277 | maj_status = gsswrapper.gss_inquire_cred(min_status, 278 | this.internGSSCred, name, lifetime, cred_usage, 279 | temp_mech_set); 280 | 281 | if (maj_status != gsswrapper.GSS_S_COMPLETE) { 282 | throw new GSSExceptionImpl((int) maj_status, (int) min_status[0]); 283 | } 284 | 285 | /* temp_mech_set is a set, retrieve elements using getElement() and 286 | getCount() */ 287 | Oid[] mechs = new Oid[(int) temp_mech_set.getCount()]; 288 | 289 | for (int i = 0; i < temp_mech_set.getCount(); i++) { 290 | mechs[i] = new Oid(temp_mech_set.getElement(i).toDotString()); 291 | } 292 | 293 | return mechs; 294 | } 295 | 296 | public void add(GSSName aName, int initLifetime, int acceptLifetime, 297 | Oid mech, int usage) throws GSSException { 298 | 299 | long maj_status = 0; 300 | long[] min_status = {0}; 301 | long[] lifetime = {0}; 302 | int[] cred_usage = {0}; 303 | 304 | if(invalid) { 305 | throw new GSSException((int) gsswrapper.GSS_S_DEFECTIVE_CREDENTIAL, 306 | 0, "credential has been disposed, no longer valid"); 307 | } 308 | 309 | maj_status = gsswrapper.gss_add_cred(min_status, this.internGSSCred, 310 | aName.getInternGSSName(), mech.getNativeOid(), 311 | usage, initLifetime, acceptLifetime, null, null, 312 | null, null); 313 | 314 | if (maj_status != gsswrapper.GSS_S_COMPLETE) { 315 | throw new GSSExceptionImpl((int) maj_status, (int) min_status[0]); 316 | } 317 | 318 | } 319 | 320 | public boolean equals(Object another) { 321 | 322 | if (! (another instanceof GSSCredential)) 323 | return false; 324 | 325 | GSSCredential tmpCred = (GSSCredential) another; 326 | 327 | if (tmpCred == null) 328 | throw new NullPointerException("Input Object is null"); 329 | 330 | try { 331 | 332 | /* test some elements of our Cred to test for equality */ 333 | if (this.invalid) 334 | return false; 335 | 336 | if (!tmpCred.getName().equals(this.getName())) 337 | return false; 338 | 339 | if (tmpCred.getUsage() != this.getUsage()) 340 | return false; 341 | 342 | } catch (GSSException e) { 343 | return false; 344 | } 345 | 346 | return true; 347 | } 348 | 349 | GSSCredential acquireCred(GSSName desiredName, int timeReq, 350 | Oid[] desiredMechs, int credUsage) throws GSSException { 351 | 352 | long maj_status = 0; 353 | long[] min_status = {0}; 354 | long[] lifetime = {0}; 355 | int[] cred_usage = {0}; 356 | long[] time_rec = {0}; 357 | long inTimeReq; 358 | 359 | gss_name_t_desc dName; 360 | gss_OID_set_desc dMechs; 361 | 362 | /* handle null GSSName arg */ 363 | if (desiredName != null) { 364 | dName = desiredName.getInternGSSName(); 365 | } else { 366 | dName = gsswrapper.GSS_C_NO_NAME; 367 | } 368 | 369 | /* handle time req. Java uses an int to store INDEFINITE, whereas 370 | native uses a long */ 371 | if (timeReq == GSSCredential.INDEFINITE_LIFETIME) { 372 | inTimeReq = (long) timeReq; 373 | } else { 374 | inTimeReq = gsswrapper.GSS_C_INDEFINITE; 375 | } 376 | 377 | /* handle null Oid arg, create gss_OID_set_desc from input set */ 378 | if (desiredMechs != null) { 379 | dMechs = new gss_OID_set_desc(); 380 | for (int i = 0; i < desiredMechs.length; i++) { 381 | maj_status = gsswrapper.gss_add_oid_set_member(min_status, 382 | desiredMechs[i].getNativeOid(), dMechs); 383 | 384 | if (maj_status != gsswrapper.GSS_S_COMPLETE) { 385 | throw new GSSExceptionImpl((int) maj_status, 386 | (int) min_status[0]); 387 | } 388 | } 389 | } else { 390 | dMechs = gsswrapper.GSS_C_NO_OID_SET; 391 | } 392 | 393 | /* initialize internal gss_cred_id_t_desc */ 394 | internGSSCred = new gss_cred_id_t_desc(); 395 | 396 | /* acquire cred */ 397 | maj_status = gsswrapper.gss_acquire_cred(min_status, 398 | dName, 399 | inTimeReq, 400 | dMechs, 401 | credUsage, 402 | internGSSCred, 403 | null, time_rec); 404 | 405 | if (maj_status != gsswrapper.GSS_S_COMPLETE) { 406 | throw new GSSExceptionImpl((int) maj_status, (int) min_status[0]); 407 | } 408 | 409 | this.invalid = false; 410 | return this; 411 | 412 | } 413 | 414 | GSSCredential acquireCred(int usage) throws GSSException { 415 | 416 | return acquireCred((GSSName) null, 417 | GSSCredential.DEFAULT_LIFETIME, (Oid[]) null, usage); 418 | 419 | } 420 | 421 | public gss_cred_id_t_desc getInternGSSCred() { 422 | return this.internGSSCred; 423 | } 424 | 425 | public void setInternGSSCred(gss_cred_id_t_desc newCred) { 426 | if (newCred != null) { 427 | this.internGSSCred = newCred; 428 | this.invalid = false; 429 | } else { 430 | this.internGSSCred = gsswrapper.GSS_C_NO_CREDENTIAL; 431 | this.invalid = false; 432 | } 433 | } 434 | 435 | public void freeGSSCredential() { 436 | if (internGSSCred != null) { 437 | long maj_status = 0; 438 | long[] min_status = {0}; 439 | 440 | maj_status = gsswrapper.gss_release_cred(min_status, 441 | internGSSCred); 442 | } 443 | } 444 | 445 | } 446 | 447 | -------------------------------------------------------------------------------- /src/java/edu/mit/jgss/GSSExceptionImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 by the Massachusetts Institute of Technology. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 12 | * * Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in 14 | * the documentation and/or other materials provided with the 15 | * distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 20 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 21 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 22 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 | * OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package edu.mit.jgss; 31 | 32 | import org.ietf.jgss.GSSException; 33 | 34 | public class GSSExceptionImpl extends GSSException { 35 | 36 | private static final long serialVersionUID = 5343836624172927333L; 37 | 38 | /* set the minor and major codes, internal gss_display_name 39 | will handle setting the error strings */ 40 | public GSSExceptionImpl(int majorCode, int minorCode) { 41 | super(majorCode); 42 | super.setMinor(minorCode, null); 43 | } 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /src/java/edu/mit/jgss/GSSManagerImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 by the Massachusetts Institute of Technology. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 12 | * * Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in 14 | * the documentation and/or other materials provided with the 15 | * distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 20 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 21 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 22 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 | * OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package edu.mit.jgss; 31 | 32 | import java.security.Provider; 33 | 34 | import org.ietf.jgss.GSSException; 35 | import org.ietf.jgss.Oid; 36 | import org.ietf.jgss.GSSContext; 37 | import org.ietf.jgss.GSSCredential; 38 | import org.ietf.jgss.GSSName; 39 | import org.ietf.jgss.GSSManager; 40 | 41 | import edu.mit.jgss.swig.*; 42 | 43 | public class GSSManagerImpl extends GSSManager { 44 | 45 | /* MIT GSSAPI only supports the following two mechanisms: 46 | 1) gss_mech_krb5 1.2.840.113554.1.2.2 47 | 2) gss_mech_krb5_old 1.3.5.1.5.2 48 | */ 49 | public Oid[] getMechs() { 50 | 51 | /* because this implementation doesn't currently support a 52 | service provider framwork, this method just returns the 53 | mechanisms supported by MIT's GSSAPI, listed above */ 54 | 55 | Oid[] mechs = new Oid[2]; 56 | 57 | try { 58 | 59 | mechs[0] = new OidImpl("1.2.840.113554.1.2.2"); 60 | mechs[1] = new OidImpl("1.3.5.1.5.2"); 61 | 62 | } catch (GSSException e) { 63 | /* ignore and continue */ 64 | } 65 | 66 | return mechs; 67 | } 68 | 69 | public Oid[] getNamesForMech(Oid mech) { 70 | 71 | long maj_status = 0; 72 | long[] min_status = {0}; 73 | gss_OID_set_desc mech_names = new gss_OID_set_desc(); 74 | gss_buffer_desc oid_name = new gss_buffer_desc(); 75 | Oid[] mechNames; 76 | int numNames = 0; 77 | 78 | try { 79 | OidImpl tmpMech = new OidImpl(mech.toString()); 80 | 81 | maj_status = gsswrapper.gss_inquire_names_for_mech(min_status, 82 | tmpMech.getNativeOid(), mech_names); 83 | 84 | if (maj_status != gsswrapper.GSS_S_COMPLETE) { 85 | /* just return null since we can't throw an exception here */ 86 | return null; 87 | } 88 | 89 | numNames = (int) mech_names.getCount(); 90 | mechNames = new Oid[numNames]; 91 | for (int i = 0; i < numNames; i++) { 92 | maj_status = gsswrapper.gss_oid_to_str(min_status, 93 | mech_names.getElement(i), oid_name); 94 | mechNames[i] = new Oid(oid_name.getValue()); 95 | } 96 | 97 | gsswrapper.gss_release_buffer(min_status, oid_name); 98 | gsswrapper.gss_release_oid_set(min_status, mech_names); 99 | tmpMech.freeOid(); 100 | 101 | } catch (GSSException e) { 102 | return null; 103 | } 104 | 105 | return mechNames; 106 | } 107 | 108 | public Oid[] getMechsForName(Oid nameType) { 109 | 110 | long maj_status = 0; 111 | long[] min_status = {0}; 112 | gss_OID_set_desc mech_types = new gss_OID_set_desc(); 113 | gss_buffer_desc mech_name = new gss_buffer_desc(); 114 | Oid[] mechs; 115 | int numMechs; 116 | 117 | try { 118 | 119 | /* create a gss_name_t_desc from the nametype we got */ 120 | GSSNameImpl tmpName = (GSSNameImpl) createName("test", nameType); 121 | 122 | maj_status = gsswrapper.gss_inquire_mechs_for_name(min_status, 123 | tmpName.getInternGSSName(), mech_types); 124 | 125 | if (maj_status != gsswrapper.GSS_S_COMPLETE) { 126 | /* just return null since we can't throw an exception here */ 127 | return null; 128 | } 129 | 130 | numMechs = (int) mech_types.getCount(); 131 | mechs = new Oid[numMechs]; 132 | for (int i = 0; i < numMechs; i++) { 133 | maj_status = gsswrapper.gss_oid_to_str(min_status, 134 | mech_types.getElement(i), mech_name); 135 | mechs[i] = new Oid(mech_name.getValue()); 136 | } 137 | 138 | gsswrapper.gss_release_buffer(min_status, mech_name); 139 | gsswrapper.gss_release_oid_set(min_status, mech_types); 140 | tmpName.freeGSSName(); 141 | 142 | } catch (GSSException e) { 143 | return null; 144 | } 145 | 146 | return mechs; 147 | } 148 | 149 | public GSSName createName(String nameStr, Oid nameType) 150 | throws GSSException { 151 | 152 | GSSNameImpl newName = new GSSNameImpl(); 153 | newName.importName(nameStr, nameType); 154 | return newName; 155 | 156 | } 157 | 158 | public GSSName createName(byte[] name, Oid nameType) 159 | throws GSSException { 160 | 161 | GSSNameImpl newName = new GSSNameImpl(); 162 | newName.importName(name, nameType); 163 | return newName; 164 | 165 | } 166 | 167 | public GSSName createName(String nameStr, Oid nameType, Oid mech) 168 | throws GSSException { 169 | 170 | GSSName newName = createName(nameStr, nameType); 171 | GSSName canonicalizedName = newName.canonicalize(mech); 172 | return canonicalizedName; 173 | 174 | } 175 | 176 | public GSSName createName(byte[] name, Oid nameType, Oid mech) 177 | throws GSSException { 178 | 179 | GSSName newName = createName(name, nameType); 180 | GSSName canonicalizedName = newName.canonicalize(mech); 181 | return canonicalizedName; 182 | 183 | } 184 | 185 | public GSSCredential createCredential(int usage) 186 | throws GSSException { 187 | 188 | if (usage != GSSCredential.INITIATE_AND_ACCEPT || 189 | usage != GSSCredential.INITIATE_ONLY || 190 | usage != GSSCredential.ACCEPT_ONLY) { 191 | throw new GSSException(GSSException.FAILURE); 192 | } else { 193 | GSSCredentialImpl newCred = new GSSCredentialImpl(); 194 | newCred.acquireCred(usage); 195 | return newCred; 196 | } 197 | 198 | } 199 | 200 | public GSSCredential createCredential(GSSName aName, int lifetime, 201 | Oid mech, int usage) throws GSSException { 202 | 203 | GSSCredentialImpl newCred = new GSSCredentialImpl(); 204 | 205 | Oid[] mechs = null; 206 | 207 | if (mech != null) { 208 | mechs = new Oid[1]; 209 | mechs[0] = mech; 210 | } 211 | 212 | newCred.acquireCred(aName, lifetime, mechs, usage); 213 | return newCred; 214 | 215 | } 216 | 217 | public GSSCredential createCredential(GSSName aName, int lifetime, 218 | Oid[] mechs, int usage) throws GSSException { 219 | 220 | GSSCredentialImpl newCred = new GSSCredentialImpl(); 221 | newCred.acquireCred(aName, lifetime, mechs, usage); 222 | return newCred; 223 | 224 | } 225 | 226 | public GSSContext createContext(GSSName peer, Oid mech, 227 | GSSCredential myCred, int lifetime) throws GSSException { 228 | 229 | return new GSSContextImpl(peer, mech, myCred, lifetime); 230 | 231 | } 232 | 233 | public GSSContext createContext(GSSCredential myCred) 234 | throws GSSException { 235 | 236 | return new GSSContextImpl(myCred); 237 | 238 | } 239 | 240 | public GSSContext createContext(byte[] interProcessToken) 241 | throws GSSException { 242 | 243 | return new GSSContextImpl(interProcessToken); 244 | 245 | } 246 | 247 | /* this gssapi implementation is wrapped around MIT Kerberos 248 | GSSAPI, which only supported Kerberos v5. Thus, at this time, 249 | a service provider framework is not supported. RFC 5653 states that a 250 | service provider framework is optional, and the implementation should 251 | throw a GSSEXception with GSSException.UNAVAILABLE if not supported. */ 252 | public void addProviderAtFront(Provider p, Oid mech) 253 | throws GSSException { 254 | throw new GSSException(GSSException.UNAVAILABLE); 255 | } 256 | 257 | public void addProviderAtEnd(Provider p, Oid mech) 258 | throws GSSException { 259 | throw new GSSException(GSSException.UNAVAILABLE); 260 | } 261 | 262 | } 263 | -------------------------------------------------------------------------------- /src/java/edu/mit/jgss/GSSNameImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 by the Massachusetts Institute of Technology. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 12 | * * Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in 14 | * the documentation and/or other materials provided with the 15 | * distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 20 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 21 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 22 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 | * OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package edu.mit.jgss; 31 | 32 | import org.ietf.jgss.GSSManager; 33 | import org.ietf.jgss.GSSName; 34 | import org.ietf.jgss.GSSException; 35 | import org.ietf.jgss.Oid; 36 | 37 | import edu.mit.jgss.swig.gss_name_t_desc; 38 | import edu.mit.jgss.swig.gss_buffer_desc; 39 | import edu.mit.jgss.swig.gss_OID_desc; 40 | import edu.mit.jgss.swig.gsswrapper; 41 | 42 | public class GSSNameImpl implements GSSName { 43 | 44 | /* Representing our underlying SWIG-wrapped gss_name_t_desc object */ 45 | private gss_name_t_desc internGSSName; 46 | 47 | /* debugging */ 48 | private boolean DEBUG_ERR = false; 49 | 50 | public boolean equals(GSSName another) throws GSSException { 51 | 52 | long maj_status = 0; 53 | long[] min_status = {0}; 54 | int ret[] = {0}; 55 | 56 | maj_status = gsswrapper.gss_compare_name(min_status, this.internGSSName, 57 | another.getInternGSSName(), ret); 58 | 59 | if (maj_status != gsswrapper.GSS_S_COMPLETE) { 60 | if (DEBUG_ERR == true) 61 | System.out.println("gss_compare_name failed... maj_status = " 62 | + maj_status); 63 | throw new GSSExceptionImpl((int)maj_status, (int)min_status[0]); 64 | } 65 | 66 | if (ret[0] == 1) 67 | return true; 68 | else 69 | return false; 70 | 71 | } 72 | 73 | public boolean equals(Object another) { 74 | 75 | if (! (another instanceof GSSName)) 76 | return false; 77 | 78 | GSSName tmpName = (GSSName) another; 79 | 80 | if (tmpName == null) 81 | throw new NullPointerException("Input Obj is null"); 82 | 83 | try { 84 | return equals(tmpName); 85 | } catch (GSSException e) { 86 | return false; 87 | } 88 | 89 | } 90 | 91 | public GSSName canonicalize(Oid mech) throws GSSException { 92 | long maj_status = 0; 93 | long[] min_status = {0}; 94 | int ret = 0; 95 | gss_OID_desc tmpOid; 96 | 97 | GSSNameImpl canonicalName = new GSSNameImpl(); 98 | gss_name_t_desc tmpName = new gss_name_t_desc(); 99 | 100 | if (mech == null) { 101 | 102 | tmpOid = new gss_OID_desc("1.2.840.113554.1.2.2"); 103 | 104 | } else { 105 | 106 | /* note that underlying native MIT gssapi library only supports 107 | gss_mech_krb5_old and gss_mech_krb5 mechanism types, so 108 | we're explicity requiring gss_mech_krb5 to be used */ 109 | tmpOid = mech.getNativeOid(); 110 | 111 | if (!tmpOid.toDotString().equals("1.2.840.113554.1.2.2")) { 112 | throw new GSSExceptionImpl((int)maj_status, (int)min_status[0]); 113 | } 114 | } 115 | 116 | maj_status = gsswrapper.gss_canonicalize_name(min_status, 117 | internGSSName, 118 | tmpOid, 119 | tmpName); 120 | 121 | if (maj_status != gsswrapper.GSS_S_COMPLETE) { 122 | if (DEBUG_ERR == true) 123 | System.err.println("internal gss_canonicalize_name failed"); 124 | throw new GSSExceptionImpl((int)maj_status, (int)min_status[0]); 125 | } 126 | 127 | ret = canonicalName.setInternGSSName(tmpName); 128 | if (ret != 0) { 129 | if (DEBUG_ERR == true) 130 | System.err.println("setInternGSSName failed after " + 131 | "canonicalize"); 132 | throw new GSSExceptionImpl((int)maj_status, (int)min_status[0]); 133 | } 134 | 135 | return canonicalName; 136 | } 137 | 138 | public byte[] export() throws GSSException { 139 | long maj_status = 0; 140 | long[] min_status = {0}; 141 | 142 | gss_buffer_desc exportName = new gss_buffer_desc(); 143 | maj_status = gsswrapper.gss_export_name(min_status, 144 | this.getInternGSSName(), 145 | exportName); 146 | 147 | if (maj_status != gsswrapper.GSS_S_COMPLETE) { 148 | throw new GSSExceptionImpl((int)maj_status, (int)min_status[0]); 149 | } 150 | 151 | byte[] tmp_array = new byte[(int)exportName.getLength()]; 152 | tmp_array = gsswrapper.getDescArray(exportName); 153 | 154 | gsswrapper.gss_release_buffer(min_status, exportName); 155 | 156 | return tmp_array; 157 | } 158 | 159 | public String toString() { 160 | long maj_status = 0; 161 | long[] min_status = {0}; 162 | String outString; 163 | 164 | gss_buffer_desc output_name_buffer = new gss_buffer_desc(); 165 | gss_OID_desc output_name_type = new gss_OID_desc(); 166 | 167 | maj_status = gsswrapper.gss_display_name(min_status, 168 | this.internGSSName, 169 | output_name_buffer, 170 | output_name_type); 171 | 172 | if (maj_status != gsswrapper.GSS_S_COMPLETE) 173 | return null; 174 | 175 | outString = output_name_buffer.getValue(); 176 | 177 | return outString; 178 | } 179 | 180 | public Oid getStringNameType() throws GSSException { 181 | long maj_status = 0; 182 | long[] min_status = {0}; 183 | 184 | gss_buffer_desc output_name_buffer = new gss_buffer_desc(); 185 | gss_OID_desc output_name_type = new gss_OID_desc(); 186 | 187 | maj_status = gsswrapper.gss_display_name(min_status, 188 | this.getInternGSSName(), 189 | output_name_buffer, 190 | output_name_type); 191 | 192 | if (maj_status != gsswrapper.GSS_S_COMPLETE) { 193 | return null; 194 | } 195 | 196 | Oid newOid = new Oid(output_name_type.toDotString()); 197 | 198 | return newOid; 199 | } 200 | 201 | public boolean isAnonymous() { 202 | 203 | try { 204 | if (GSSName.NT_ANONYMOUS.equals(this.getStringNameType())) 205 | return true; 206 | return false; 207 | } catch (GSSException e) { 208 | return false; 209 | } 210 | } 211 | 212 | public boolean isMN() { 213 | 214 | long maj_status = 0; 215 | long[] min_status = {0}; 216 | gss_buffer_desc exportName = new gss_buffer_desc(); 217 | 218 | /* to test if our GSSName is a MN, we call the native 219 | export_name function and check for the 220 | GSS_S_NAME_NOT_MN error code */ 221 | maj_status = gsswrapper.gss_export_name(min_status, 222 | this.getInternGSSName(), 223 | exportName); 224 | 225 | if (maj_status == gsswrapper.GSS_S_NAME_NOT_MN) { 226 | return false; 227 | } 228 | return true; 229 | 230 | } 231 | 232 | public gss_name_t_desc getInternGSSName() { 233 | return this.internGSSName; 234 | } 235 | 236 | public int setInternGSSName(gss_name_t_desc newName) { 237 | if (newName != null) { 238 | this.internGSSName = newName; 239 | } else { 240 | this.internGSSName = gsswrapper.GSS_C_NO_NAME; 241 | } 242 | 243 | return 0; 244 | } 245 | 246 | GSSName importName(String nameStr, Oid nameType) throws GSSException { 247 | 248 | long maj_status = 0; 249 | long[] min_status = {0}; 250 | gss_buffer_desc nameBuffer = new gss_buffer_desc(); 251 | 252 | if (nameStr == null) { 253 | if (DEBUG_ERR == true) 254 | System.out.println("nameStr == null, during createName"); 255 | throw new GSSExceptionImpl((int)maj_status, (int)min_status[0]); 256 | } 257 | 258 | nameBuffer.setLength(nameStr.length()); 259 | nameBuffer.setValue(nameStr); 260 | 261 | /* Check supported nametypes. If it's not a supported one, or null, 262 | throw exception */ 263 | if (nameType != null && 264 | !nameType.equals(GSSName.NT_HOSTBASED_SERVICE) && 265 | !nameType.equals(GSSName.NT_USER_NAME) && 266 | !nameType.equals(GSSName.NT_MACHINE_UID_NAME) && 267 | !nameType.equals(GSSName.NT_STRING_UID_NAME) && 268 | !nameType.equals(GSSName.NT_ANONYMOUS)) { 269 | /* nametype is not supported */ 270 | if (DEBUG_ERR == true) 271 | System.out.println("nametype not supported"); 272 | throw new GSSExceptionImpl((int)maj_status, (int)min_status[0]); 273 | } 274 | 275 | /* initialize internal gss_name_t_desc */ 276 | internGSSName = new gss_name_t_desc(); 277 | 278 | if (nameType != null) { 279 | maj_status = gsswrapper.gss_import_name(min_status, nameBuffer, 280 | nameType.getNativeOid(), internGSSName); 281 | } else { 282 | /* use the default nametype */ 283 | maj_status = gsswrapper.gss_import_name(min_status, nameBuffer, 284 | null, internGSSName); 285 | } 286 | 287 | if (maj_status != gsswrapper.GSS_S_COMPLETE) { 288 | if (DEBUG_ERR == true) 289 | System.out.println("gss_import_name failed, during createName"); 290 | throw new GSSExceptionImpl((int)maj_status, (int)min_status[0]); 291 | } 292 | 293 | return this; 294 | } 295 | 296 | GSSName importName(byte[] nameStr, Oid nameType) throws GSSException { 297 | 298 | long maj_status = 0; 299 | long[] min_status = {0}; 300 | gss_buffer_desc nameBuffer = new gss_buffer_desc(); 301 | 302 | if (nameStr == null) { 303 | if (DEBUG_ERR == true) 304 | System.out.println("nameStr == null, during createName"); 305 | throw new GSSExceptionImpl((int)maj_status, (int)min_status[0]); 306 | } 307 | 308 | /* copy byte[] to native gss_buffer_desc */ 309 | gsswrapper.setDescArray(nameBuffer, nameStr); 310 | nameBuffer.setLength(nameStr.length); 311 | 312 | /* Check supported nametypes. If it's not a supported one, or null, 313 | throw exception */ 314 | if (nameType != null && 315 | !nameType.equals(GSSName.NT_HOSTBASED_SERVICE) && 316 | !nameType.equals(GSSName.NT_USER_NAME) && 317 | !nameType.equals(GSSName.NT_MACHINE_UID_NAME) && 318 | !nameType.equals(GSSName.NT_STRING_UID_NAME) && 319 | !nameType.equals(GSSName.NT_ANONYMOUS) && 320 | !nameType.equals(GSSName.NT_EXPORT_NAME)) { 321 | /* nametype is not supported */ 322 | if (DEBUG_ERR == true) 323 | System.out.println("nametype not supported"); 324 | throw new GSSExceptionImpl((int)maj_status, (int)min_status[0]); 325 | } 326 | 327 | /* initialize internal gss_name_t_desc */ 328 | internGSSName = new gss_name_t_desc(); 329 | 330 | if (nameType != null) { 331 | maj_status = gsswrapper.gss_import_name(min_status, nameBuffer, 332 | nameType.getNativeOid(), internGSSName); 333 | } else { 334 | /* use the default nametype */ 335 | maj_status = gsswrapper.gss_import_name(min_status, nameBuffer, 336 | null, internGSSName); 337 | } 338 | 339 | if (maj_status != gsswrapper.GSS_S_COMPLETE) { 340 | if (DEBUG_ERR == true) 341 | System.out.println("gss_import_name failed, during createName"); 342 | throw new GSSExceptionImpl((int)maj_status, (int)min_status[0]); 343 | } 344 | 345 | return this; 346 | } 347 | 348 | public void freeGSSName() { 349 | if (internGSSName != null) { 350 | long maj_status = 0; 351 | long[] min_status = {0}; 352 | 353 | maj_status = gsswrapper.gss_release_name(min_status, 354 | internGSSName); 355 | } 356 | } 357 | 358 | } 359 | -------------------------------------------------------------------------------- /src/java/edu/mit/jgss/OidImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 by the Massachusetts Institute of Technology. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 12 | * * Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in 14 | * the documentation and/or other materials provided with the 15 | * distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 20 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 21 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 22 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 | * OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package edu.mit.jgss; 31 | 32 | import java.io.InputStream; 33 | import org.ietf.jgss.Oid; 34 | import org.ietf.jgss.GSSException; 35 | 36 | import edu.mit.jgss.swig.*; 37 | 38 | public class OidImpl extends Oid { 39 | 40 | public OidImpl(String strOid) throws GSSException { 41 | super(strOid); 42 | } 43 | 44 | public OidImpl(InputStream derOid) throws GSSException { 45 | super(derOid); 46 | } 47 | 48 | public OidImpl(byte[] derOid) throws GSSException { 49 | super(derOid); 50 | } 51 | 52 | public gss_OID_desc getNativeOid() { 53 | return super.oid; 54 | } 55 | 56 | public void setNativeOid(gss_OID_desc newOid) { 57 | if (newOid != null) { 58 | super.oid = newOid; 59 | super.derOid = null; 60 | } 61 | } 62 | 63 | public void freeOid() { 64 | if (super.oid != null) { 65 | 66 | long maj_status = 0; 67 | long[] min_status = {0}; 68 | 69 | maj_status = gsswrapper.gss_release_oid(min_status, 70 | super.oid); 71 | } 72 | } 73 | } 74 | 75 | 76 | -------------------------------------------------------------------------------- /src/java/edu/mit/jgss/OidUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 by the Massachusetts Institute of Technology. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 12 | * * Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in 14 | * the documentation and/or other materials provided with the 15 | * distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 20 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 21 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 22 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 | * OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package edu.mit.jgss; 31 | 32 | import java.io.*; 33 | import java.util.regex.*; 34 | 35 | /** 36 | * Contains utility functions for Oid object conversions. 37 | */ 38 | public class OidUtil { 39 | 40 | /** 41 | * Converts a DER-encoded Oid from a byte array to a dot-separated 42 | * String representation. 43 | * 44 | * @param oid DER-encoded Oid byte array 45 | * @return Oid in dot-separated String representation 46 | * 47 | */ 48 | public static String OidDer2String(byte[] oid) { 49 | // TODO - not necessary, but might be useful in the future? 50 | return null; 51 | } 52 | 53 | /** 54 | * Converts a DER-encoded Oid from an InputStream to a dot-separated 55 | * String representation. 56 | * 57 | * @param oid DER-encoded Oid InputStream 58 | * @return Oid in dot-separated String representation 59 | * 60 | */ 61 | public static byte[] OidStream2DER(InputStream oid) throws IOException { 62 | 63 | int tag; 64 | int length; 65 | ByteArrayOutputStream outOid = new ByteArrayOutputStream(); 66 | 67 | try { 68 | tag = oid.read(); 69 | length = oid.read(); 70 | outOid.write(tag); 71 | outOid.write(length); 72 | 73 | for (int i = 0; i < length; i++) { 74 | outOid.write(oid.read()); 75 | } 76 | } catch (IOException e) { 77 | throw new IOException("I/O Error occurred when reading InputStream"); 78 | } 79 | 80 | return outOid.toByteArray(); 81 | } 82 | 83 | /** 84 | * Converts an Oid in dot-separated string representation to a 85 | * DER-encoded byte array. 86 | * 87 | * @param oid Oid in dot-separated String representation 88 | * @return DER-encoded Oid byte array 89 | * 90 | */ 91 | public static byte[] OidString2DER(String oid) { 92 | 93 | int octet = 0; 94 | int base = 0; 95 | int times = 0; 96 | int tbMaj = 0; 97 | 98 | ByteArrayOutputStream bytearray = new ByteArrayOutputStream(); 99 | ByteArrayOutputStream tmpArray = new ByteArrayOutputStream(); 100 | 101 | /* Convert String to int[] */ 102 | String[] tmp = oid.split("\\."); 103 | int[] input = new int[tmp.length]; 104 | for (int i = 0; i < tmp.length; i++ ) { 105 | input[i] = Integer.parseInt(tmp[i]); 106 | } 107 | 108 | /* Add tag for OID (0x06) */ 109 | bytearray.write(6); 110 | 111 | /* Calculate first byte */ 112 | tmpArray.write((input[0]*40) + input[1]); 113 | 114 | /* Encode the rest of the OID nodes in DER format */ 115 | for (int j = 2; j < input.length; j++) { 116 | 117 | if (input[j] <= 127) { 118 | 119 | /* Encode directly */ 120 | tmpArray.write(input[j]); 121 | 122 | } else if (input[j] > 127) { 123 | 124 | /* Reset variables */ 125 | octet = input[j]; 126 | base = 128; 127 | times = 0; 128 | tbMaj = 8; 129 | 130 | /* If bigger than 16383 */ 131 | if (octet > 16383) { 132 | 133 | base = 262144; 134 | times = (int) Math.floor(octet / base); 135 | tbMaj = 8 + times; 136 | octet = octet - (times * base); 137 | 138 | base = 16384; 139 | times = (int) Math.floor(octet / base); 140 | tmpArray.write((16*tbMaj) + times); 141 | 142 | /* Reset tbMaj in case we're skipping next if */ 143 | tbMaj = 8; 144 | } 145 | 146 | /* 2047 < octet <= 16383 */ 147 | if (octet > 2047 && octet <= 16383) { 148 | 149 | base = 2048; 150 | times = (int) Math.floor(octet / base); 151 | tbMaj = 8 + times; 152 | octet = octet - (times * base); 153 | } 154 | 155 | /* 127 < octet < 2047 */ 156 | base = 128; 157 | times = (int) Math.floor(octet / base); 158 | tmpArray.write((16 * tbMaj) + times); 159 | tmpArray.write(octet - (times * 128)); 160 | } 161 | } 162 | 163 | byte[] convArray = tmpArray.toByteArray(); 164 | bytearray.write(convArray.length); 165 | for (int k = 0; k < convArray.length; k++) { 166 | bytearray.write(convArray[k]); 167 | } 168 | 169 | return bytearray.toByteArray(); 170 | 171 | } /* end OidString2DER */ 172 | 173 | /** 174 | * Verifies that an OID is in dot-separated string format. 175 | * TODO: Make this more robust. 176 | * 177 | * @param oid OID to verify 178 | * @return true if OID is valid, false otherwise 179 | */ 180 | public static boolean verifyOid(String oid) { 181 | 182 | // Pattern to match '.' separated Oid string format 183 | Pattern oidPattern = Pattern.compile("^([0-9]+.{1})+[0-9]+$"); 184 | Matcher oidIN = oidPattern.matcher(oid); 185 | 186 | if (oidIN.matches()) { 187 | return true; 188 | } else { 189 | return false; 190 | } 191 | } 192 | 193 | /** 194 | * Verifies DER-encoded byte array has a valid tag and length 195 | * 196 | * @param oid OID to verify, DER-encoded byte array 197 | * @return true if OID is valid, false otherwise 198 | */ 199 | public static boolean verifyOid(byte[] oid) { 200 | 201 | /* verify tag is set to an OID (0x06) */ 202 | if (oid[0] != 6) 203 | return false; 204 | 205 | /* verify length is correct */ 206 | if (oid.length-2 != oid[1]) { 207 | return false; 208 | } 209 | 210 | return true; 211 | } 212 | 213 | } 214 | -------------------------------------------------------------------------------- /src/java/edu/mit/jgss/swig/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cconlon/kerberos-java-gssapi/1a70d4c68d2b59a3b61a70fb299753d4fbacc0cf/src/java/edu/mit/jgss/swig/.gitignore -------------------------------------------------------------------------------- /src/java/org/ietf/jgss/ChannelBinding.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 by the Massachusetts Institute of Technology. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 12 | * * Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in 14 | * the documentation and/or other materials provided with the 15 | * distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 20 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 21 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 22 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 | * OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package org.ietf.jgss; 31 | 32 | import java.net.InetAddress; 33 | import java.util.Arrays; 34 | import edu.mit.jgss.swig.*; 35 | 36 | /** 37 | * Class to represent GSS-API caller-provided channel binding information. 38 | * Channel bindings are used to allow callers to bind the establishment 39 | * of the security context to relevant characteristics like addresses 40 | * or to application-specific data. 41 | * 42 | * The use of channel bindings is optional in GSS-API. Because channel binding 43 | * information may be transmitted in context establishment tokens, 44 | * applications should therefore not use confidential data as channel-binding 45 | * components. 46 | */ 47 | public class ChannelBinding { 48 | 49 | protected gss_channel_bindings_struct channelBindStruct; 50 | 51 | /* Address of the context initiator */ 52 | private InetAddress initAddr = null; 53 | 54 | /* Address of the context acceptor */ 55 | private InetAddress acceptAddr = null; 56 | 57 | /* Application-supplied data to be used as part of the channel bindings */ 58 | private byte[] appData = null; 59 | 60 | /** 61 | * Creates ChannelBinding object with the given address and data 62 | * information. "null" values may be used for any fields that the 63 | * application does not want to specify. 64 | * 65 | * @param initAddr the address of the context initiator. 66 | * @param acceptAddr the address fo the context acceptor. 67 | * @param appData application-supplied data to be used as part of the 68 | * channel bindings. 69 | */ 70 | public ChannelBinding(InetAddress initAddr, InetAddress acceptAddr, 71 | byte[] appData) { 72 | 73 | this(appData); 74 | 75 | /* If the user passes in null values for all arguments, we'll 76 | just set our internal gss_channel_bindings_struct equal to 77 | GSS_C_NO_CHANNEL_BINDINGS */ 78 | if (initAddr == null && acceptAddr == null && appData == null) { 79 | channelBindStruct = gsswrapper.GSS_C_NO_CHANNEL_BINDINGS; 80 | return; 81 | } 82 | 83 | /* otherwise, continue with setup as normal */ 84 | channelBindStruct = new gss_channel_bindings_struct(); 85 | 86 | if (initAddr != null) { 87 | this.initAddr = initAddr; 88 | channelBindStruct.setInitiator_addrtype(gsswrapper.GSS_C_AF_INET); 89 | gss_buffer_desc initAddrBuff = new gss_buffer_desc(); 90 | gsswrapper.setDescArray(initAddrBuff, initAddr.getAddress()); 91 | initAddrBuff.setLength(initAddr.getAddress().length); 92 | channelBindStruct.setInitiator_address(initAddrBuff); 93 | } 94 | 95 | if (acceptAddr != null) { 96 | this.acceptAddr = acceptAddr; 97 | channelBindStruct.setAcceptor_addrtype(gsswrapper.GSS_C_AF_INET); 98 | gss_buffer_desc acceptAddrBuff = new gss_buffer_desc(); 99 | gsswrapper.setDescArray(acceptAddrBuff, acceptAddr.getAddress()); 100 | acceptAddrBuff.setLength(acceptAddr.getAddress().length); 101 | channelBindStruct.setAcceptor_address(acceptAddrBuff); 102 | } 103 | 104 | if (appData != null) { 105 | setAppData(appData); 106 | 107 | gss_buffer_desc appBuffer = new gss_buffer_desc(); 108 | gsswrapper.setDescArray(appBuffer, appData); 109 | appBuffer.setLength(appData.length); 110 | channelBindStruct.setApplication_data(appBuffer); 111 | } 112 | 113 | } 114 | 115 | /** 116 | * Creates ChannelBinding object with the supplied application data 117 | * (without any addressing information). 118 | * 119 | * @param appData application-supplied data to be used as part of the 120 | * channel bindings. 121 | */ 122 | public ChannelBinding(byte[] appData) { 123 | 124 | if (appData != null) { 125 | 126 | channelBindStruct = new gss_channel_bindings_struct(); 127 | setAppData(appData); 128 | 129 | gss_buffer_desc appBuffer = new gss_buffer_desc(); 130 | gsswrapper.setDescArray(appBuffer, appData); 131 | appBuffer.setLength(appData.length); 132 | channelBindStruct.setApplication_data(appBuffer); 133 | } else { 134 | channelBindStruct = gsswrapper.GSS_C_NO_CHANNEL_BINDINGS; 135 | } 136 | } 137 | 138 | /** 139 | * Returns the address of the context initiator. 140 | * 141 | * @return address of the context initiator. 142 | */ 143 | public InetAddress getInitiatorAddress() { 144 | 145 | return initAddr; 146 | } 147 | 148 | /** 149 | * Returns the address of the context acceptor. 150 | * 151 | * @return address of the context acceptor. 152 | */ 153 | public InetAddress getAcceptorAddress() { 154 | 155 | return acceptAddr; 156 | } 157 | 158 | /** 159 | * Returns the application data being used as part of the 160 | * ChannelBinding. "null" is returned if no application data has been 161 | * specified for the channel bindings. 162 | * 163 | * @return application-supplied data used as part of the ChannelBinding, 164 | * "null" if not set. 165 | */ 166 | public byte[] getApplicationData() { 167 | 168 | if (appData == null) { 169 | return null; 170 | } else { 171 | byte[] tmp = new byte[this.appData.length]; 172 | System.arraycopy(this.appData, 0, tmp, 0, this.appData.length); 173 | return tmp; 174 | } 175 | } 176 | 177 | /** 178 | * Returns "true" if two ChannelBinding objects match. 179 | * 180 | * @return "true" if the two objects are equal, "false" otherwise. 181 | */ 182 | public boolean equals(Object obj) { 183 | 184 | if (!(obj instanceof ChannelBinding)) { 185 | return false; 186 | } 187 | 188 | ChannelBinding tmp = (ChannelBinding) obj; 189 | 190 | if (!initAddr.equals(tmp.initAddr) || 191 | !(acceptAddr.equals(tmp.acceptAddr))) { 192 | return false; 193 | } 194 | 195 | if (!Arrays.equals(appData, tmp.appData)) { 196 | return false; 197 | } 198 | 199 | return true; 200 | } 201 | 202 | private void setAppData(byte[] appData) { 203 | if (appData != null) { 204 | this.appData = new byte[appData.length]; 205 | System.arraycopy(appData, 0, this.appData, 0, appData.length); 206 | } 207 | } 208 | 209 | } 210 | -------------------------------------------------------------------------------- /src/java/org/ietf/jgss/GSSCredential.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 by the Massachusetts Institute of Technology. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 12 | * * Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in 14 | * the documentation and/or other materials provided with the 15 | * distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 20 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 21 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 22 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 | * OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package org.ietf.jgss; 31 | 32 | /** 33 | * This interface encapsulates the GSS-API credentials for an entity. 34 | * This interface is defined in section 7.3 of RFC 5653 35 | * (http://tools.ietf.org/html/rfc5653). 36 | */ 37 | public interface GSSCredential extends Cloneable { 38 | 39 | /** 40 | * Flag requesting that credential be albe to be used for both 41 | * context initiation and acceptance. 42 | */ 43 | public static final int INITIATE_AND_ACCEPT = 0; 44 | 45 | /** 46 | * Flag requesting that credential be able to be used for context 47 | * initialization only. 48 | */ 49 | public static final int INITIATE_ONLY = 1; 50 | 51 | /** 52 | * Flag requesting that credential be able to be used for context 53 | * acceptance only. 54 | */ 55 | public static final int ACCEPT_ONLY = 2; 56 | 57 | /** 58 | * Lifetime constant representing the default credential lifetime. 59 | */ 60 | public static final int DEFAULT_LIFETIME = 0; 61 | 62 | /** 63 | * Lifetime constant representing indefinite credential lifetime. 64 | */ 65 | public static final int INDEFINITE_LIFETIME = Integer.MAX_VALUE; 66 | 67 | /** 68 | * Releases any sensitive information that the GSSCredential object 69 | * may be containing. This should be called as soon as the credential 70 | * is no longer needed to minimize the time any sensitive information 71 | * is maintained. 72 | * 73 | * @throws GSSException 74 | */ 75 | public void dispose() throws GSSException; 76 | 77 | /** 78 | * Retrieves the name of the entity that the credential asserts. 79 | * 80 | * @return name of entity that the credential asserts. 81 | * @throws GSSException 82 | */ 83 | public GSSName getName() throws GSSException; 84 | 85 | /** 86 | * Retrieves a mechanism name of the entity that the credential asserts. 87 | * Equivalent to calling canonicalize() on the name returned from 88 | * GSSCredential.getName(). 89 | * 90 | * @param mechOID mechanism for which information shoud be returned. 91 | * @return mechanism name of entity that the credential asserts. 92 | * @throws GSSException 93 | */ 94 | public GSSName getName(Oid mechOID) throws GSSException; 95 | 96 | /** 97 | * Returns the remaining lifetime in seconds for the credential. 98 | * 99 | * @return remaining lifetime in seconds for the credential. 100 | * @throws GSSException 101 | */ 102 | public int getRemainingLifetime() throws GSSException; 103 | 104 | /** 105 | * Returns the remaining lifetime in seconds for the credential to 106 | * remain capable of initiating security contexts under the specified 107 | * mechanism. A return value of GSSCredential.INDEFINITE_LIFETIME 108 | * indicates that the credential does not expire for context initiation. 109 | * A return value of 0 indicates that the credential is already expired. 110 | * 111 | * @param mech mechanism for which information should be returned. 112 | * @return remaining lifetime in seconds for credential to remain 113 | * capable of initiating security contexts, 114 | * GSSCredential.INDEFINITE_LIFETIME if it never expires, or 0 if 115 | * it has already expired. 116 | * @throws GSSException 117 | */ 118 | public int getRemainingInitLifetime(Oid mech) throws GSSException; 119 | 120 | /** 121 | * Returns the remaining lifetime in seconds for the credential to 122 | * remain capable of accepting security contexts under the specified 123 | * mechanism. A return value of GSSCredential.INDEFINITE_LIFETIME 124 | * indicates that the credential does not expire for context acceptance. 125 | * A return value of 0 indicates that the credential is already expired. 126 | * 127 | * @param mech mechanism for which information should be returned. 128 | * @return remaining lifetime in seconds for credential to remain 129 | * capable of accepting security contexts, 130 | * GSSCredential.INDEFINITE_LIFETIME if it never expires, or 0 if 131 | * it has already expired. 132 | * @throws GSSException 133 | */ 134 | public int getRemainingAcceptLifetime(Oid mech) throws GSSException; 135 | 136 | /** 137 | * Returns the credential usage flag as a union over all mechanisms. 138 | * 139 | * @return either GSSCredential.INITIATE_AND_ACCEPT(0), 140 | * GSSCredential.INITIATE_ONLY(1), or GSSCredential.ACCEPT_ONLY(2). 141 | * @throws GSSException 142 | */ 143 | public int getUsage() throws GSSException; 144 | 145 | /** 146 | * Returns the credential usage flag for the specified mechanism only. 147 | * 148 | * @return either GSSCredential.INITIATE_AND_ACCEPT(0), 149 | * GSSCredential.INITIATE_ONLY(1), or GSSCredential.ACCEPT_ONLY(2). 150 | * @throws GSSException 151 | */ 152 | public int getUsage(Oid mechOID) throws GSSException; 153 | 154 | /** 155 | * Returns an array of mechanisms supported by this credential. 156 | * 157 | * @return array of mechanisms supported by this credential. 158 | * @throws GSSException 159 | */ 160 | public Oid[] getMechs() throws GSSException; 161 | 162 | /** 163 | * Adds a mechanism-specific credential-element to an existing 164 | * credential, thus allowing the construction of a credential one 165 | * mechanism at a time. 166 | * 167 | * For initLifetime and acceptLifetime, use 168 | * GSSCredential.INDEFINITE_LIFETIME to request that credentials have 169 | * the maximum permitted lifetime. Use GSSCredential.DEFAULT_LIFETIME 170 | * to request default credential lifetime. 171 | * 172 | * The value of "usage" must be one of: 173 | * GSSCredential.INITIATE_AND_ACCEPT(0), 174 | * GSSCredential.INITIATE_ONLY(1), or 175 | * GSSCredential.ACCEPT_ONLY(2) 176 | * 177 | * @param aName name of principal for whom credential is to be acquired. 178 | * @param initLifetime number of seconds that credentials should 179 | * remain valid for initiating of security contexts. 180 | * @param acceptLifetime number of seconds that credentials should 181 | * remain valid for accepting fo security contexts. 182 | * @param mech mechanisms over which the credential is to be acquired. 183 | * @param usage intended usage for this credential object. 184 | * @throws GSSException 185 | */ 186 | public void add(GSSName aName, int initLifetime, int acceptLifetime, 187 | Oid mech, int usage) throws GSSException; 188 | 189 | /** 190 | * Tests if this GSSCredential refers to the same entity as the supplied 191 | * object. To be equal, the two credentials must be acquired over the 192 | * same mechanisms and must refer to the same principal. 193 | * 194 | * @param another GSSCredential object for comparison. 195 | * @return "true" if the two credentials are equal, otherwise "false". 196 | */ 197 | public boolean equals(Object another); 198 | 199 | } 200 | -------------------------------------------------------------------------------- /src/java/org/ietf/jgss/GSSException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 by the Massachusetts Institute of Technology. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 12 | * * Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in 14 | * the documentation and/or other materials provided with the 15 | * distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 20 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 21 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 22 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 | * OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package org.ietf.jgss; 31 | 32 | import edu.mit.jgss.swig.*; 33 | 34 | public class GSSException extends Exception { 35 | 36 | private static final long serialVersionUID = -5142354087553823574L; 37 | 38 | public static final int BAD_BINDINGS = 1; 39 | public static final int BAD_MECH = 2; 40 | public static final int BAD_NAME = 3; 41 | public static final int BAD_NAMETYPE = 4; 42 | public static final int BAD_STATUS = 5; 43 | public static final int BAD_MIC = 6; 44 | public static final int CONTEXT_EXPIRED = 7; 45 | public static final int CREDENTIALS_EXPIRED = 8; 46 | public static final int DEFECTIVE_CREDENTIAL = 9; 47 | public static final int DEFECTIVE_TOKEN = 10; 48 | public static final int FAILURE = 11; 49 | public static final int NO_CONTEXT = 12; 50 | public static final int NO_CRED = 13; 51 | public static final int BAD_QOP = 14; 52 | public static final int UNAUTHORIZED = 15; 53 | public static final int UNAVAILABLE = 16; 54 | public static final int DUPLICATE_ELEMENT = 17; 55 | public static final int NAME_NOT_MN = 18; 56 | public static final int DUPLICATE_TOKEN = 19; 57 | public static final int OLD_TOKEN = 20; 58 | public static final int UNSEQ_TOKEN = 21; 59 | public static final int GAP_TOKEN = 22; 60 | 61 | private int majCode; 62 | private int minCode; 63 | private String minString; 64 | private String majString; 65 | 66 | public GSSException(int majorCode) { 67 | super(); 68 | this.majCode = majorCode; 69 | } 70 | 71 | public GSSException(int majorCode, int minorCode, String minorString) { 72 | super(); 73 | this.majCode = majorCode; 74 | this.minCode = minorCode; 75 | this.minString = minorString; 76 | } 77 | 78 | public int getMajor() { 79 | return this.majCode; 80 | } 81 | 82 | public int getMinor() { 83 | return this.minCode; 84 | } 85 | 86 | public String getMajorString() { 87 | 88 | long[] msg_ctx = {0}; 89 | long ret = 0; 90 | gss_buffer_desc storeBuff = new gss_buffer_desc(); 91 | 92 | ret = gsswrapper.gss_display_status_wrap(minCode, majCode, 93 | gsswrapper.GSS_C_GSS_CODE, 94 | gsswrapper.GSS_C_NO_OID, 95 | msg_ctx, storeBuff); 96 | if (ret != gsswrapper.GSS_S_COMPLETE) { 97 | this.majString = null; 98 | } else { 99 | this.majString = storeBuff.getValue(); 100 | } 101 | 102 | return this.majString; 103 | } 104 | 105 | public String getMinorString() { 106 | 107 | long[] msg_ctx = {0}; 108 | long ret = 0; 109 | gss_buffer_desc storeBuff = new gss_buffer_desc(); 110 | 111 | ret = gsswrapper.gss_display_status_wrap(majCode, minCode, 112 | gsswrapper.GSS_C_MECH_CODE, 113 | gsswrapper.GSS_C_NO_OID, 114 | msg_ctx, storeBuff); 115 | 116 | if (ret != gsswrapper.GSS_S_COMPLETE) { 117 | this.minString = null; 118 | } else { 119 | this.minString = storeBuff.getValue(); 120 | } 121 | return this.minString; 122 | } 123 | 124 | public void setMinor(int minorCode, String message) { 125 | this.minCode = minorCode; 126 | this.minString = message; 127 | } 128 | 129 | @Override 130 | public String toString() { 131 | return "GSSException: " + getMessage(); 132 | } 133 | 134 | @Override 135 | public String getMessage() { 136 | return "Major Status: (" + getMajor() + ", " + getMajorString() + "), " + "Minor Status: (" + getMinor() + ", " + getMinorString() + ")"; 137 | } 138 | 139 | } 140 | -------------------------------------------------------------------------------- /src/java/org/ietf/jgss/GSSManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 by the Massachusetts Institute of Technology. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 12 | * * Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in 14 | * the documentation and/or other materials provided with the 15 | * distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 20 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 21 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 22 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 | * OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package org.ietf.jgss; 31 | 32 | import java.security.Provider; 33 | 34 | /** 35 | * Abstract class that serves as a factory for three GSS interfaces: 36 | * GSSName, GSSCredential, and GSSContext. It also provides methods for 37 | * applications to determine what mechanisms are available from the GSS 38 | * implementation and what name types these mechanisms support. 39 | * 40 | * This abstract class is defined in section 7.1 of RFC 5653 41 | * (http://tools.ietf.org/html/rfc5653). 42 | */ 43 | public abstract class GSSManager { 44 | 45 | /** 46 | * Returns the default GSSManager implementation. 47 | * 48 | * @return default GSSManager implementation. 49 | */ 50 | public static GSSManager getInstance() { 51 | return new edu.mit.jgss.GSSManagerImpl(); 52 | } 53 | 54 | /** 55 | * Returns an array of Oid objects indicating the mechanisms available 56 | * to GSS-API callers. 57 | * 58 | * @return array of Oid objects indicating the mechanisms available to 59 | * GSS-API callers. 60 | */ 61 | public abstract Oid[] getMechs(); 62 | 63 | /** 64 | * Returns name type Oids supported by the specified mechanism. 65 | * 66 | * @param mech Oid object for the mechanism to query. 67 | * @return name type Oids supported by mech. 68 | * @throws GSSException 69 | */ 70 | public abstract Oid[] getNamesForMech(Oid mech) 71 | throws GSSException; 72 | 73 | /** 74 | * Returns array of Oid objects corresponding to the mechanisms that 75 | * support the specific name type. If no mechanisms are found, "null" 76 | * is returned. 77 | * 78 | * @param nameType Oid object for the name type. 79 | * @return array of Oid objects with the mechanisms supported by nameType. 80 | */ 81 | public abstract Oid[] getMechsForName(Oid nameType); 82 | 83 | /** 84 | * Converts a contiguous string name from the specified namespace to a 85 | * GSSName object. In general, the GSSName object created will not be 86 | * a MN. 87 | * 88 | * @param nameStr string representing a printable form of the name to 89 | * create. 90 | * @param nameType Oid specifying the namespace of the printable name. 91 | * "null" can be used to specify that a mechanism-specific default 92 | * printable syntax should be assumed by each mechanism that examines 93 | * nameStr. 94 | * @return GSSName representation of the string name nameStr. 95 | * @throws GSSException 96 | */ 97 | public abstract GSSName createName(String nameStr, Oid nameType) 98 | throws GSSException; 99 | 100 | /** 101 | * Converts a contiguous byte array containing a name from the specified 102 | * namespace to a GSSName object. In general, the GSSName object created 103 | * will not be a MN. 104 | * 105 | * @param name byte array containing the name to create. 106 | * @param nameType Oid specifying the namespace of the printable name. 107 | * "null" can be used to specify that a mechanism-specific default 108 | * printable syntax should be assumed by each mechanism that examines 109 | * nameStr. 110 | * @return GSSName representation of the string name represented in name. 111 | * @throws GSSException 112 | */ 113 | public abstract GSSName createName(byte[] name, Oid nameType) 114 | throws GSSException; 115 | 116 | /** 117 | * Converts a contiguous string name from the specified namespace to a 118 | * GSSName object that is a mechanism name (MN). This method is equivalent 119 | * to calling createName() and GSSName.canonicalize(). 120 | * 121 | * @param nameStr string representing a printable form of the name to 122 | * create. 123 | * @param nameType Oid specifying the namespace of the printable name 124 | * supplied. "null" may be used to specify that a mechanism-specific 125 | * default printable syntax should be assumed when the mechanism 126 | * examines nameStr. 127 | * @param mech Oid specifying the mechanism for which this name 128 | * should be created. 129 | * @return GSSName representation of the string name, nameStr. 130 | * @throws GSSException 131 | */ 132 | public abstract GSSName createName(String nameStr, Oid nameType, 133 | Oid mech) throws GSSException; 134 | 135 | /** 136 | * Converts a contiguous byte array containing a name from the 137 | * specified namespace to a GSSName object that is a MN. This method 138 | * is the equivalent to calling createName() and GSSName.canonicalize(). 139 | * 140 | * @param name byte array representing the name to create 141 | * @param nameType Oid specifying the namespace of the name supplied 142 | * in the byte array. "null" may be used to specify that a mechanism- 143 | * specific default syntax should be assumed by each mechanism that 144 | * examines the byte array. 145 | * @param mech Oid specifying the mechanism for which this name should be 146 | * created. 147 | * @return GSSName representation of the string name held in name. 148 | * @throws GSSException 149 | */ 150 | public abstract GSSName createName(byte[] name, Oid nameType, Oid mech) 151 | throws GSSException; 152 | 153 | /** 154 | * Acquires default credentials. This causes the GSS-API to use 155 | * system-specific defaults for the set of mechanisms, name, and 156 | * a DEFAULT lifetime. 157 | * 158 | * @param usage the intented usage of this credential object. This value 159 | * must be either GSSCredential.INITIATE_AND_ACCEPT(0), 160 | * GSSCredential.INITIATE_ONLY(1), or GSSCredential.ACCEPT_ONLY(2). 161 | * @return the created GSSCredential object. 162 | * @throws GSSException 163 | */ 164 | public abstract GSSCredential createCredential(int usage) 165 | throws GSSException; 166 | 167 | /** 168 | * Acquires a single mechanism credential. 169 | * 170 | * @param aName name of the principal for whom this credential is to be 171 | * acquired. Use "null" to specify the default principal. 172 | * @param lifetime number of seconds that credentials should remain 173 | * valid. Use GSSCredential.INDEFINITE_LIFETIME to request that the 174 | * credentials have the maximum permitted lifetime. Use 175 | * GSSCredential.DEFAULT_LIFETIME to request default credential lifetime. 176 | * @param mech Oid of the desired mechanism. Use "(Oid) null" to request 177 | * the default mechanism(s). 178 | * @param usage the intented usage of this credential object. This value 179 | * must be either GSSCredential.INITIATE_AND_ACCEPT(0), 180 | * GSSCredential.INITIATE_ONLY(1), or GSSCredential.ACCEPT_ONLY(2). 181 | * @return the created GSSCredential object. 182 | * @throws GSSException 183 | */ 184 | public abstract GSSCredential createCredential(GSSName aName, 185 | int lifetime, Oid mech, int usage) throws GSSException; 186 | 187 | /** 188 | * Acquires credentials for each of the mechanisms specified in the 189 | * array called mechs. To determine the list of mechanisms for which 190 | * the acquisition of credentials succeeded, the caller should use 191 | * the GSSCredential.getMechs() method. 192 | * 193 | * @param aName Name of the principal for whom this credential is to be 194 | * acquired. Use "null" to specify the default principal. 195 | * @param lifetime number of seconds that credentials should remain 196 | * valid. Use GSSCredential.INDEFINITE_LIFETIME to request that the 197 | * credentials have the maximum permitted lifetime. Use 198 | * GSSCredential.DEFAULT_LIFETIME to request default credential lifetime. 199 | * @param mechs array of mechanisms over which the credential is to be 200 | * acquired. Use "(Oid[]) null" for requesting a system-specific 201 | * default set of mechanisms. 202 | * @param usage the intented usage of this credential object. This value 203 | * must be either GSSCredential.INITIATE_AND_ACCEPT(0), 204 | * GSSCredential.INITIATE_ONLY(1), or GSSCredential.ACCEPT_ONLY(2). 205 | * @return the created GSSCredential object. 206 | * @throws GSSException 207 | */ 208 | public abstract GSSCredential createCredential(GSSName aName, 209 | int lifetime, Oid[] mechs, int usage) throws GSSException; 210 | 211 | /** 212 | * Creates a context on the initiator's side. Context flags may be 213 | * modified through the mutator methods prior to calling 214 | * GSSContext.initSecContext(). 215 | * 216 | * @param peer name of the target peer. 217 | * @param mech Oid of the desired mechanism. Use "(Oid) null" to request 218 | * the default mechanism. 219 | * @param myCred credentials of the initiator. Use "null" to act as a 220 | * default initiator principal. 221 | * @param lifetime The request lifetime, in seconds, for the context. 222 | * Use GSSContext.INDEFINITE_LIFETIME and GSSContext.DEFAULT_LIFETIME to 223 | * request indefinite or default context lifetime. 224 | * @return the created GSSContext object. 225 | * @throws GSSException 226 | */ 227 | public abstract GSSContext createContext(GSSName peer, Oid mech, 228 | GSSCredential myCred, int lifetime) throws GSSException; 229 | 230 | /** 231 | * Creates a context on the acceptor's side. The context properties will 232 | * be determined from the input token supplied to the accept method. 233 | * 234 | * @param myCred credentials for the acceptor. Use "null" to act as a 235 | * default acceptor principal. 236 | * @return the created GSSContext object. 237 | * @throws GSSException 238 | */ 239 | public abstract GSSContext createContext(GSSCredential myCred) 240 | throws GSSException; 241 | 242 | /** 243 | * Creates a previously-exported context. The context properties will 244 | * be determined from the input token and can't be modified 245 | * through the set methods. 246 | * 247 | * @param interProcessToken token previously emitted from the export 248 | * method. 249 | * @return the created GSSContext object. 250 | * @throws GSSException 251 | */ 252 | public abstract GSSContext createContext(byte[] interProcessToken) 253 | throws GSSException; 254 | 255 | /** 256 | * Indicates that a specified provider should be used ahead of all 257 | * other providers when support for the given mechanism is desired. When 258 | * "null" is used in place of the Oid for the mechanism, the GSSManager 259 | * must use the indicated provider ahead of all others no matter what the 260 | * mechanism is. Only when the indicated provider does not support the 261 | * needed mechanism should the GSSManager move on to a different provider. 262 | * 263 | * @param p provider instance that should be used. 264 | * @param mech mechanism for which the provider is being set. 265 | * @throws GSSException 266 | */ 267 | public abstract void addProviderAtFront(Provider p, Oid mech) 268 | throws GSSException; 269 | 270 | /** 271 | * Indicates that the application would like a particular provider to 272 | * be used if no other provider can be found that supports the given 273 | * mechanism. When "null" is used instead of an Oid for the mechanism, 274 | * the GSSManager must use the indicated provider for any mechanism. 275 | * 276 | * @param p provider instance that should be used whenever support is 277 | * needed for mech. 278 | * @param mech mechanism for which the provider is being set. 279 | * @throws GSSException 280 | */ 281 | public abstract void addProviderAtEnd(Provider p, Oid mech) 282 | throws GSSException; 283 | 284 | } 285 | -------------------------------------------------------------------------------- /src/java/org/ietf/jgss/GSSName.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 by the Massachusetts Institute of Technology. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 12 | * * Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in 14 | * the documentation and/or other materials provided with the 15 | * distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 20 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 21 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 22 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 | * OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package org.ietf.jgss; 31 | 32 | import edu.mit.jgss.swig.gss_name_t_desc; 33 | 34 | /** 35 | * Encapsulates a single GSS-API princiapl entity. This interface is defined 36 | * in section 7.2 of RFC 5653 (http://tools.ietf.org/html/rfc5653). 37 | */ 38 | public interface GSSName { 39 | 40 | /** 41 | * Oid indicating a host-based service name form. It is used to represent 42 | * services associated with host computers. This name form is constructed 43 | * using two elements, "service" and "hostname", i.e. "service@hostname". 44 | * 45 | * It represents the following value: { iso{1) member-body(2) United 46 | * States(840) mit(113554) infosys(1) gssapi(2) generic(1) 47 | * service_name(4) } 48 | * 49 | * Native GSS-API equivalent = GSS_C_NT_HOSTBASED_SERVICE 50 | */ 51 | public static final Oid NT_HOSTBASED_SERVICE 52 | = Oid.getNewOid("1.2.840.113554.1.2.1.4"); 53 | 54 | /** 55 | * Name type to indicate a named user on a local system. 56 | * 57 | * It represents the following value: { iso(1) member-body(2) 58 | * United States(840) mit(113554) infosys(1) gssapi(2) generic(1) 59 | * user_name(1) } 60 | * 61 | * Native GSS-API equivalent = GSS_C_NT_USER_NAME 62 | */ 63 | public static final Oid NT_USER_NAME 64 | = Oid.getNewOid("1.2.840.113554.1.2.1.1"); 65 | 66 | /** 67 | * Name type to indicate a numeric user identifier corresponding to a 68 | * user on a local system (e.g., Uid). 69 | * 70 | * It represents the following value: { iso(1) member-body(2) 71 | * United States(840) mit(113554) infosys(1) gssapi(2) generic(1) 72 | * machine_uid_name(2) } 73 | * 74 | * Native GSS-API equivalent = GSS_C_NT_MACHINE_UID_NAME 75 | */ 76 | public static final Oid NT_MACHINE_UID_NAME 77 | = Oid.getNewOid("1.2.840.113554.1.2.1.2"); 78 | 79 | /** 80 | * Name type to indicate a string of digits representing the numeric 81 | * user identifier of a user on a local system. 82 | * 83 | * It represents the following value: { iso(1) member-body(2) United 84 | * States(840) mit(113554) infosys(1) gssapi(2) generic(1) 85 | * string_uid_name(3) } 86 | * 87 | * Native GSS-API equivalent = GSS_C_NT_STRING_UID_NAME 88 | */ 89 | public static final Oid NT_STRING_UID_NAME 90 | = Oid.getNewOid("1.2.840.113554.1.2.1.3"); 91 | 92 | /** 93 | * Name type for representing an anonymous entity. 94 | * 95 | * It represents the following value: { iso(1), org(3), dod(6), 96 | * internet(1), security(5), nametypes(6), gss-anonymous-name(3) } 97 | * 98 | * Native GSS-API equivalent = GSS_C_NT_ANONYMOUS 99 | */ 100 | public static final Oid NT_ANONYMOUS 101 | = Oid.getNewOid("1.3.6.1.5.6.3"); 102 | 103 | /** 104 | * Name type used to indicate an exported name produced by the export 105 | * method. 106 | * 107 | * It represents the following value: { iso(1), org(3), dod(6), 108 | * internet(1), security(5), nametypes(6), gss-api-exported-name(4) } 109 | * 110 | * Native GSS-API equivalent = GSS_C_NT_EXPORT_NAME; 111 | */ 112 | public static final Oid NT_EXPORT_NAME 113 | = Oid.getNewOid("1.3.6.1.5.6.4"); 114 | 115 | /** 116 | * Compares two GSSName objects to determine if they refer to the same 117 | * entity. If the names cannot be compared, a GSSException may 118 | * be thrown. 119 | * 120 | * @param another GSSName object with which to compare 121 | * @return "true" if the two objects are equal, "false" if the are 122 | * not equal or if either of the names represents an anonymous 123 | * entity. 124 | */ 125 | public boolean equals(GSSName another) throws GSSException; 126 | 127 | /** 128 | * Compares the two GSSName objects to determine if they refer to the 129 | * same entity. If an error occurs, "false" will be returned. Note that 130 | * two GSSName objects are equal if the result of calling hashCode() 131 | * on each is equal. 132 | * 133 | * @param another GSSName object with which to compare 134 | * @return "true" if the two objects are equal, "false" if they are 135 | * not, if an error occurs, or if either of the names represents an 136 | * anonymous entity. 137 | */ 138 | public boolean equals(Object another); 139 | 140 | /** 141 | * Creates a mechanism name (MN) from an arbitrary internal name. 142 | * 143 | * @param mech Oid for the mechanism for which the canonical form of 144 | * the name is requested. 145 | * @return the canonical form of the given Oid 146 | */ 147 | public GSSName canonicalize(Oid mech) throws GSSException; 148 | 149 | /** 150 | * Returns a canonical contiguous byte representation of a mechanism 151 | * name (MN), suitable for direct, byte-by-byte comparison by 152 | * authorization functions. If the name is not a MN, a GSSException 153 | * may be thrown. 154 | * 155 | * @return canonical contiguous byte representation of the mechanism 156 | * name. 157 | */ 158 | public byte[] export() throws GSSException; 159 | 160 | /** 161 | * Returns a textual representation of the GSSName object. 162 | * 163 | * @return textual representation of the GSSName object. 164 | */ 165 | public String toString(); 166 | 167 | /** 168 | * Returns the Oid representing the type of name returned through the 169 | * toString method. 170 | * 171 | * @return Oid representing the type of name returned through the toString 172 | * method. 173 | */ 174 | public Oid getStringNameType() throws GSSException; 175 | 176 | /** 177 | * Tests if the GSSName object represents an anonymous entity. 178 | * 179 | * @return "true" if the GSSName object is an anonymous name, "false" 180 | * otherwise. 181 | */ 182 | public boolean isAnonymous(); 183 | 184 | /** 185 | * Tests if the GSSName object contains only one mechanism element and 186 | * is thus a mechanism name. 187 | * 188 | * @return "true" if the GSSName object is a mechanism name, "false" 189 | * otherwise. 190 | */ 191 | public boolean isMN(); 192 | 193 | /** 194 | * Returns the internal SWIG-generated object of type 195 | * gss_name_t_desc. Used in functions from GSSNameImpl.java 196 | * 197 | * 198 | * @return internal gss_name_t_desc object 199 | */ 200 | public gss_name_t_desc getInternGSSName(); 201 | 202 | /** 203 | * Sets the internal SWIG-generated object of type 204 | * gss_name_t_desc. Used in functions from GSSNameImpl.java 205 | * 206 | * @return 0 on success, -1 on failure 207 | * 208 | */ 209 | public int setInternGSSName(gss_name_t_desc newName); 210 | 211 | } 212 | -------------------------------------------------------------------------------- /src/java/org/ietf/jgss/MessageProp.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 by the Massachusetts Institute of Technology. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 12 | * * Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in 14 | * the documentation and/or other materials provided with the 15 | * distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 20 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 21 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 22 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 | * OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package org.ietf.jgss; 31 | 32 | /** 33 | * This is a utility class used within the per-message GSSContext 34 | * methods to convey per-message properties. 35 | */ 36 | public class MessageProp { 37 | 38 | private int qop; 39 | private boolean privState; 40 | private int minorStatus; 41 | private String minorString; 42 | private boolean duplicate; 43 | private boolean old; 44 | private boolean unseq; 45 | private boolean gap; 46 | 47 | /** 48 | * Creates a MessageProp object with the desired privacy state. QOP value 49 | * is set to 0, indicating that the default QOP is requested. 50 | * 51 | * @param privState the desired privacy state. "true" for privacy and 52 | * "false for integrity only. 53 | */ 54 | public MessageProp(boolean privState) { 55 | 56 | this.qop = 0; 57 | this.privState = privState; 58 | } 59 | 60 | /** 61 | * Creates a MessageProp object with the desired QOP and privacy state. 62 | * 63 | * @param qop the desired QOP. Use 0 to request a default QOP. 64 | * @param privState the desired privacy state. "true" for privacy and 65 | * "false" for integrity only. 66 | */ 67 | public MessageProp(int qop, boolean privState) { 68 | 69 | this.qop = qop; 70 | this.privState = privState; 71 | } 72 | 73 | /** 74 | * Returns the QOP value. 75 | * 76 | * @return current QOP value. 77 | */ 78 | public int getQOP() { 79 | 80 | return this.qop; 81 | } 82 | 83 | /** 84 | * Returns the privacy state. 85 | * 86 | * @return current privacy state. "true" indicates privacy, "false" 87 | * indicates integrity only. 88 | */ 89 | public boolean getPrivacy() { 90 | 91 | return this.privState; 92 | } 93 | 94 | /** 95 | * Returns the minor status that the underlying mechanism might have set. 96 | * 97 | * @return minor status set by underlying mechanism. 98 | */ 99 | public int getMinorStatus() { 100 | 101 | return this.minorStatus; 102 | } 103 | 104 | /** 105 | * Returns the string explanation of the minor code set by the 106 | * underlying mechanism. 107 | * 108 | * @return string explanation of minor code. "null" is returned when 109 | * no mechanism error code has been set. 110 | */ 111 | public String getMinorString() { 112 | 113 | return this.minorString; 114 | } 115 | 116 | /** 117 | * Sets the QOP value. 118 | * 119 | * @param qopValue QOP value to be set. Use 0 to request a default QOP 120 | * value. 121 | */ 122 | public void setQOP(int qopValue) { 123 | 124 | this.qop = qopValue; 125 | } 126 | 127 | /** 128 | * Sets the privacy state. 129 | * 130 | * @param privState the privacy state. Use "true" for privacy, "false" for 131 | * integrity only. 132 | */ 133 | public void setPrivacy(boolean privState) { 134 | 135 | this.privState = privState; 136 | } 137 | 138 | /** 139 | * Returns "true" if this is a duplicate of an earlier token. 140 | * 141 | * @return "true" if token is a duplicate, "false" otherwise. 142 | */ 143 | public boolean isDuplicateToken() { 144 | 145 | return this.duplicate; 146 | } 147 | 148 | /** 149 | * Returns "true" if the token's validity period has expired. 150 | * 151 | * @return "true" if the token has expired, "false" otherwise. 152 | */ 153 | public boolean isOldToken() { 154 | 155 | return this.old; 156 | } 157 | 158 | /** 159 | * Returns "true" if a later token has already been processed. 160 | * 161 | * @return "true" if a later token has been processed. 162 | */ 163 | public boolean isUnseqToken() { 164 | 165 | return this.unseq; 166 | } 167 | 168 | /** 169 | * Returns "true" if an expected per-message token was not received. 170 | * 171 | * @return "true" if expected per-message token was not received. 172 | */ 173 | public boolean isGapToken() { 174 | 175 | return this.gap; 176 | } 177 | 178 | /** 179 | * Sets the supplementary information flags and the minor status. 180 | * 181 | * @param duplicate "true" if token was a duplicate of an earlier token; 182 | * otherwise, "false" 183 | * @param old "true" if the token's validity period has expired; 184 | * otherwise, "false" 185 | * @param unseq "true" if a later token has already been processed; 186 | * otherwise, "false" 187 | * @param gap "true" if one or more predecessor tokens have not yet been 188 | * successfully processed; otherwise, "false". 189 | * @param minorStatus the integer minor status code set by the underlying 190 | * mechanism. 191 | * @param minorString textual representation of the minor status value. 192 | */ 193 | public void setSupplementaryStates(boolean duplicate, boolean old, 194 | boolean unseq, boolean gap, 195 | int minorStatus, String minorString) { 196 | this.duplicate = duplicate; 197 | this.old = old; 198 | this.unseq = unseq; 199 | this.gap = gap; 200 | this.minorStatus = minorStatus; 201 | this.minorString = minorString; 202 | } 203 | } 204 | -------------------------------------------------------------------------------- /src/java/org/ietf/jgss/Oid.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 by the Massachusetts Institute of Technology. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 12 | * * Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in 14 | * the documentation and/or other materials provided with the 15 | * distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 20 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 21 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 22 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 28 | * OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | package org.ietf.jgss; 31 | 32 | import java.util.Arrays; 33 | import java.io.*; 34 | 35 | import edu.mit.jgss.OidUtil; 36 | import edu.mit.jgss.GSSExceptionImpl; 37 | import edu.mit.jgss.swig.*; 38 | 39 | public class Oid { 40 | 41 | protected gss_OID_desc oid = null; 42 | protected byte[] derOid; 43 | 44 | /** 45 | * Creates a new Oid object from a string representation of the Oid's 46 | * integer components (e.g., "1.2.840.113554.1.2.2"). 47 | * 48 | * @param strOid the string representation of the Oid, separated by dots. 49 | */ 50 | public Oid(String strOid) throws GSSException { 51 | 52 | boolean matches = OidUtil.verifyOid(strOid); 53 | 54 | if (matches) { 55 | this.oid = new gss_OID_desc(strOid); 56 | } else { 57 | System.out.println("failed to verify OID string"); 58 | freeStructs(); 59 | throw new GSSException(GSSException.FAILURE); 60 | } 61 | } 62 | 63 | /** 64 | * Creates a new Oid object from its DER encoding. The DER encoding 65 | * refers to the full encoding, including the tag and length. 66 | * Structure and encoding of Oids is defined in ISOIEC-8824 and 67 | * ISOIEC-8825. 68 | * 69 | * @param derOid the stream containing the DER-encoded Oid. 70 | */ 71 | public Oid(InputStream derOid) throws GSSException { 72 | 73 | if (derOid == null) { 74 | freeStructs(); 75 | throw new NullPointerException(); 76 | } 77 | 78 | try { 79 | byte[] tmpOid = OidUtil.OidStream2DER(derOid); 80 | boolean valid = OidUtil.verifyOid(tmpOid); 81 | 82 | if (!valid) { 83 | freeStructs(); 84 | throw new GSSException(GSSException.FAILURE); 85 | } 86 | 87 | /* Remove tag and length from byte array */ 88 | byte[] shortDerOid = new byte[tmpOid.length - 2]; 89 | for (int i = 0; i < tmpOid.length-2; i++) { 90 | shortDerOid[i] = tmpOid[i+2]; 91 | } 92 | this.oid = new gss_OID_desc(shortDerOid); 93 | 94 | /* store der-encoded Oid in object for future use */ 95 | this.derOid = new byte[tmpOid.length]; 96 | System.arraycopy(tmpOid, 0, this.derOid, 0, tmpOid.length); 97 | 98 | } catch (IOException e) { 99 | freeStructs(); 100 | throw new GSSException(GSSException.FAILURE); 101 | } 102 | } 103 | 104 | /** 105 | * Creates a new Oid object from its DER encoding. The DER encoding 106 | * refers to the full encoding, including the tag and length. 107 | * Structure and encoding of Oids is defined in ISOIEC-8824 and 108 | * ISOIEC_8825. 109 | * 110 | * @param derOid the byte array containing the DER-encoded Oid. 111 | */ 112 | public Oid(byte[] derOid) throws GSSException { 113 | 114 | if (derOid == null) { 115 | freeStructs(); 116 | throw new NullPointerException(); 117 | } 118 | 119 | boolean valid = OidUtil.verifyOid(derOid); 120 | if (!valid) { 121 | freeStructs(); 122 | throw new GSSException(GSSException.FAILURE); 123 | } 124 | 125 | /* Remove tag and length from byte array */ 126 | byte[] shortDerOid = new byte[derOid.length - 2]; 127 | for (int i = 0; i < derOid.length-2; i++) { 128 | shortDerOid[i] = derOid[i+2]; 129 | } 130 | this.oid = new gss_OID_desc(shortDerOid); 131 | 132 | /* store der-encoded Oid in object for future use */ 133 | this.derOid = new byte[derOid.length]; 134 | System.arraycopy(derOid, 0, this.derOid, 0, derOid.length); 135 | } 136 | 137 | /** 138 | * Returns a string representation of the Oid's integer components in 139 | * the dot separated notation. 140 | * 141 | * @return string representation of the Oid's integer components in dot 142 | * notation. 143 | */ 144 | public String toString() { 145 | if (oid != null) { 146 | //return (this.oid).toString(); 147 | 148 | /* Get native OID string, { X X ... X } representation */ 149 | String tmpString = (this.oid).toString(); 150 | String[] stringArray = tmpString.split(" "); 151 | 152 | /* Convert to dot-separated representation */ 153 | StringBuilder oidString = new StringBuilder(); 154 | for (int i = 0; i < stringArray.length; i++) { 155 | if (stringArray[i].matches("\\d*")) { 156 | oidString.append(stringArray[i]); 157 | if ((stringArray.length - i) > 2) { 158 | oidString.append("."); 159 | } 160 | } 161 | } 162 | return oidString.toString(); 163 | 164 | } else { 165 | return null; 166 | } 167 | } 168 | 169 | /** 170 | * Compares two Oid objects, returning "true" if the two represent 171 | * the same Oid value. Two Oid objects are equal when the 172 | * integer result from hashCode() method called on them is the same. 173 | * 174 | * @param obj the Oid object with which to compare. 175 | * @return "true" if the two objects are equal, "false" otherwise. 176 | */ 177 | public boolean equals(Object obj) { 178 | 179 | if (! (obj instanceof Oid)) 180 | return false; 181 | 182 | Oid tmp = (Oid) obj; 183 | 184 | if (tmp == null) { 185 | throw new NullPointerException("Input Obj is null"); 186 | } 187 | 188 | if (Arrays.equals(this.getDER(), tmp.getDER())) 189 | return true; 190 | else 191 | return false; 192 | } 193 | 194 | /** 195 | * Returns the full ASN.1 DER encoding for the Oid object. This encoding 196 | * includes the tag and length. 197 | * 198 | * @return full ASN.1 DER encoding for the Oid object. 199 | */ 200 | public byte[] getDER() { 201 | 202 | if (derOid == null) { 203 | byte[] tmpDerOid = OidUtil.OidString2DER(this.toString()); 204 | return tmpDerOid; 205 | //System.arraycopy(tmpDerOid, 0, this.derOid, 0, tmpDerOid.length); 206 | //this.derOid = OidUtil.OidString2DER(this.toString()); 207 | } 208 | 209 | return this.derOid; 210 | } 211 | 212 | /** 213 | * Tests if an Oid object is contained in the given Oid object array. 214 | * 215 | * @param oids the array of Oid objects to test against. 216 | * @return "true" if the Oid object is contained in the array, 217 | * "false" otherwise. 218 | */ 219 | public boolean containedIn(Oid[] oids) { 220 | 221 | if (oids == null) 222 | throw new NullPointerException("Input Oid[] is null"); 223 | 224 | for (int i = 0; i < oids.length; i++) 225 | { 226 | if (oid.equals(oids[i].oid)) 227 | return true; 228 | } 229 | return false; 230 | } 231 | 232 | /** 233 | * package-scope method used in GSSName.java to create a new Oid 234 | * object. 235 | * 236 | * @param strOid Oid in dot-separated String representation 237 | * @return new Oid object matching input string 238 | */ 239 | static Oid getNewOid(String strOid) { 240 | 241 | Oid retOid = null; 242 | 243 | try { 244 | retOid = new Oid(strOid); 245 | } catch (GSSException e) { 246 | e.printStackTrace(); 247 | } 248 | 249 | return retOid; 250 | } 251 | 252 | private void freeStructs() throws GSSException { 253 | 254 | if (oid != null) { 255 | long maj_status = 0; 256 | long[] min_status = {0}; 257 | 258 | maj_status = gsswrapper.gss_release_oid(min_status, oid); 259 | if (maj_status != gsswrapper.GSS_S_COMPLETE) { 260 | throw new GSSExceptionImpl((int)maj_status, (int)min_status[0]); 261 | } 262 | } 263 | } 264 | 265 | public gss_OID_desc getNativeOid() { 266 | return this.oid; 267 | } 268 | 269 | public void setNativeOid(gss_OID_desc newOid) { 270 | if (newOid != null) { 271 | this.oid = newOid; 272 | this.derOid = null; 273 | } 274 | } 275 | } 276 | -------------------------------------------------------------------------------- /src/test/junit-4.10.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cconlon/kerberos-java-gssapi/1a70d4c68d2b59a3b61a70fb299753d4fbacc0cf/src/test/junit-4.10.jar -------------------------------------------------------------------------------- /src/test/org/ietf/jgss/ChannelBindingTest.java: -------------------------------------------------------------------------------- 1 | package org.ietf.jgss; 2 | 3 | import org.junit.Test; 4 | import junit.framework.TestCase; 5 | import static org.junit.Assert.assertEquals; 6 | 7 | import java.net.InetAddress; 8 | import java.util.Arrays; 9 | 10 | import org.ietf.jgss.ChannelBinding; 11 | 12 | public class ChannelBindingTest extends TestCase { 13 | 14 | public void testChannelBindingCreation() { 15 | 16 | byte[] appData = {55, 54, 33}; 17 | 18 | try { 19 | 20 | InetAddress initAddr = InetAddress.getByName("127.0.0.1"); 21 | InetAddress acceptAddr = InetAddress.getByName("127.0.0.1"); 22 | 23 | ChannelBinding cb = new ChannelBinding(initAddr, acceptAddr, 24 | appData); 25 | ChannelBinding cb2 = new ChannelBinding(initAddr, acceptAddr, 26 | appData); 27 | ChannelBinding cb3 = new ChannelBinding(appData); 28 | 29 | if (!cb.getInitiatorAddress().getHostAddress().equals("127.0.0.1")) 30 | fail("Failed to set initiator InetAddress correctly"); 31 | 32 | if (!cb.getAcceptorAddress().getHostAddress().equals("127.0.0.1")) 33 | fail("Failed to set acceptor InetAddress correctly"); 34 | System.out.format("%-40s %10s%n", "... testing setting InetAddress", 35 | "... passed"); 36 | 37 | if (!Arrays.equals(cb.getApplicationData(), appData)) 38 | fail("Failed to set application data correctly"); 39 | System.out.format("%-40s %10s%n", "... testing setting app data", 40 | "... passed"); 41 | 42 | if (!cb.equals(cb2)) 43 | fail("ChannelBinding equals method failed"); 44 | System.out.format("%-40s %10s%n", "... testing equals()", 45 | "... passed"); 46 | 47 | } catch (Exception e) { 48 | e.printStackTrace(); 49 | } 50 | } 51 | } 52 | 53 | -------------------------------------------------------------------------------- /src/test/org/ietf/jgss/GSSNameTest.java: -------------------------------------------------------------------------------- 1 | package org.ietf.jgss; 2 | 3 | import org.junit.Test; 4 | import junit.framework.TestCase; 5 | import static org.junit.Assert.assertEquals; 6 | 7 | import java.io.*; 8 | import java.util.Arrays; 9 | import org.ietf.jgss.GSSName; 10 | import org.ietf.jgss.GSSException; 11 | 12 | public class GSSNameTest extends TestCase { 13 | 14 | /** 15 | * Tests the creaton of new GSSName objects. There are 4 different 16 | * createName methods inside of GSSManager: 17 | * 18 | * 1) createName(String, Oid) 19 | * 2) createName(byte[], Oid) 20 | * 3) createName(String, Oid, Oid) 21 | * 4) createName(byte[], Oid, Oid) 22 | * 23 | */ 24 | public void testCreateGSSName() throws GSSException { 25 | 26 | GSSManager testManager = GSSManager.getInstance(); 27 | 28 | byte[] exportName_actual = {(byte)0x04, (byte)0x01, (byte)0x00, 29 | (byte)0x0B, (byte)0x06, (byte)0x09, 30 | (byte)0x2A, (byte)0x86, (byte)0x48, 31 | (byte)0x86, (byte)0xF7, (byte)0x12, 32 | (byte)0x01, (byte)0x02, (byte)0x02, 33 | (byte)0x00, (byte)0x00, (byte)0x00, 34 | (byte)0x0C, (byte)0x73, (byte)0x65, 35 | (byte)0x72, (byte)0x76, (byte)0x69, 36 | (byte)0x63, (byte)0x65, (byte)0x40, 37 | (byte)0x68, (byte)0x6F, (byte)0x73, 38 | (byte)0x74}; 39 | 40 | /* create NT_USER_NAME */ 41 | try { 42 | GSSName testName = testManager.createName("testuser", 43 | GSSName.NT_USER_NAME); 44 | } catch (GSSException e) { 45 | fail("Failed to create new GSSName (testuser, NT_USER_NAME)"); 46 | } 47 | 48 | /* create NT_HOSTBASED_SERVICE */ 49 | try { 50 | GSSName testName2 = testManager.createName("service@hostname", 51 | GSSName.NT_HOSTBASED_SERVICE); 52 | } catch (GSSException e) { 53 | fail("Failed to create new GSSName (service@hostname, " + 54 | "NT_HOSTBASED_SERVICE)"); 55 | } 56 | 57 | /* create NT_MACHINE_UID_NAME */ 58 | try { 59 | GSSName testName3 = testManager.createName("test@test", 60 | GSSName.NT_MACHINE_UID_NAME); 61 | } catch (GSSException e) { 62 | fail("Failed to create new GSSName (test@test, " + 63 | "NT_MACHINE_UID_NAME)"); 64 | } 65 | 66 | /* create NT_STRING_UID_NAME */ 67 | try { 68 | GSSName testName4 = testManager.createName("test@test", 69 | GSSName.NT_STRING_UID_NAME); 70 | } catch (GSSException e) { 71 | fail("Failed to create new GSSName (test@test, " + 72 | "NT_STRING_UID_NAME)"); 73 | } 74 | 75 | /* create NT_ANONYMOUS */ 76 | try { 77 | GSSName testName5 = testManager.createName("test@test", 78 | GSSName.NT_ANONYMOUS); 79 | } catch (GSSException e) { 80 | fail("Failed to create new GSSName (test@test, " + 81 | "NT_ANONYMOUS)"); 82 | } 83 | 84 | /* createName(String, GSSName, Oid) */ 85 | Oid krb5Mech = new Oid("1.2.840.113554.1.2.2"); 86 | try { 87 | GSSName testName6 = testManager.createName("foo", 88 | GSSName.NT_USER_NAME, krb5Mech); 89 | } catch (GSSException e) { 90 | fail("Failed in GSSName.createName(String, GSSName, Oid)"); 91 | } 92 | 93 | /* createName(byte[], GSSName) */ 94 | try { 95 | GSSName testName7 = testManager.createName(exportName_actual, 96 | GSSName.NT_EXPORT_NAME); 97 | } catch (GSSException e) { 98 | fail("Failed in GSSName.createName(byte[], GSSName)"); 99 | } 100 | 101 | /* createName(byte[], GSSName, Oid) */ 102 | try { 103 | GSSName testName8 = testManager.createName(exportName_actual, 104 | GSSName.NT_EXPORT_NAME, krb5Mech); 105 | } catch (GSSException e) { 106 | fail("Failed in GSSName.createName(byte[], GSSName)"); 107 | } 108 | 109 | } 110 | 111 | /** 112 | * Tests methods inside GSSName class. Currently tests: 113 | * 1) equals(GSSName) 114 | * 2) equals(Object) 115 | * 3) canonicalize(Oid) 116 | * 4) export() 117 | * 5) toString() 118 | * 6) getStringNameType() 119 | * 7) isAnonymous() 120 | * 8) isMN() 121 | * 122 | */ 123 | public void testGSSNameMethods() throws GSSException { 124 | 125 | GSSManager testManager = GSSManager.getInstance(); 126 | 127 | try { 128 | 129 | /* (1) ----- testing GSSName.equals(GSSName) ----- */ 130 | GSSName testName1 = testManager.createName("testUser", 131 | GSSName.NT_USER_NAME); 132 | GSSName testName2 = testManager.createName("testUser", 133 | GSSName.NT_USER_NAME); 134 | GSSName testName3 = testManager.createName("testUser3", 135 | GSSName.NT_USER_NAME); 136 | 137 | if(!testName1.equals(testName2)) 138 | fail("GSSName.equals(GSSName) failed"); 139 | 140 | if(testName1.equals(testName3)) 141 | fail("GSSName.equals(GSSName) failed"); 142 | 143 | System.out.format("%-40s %10s%n", "... testing equals(GSSName)", 144 | "... passed"); 145 | 146 | 147 | /* (2) ----- testing GSSName.equals(Object) ----- */ 148 | 149 | if(!testName1.equals((Object)testName2)) 150 | fail("GSSName.equals(GSSName) failed"); 151 | 152 | if(testName1.equals((Object)testName3)) 153 | fail("GSSName.equals(GSSName) failed"); 154 | 155 | System.out.format("%-40s %10s%n", "... testing equals(Object)", 156 | "... passed"); 157 | 158 | 159 | /* (3) ----- testing GSSName.canonicalize ----- */ 160 | GSSName name = testManager.createName("service@host", 161 | GSSName.NT_USER_NAME); 162 | 163 | Oid krb5 = new Oid("1.2.840.113554.1.2.2"); 164 | 165 | GSSName mechName = name.canonicalize(krb5); 166 | 167 | /* above 2 steps are equal to the following */ 168 | /* GSSName mechName = testManager.createName("service@host", 169 | GSSName.NT_HOSTBASED_SERVICE, krb5); */ 170 | 171 | if (!name.equals(mechName)) 172 | fail("GSSName.equals on canonicalized name failed"); 173 | 174 | System.out.format("%-40s %10s%n", "... testing canonicalize()", 175 | "... passed"); 176 | 177 | 178 | /* (4) ----- testing GSSName.export ----- */ 179 | byte[] exportName_actual = {(byte)0x04, (byte)0x01, (byte)0x00, 180 | (byte)0x0B, (byte)0x06, (byte)0x09, 181 | (byte)0x2A, (byte)0x86, (byte)0x48, 182 | (byte)0x86, (byte)0xF7, (byte)0x12, 183 | (byte)0x01, (byte)0x02, (byte)0x02, 184 | (byte)0x00, (byte)0x00, (byte)0x00, 185 | (byte)0x0C, (byte)0x73, (byte)0x65, 186 | (byte)0x72, (byte)0x76, (byte)0x69, 187 | (byte)0x63, (byte)0x65, (byte)0x40, 188 | (byte)0x68, (byte)0x6F, (byte)0x73, 189 | (byte)0x74}; 190 | 191 | byte[] exportName = mechName.export(); 192 | 193 | if (!Arrays.equals(exportName, exportName_actual)) 194 | fail("GSSName.export failed"); 195 | 196 | System.out.format("%-40s %10s%n", "... testing export()", 197 | "... passed"); 198 | 199 | 200 | /* (5) ----- testing GSSName.toString ----- */ 201 | if(!name.toString().equals("service@host")) 202 | fail("GSSName.toString failed"); 203 | 204 | System.out.format("%-40s %10s%n", "... testing toString()", 205 | "... passed"); 206 | 207 | 208 | /* (6) ----- testing GSSName.getStringNameType ----- */ 209 | Oid nameType = name.getStringNameType(); 210 | if (!nameType.equals(GSSName.NT_USER_NAME)) 211 | fail("GSSName.getStringNameType failed"); 212 | 213 | System.out.format("%-40s %10s%n", 214 | "... testing getStringNameType()", 215 | "... passed"); 216 | 217 | 218 | /* (7) ----- testing GSSName.isAnonymous ----- */ 219 | GSSName nameAnon = testManager.createName("service@host", 220 | GSSName.NT_ANONYMOUS); 221 | if(!nameAnon.isAnonymous()) 222 | fail("GSSName.isAnonymous failed"); 223 | if(name.isAnonymous()) 224 | fail("GSSName.isAnonymous failed"); 225 | 226 | System.out.format("%-40s %10s%n", "... testing isAnonymous()", 227 | "... passed"); 228 | 229 | 230 | /* (8) ----- testing GSSName.isMN ----- */ 231 | if(!mechName.isMN()) { 232 | fail("GSSName.isMN failed"); 233 | } 234 | if(name.isMN()) { 235 | fail("GSSName.isMN failed"); 236 | } 237 | System.out.format("%-40s %10s%n", "... testing isMN()", 238 | "... passed"); 239 | 240 | } catch (GSSException e) { 241 | System.out.println(e.toString()); 242 | fail("Failed during testGSSNameMethods"); 243 | } 244 | } 245 | } 246 | 247 | -------------------------------------------------------------------------------- /src/test/org/ietf/jgss/JUnit4Suite.java: -------------------------------------------------------------------------------- 1 | package org.ietf.jgss; 2 | 3 | import org.junit.runner.RunWith; 4 | import org.junit.runners.Suite; 5 | import org.junit.runners.Suite.SuiteClasses; 6 | 7 | import org.ietf.jgss.OidTest; 8 | 9 | @RunWith(Suite.class) 10 | @SuiteClasses({OidTest.class, 11 | MessagePropTest.class, 12 | ChannelBindingTest.class, 13 | GSSNameTest.class}) 14 | public class JUnit4Suite { } 15 | 16 | -------------------------------------------------------------------------------- /src/test/org/ietf/jgss/MessagePropTest.java: -------------------------------------------------------------------------------- 1 | package org.ietf.jgss; 2 | 3 | import org.junit.Test; 4 | import junit.framework.TestCase; 5 | 6 | import org.ietf.jgss.MessageProp; 7 | 8 | public class MessagePropTest extends TestCase { 9 | 10 | public void testMessagePropCreation() { 11 | 12 | MessageProp msgp = new MessageProp(true); 13 | MessageProp msgp2 = new MessageProp(0, true); 14 | 15 | msgp2.setQOP(1); 16 | msgp2.setPrivacy(false); 17 | msgp2.setSupplementaryStates(false, false, false, false, 18 | 0, "no status"); 19 | 20 | if (msgp2.getQOP() != 1) 21 | fail("Failed to get QOP from MessageProp"); 22 | System.out.format("%-40s %10s%n", "... testing getQOP()", 23 | "... passed"); 24 | 25 | if (msgp2.getPrivacy() != false) 26 | fail("Failed to get Privacy from MessageProp"); 27 | System.out.format("%-40s %10s%n", "... testing getPrivacy()", 28 | "... passed"); 29 | 30 | if (msgp2.getMinorStatus() != 0) 31 | fail("Failed to get minor status from MessageProp"); 32 | System.out.format("%-40s %10s%n", "... testing getMinorStatus()", 33 | "... passed"); 34 | 35 | if (!msgp2.getMinorString().equals("no status")) 36 | fail("Failed to get minor status string from MessageProp"); 37 | System.out.format("%-40s %10s%n", "... testing getMinorString()", 38 | "... passed"); 39 | 40 | if (msgp2.isDuplicateToken()) 41 | fail("Incorrect duplicate flag set"); 42 | System.out.format("%-40s %10s%n", "... testing isDuplicateToken()", 43 | "... passed"); 44 | 45 | if (msgp2.isOldToken()) 46 | fail("Incorrect old token flag set"); 47 | System.out.format("%-40s %10s%n", "... testing isOldToken()", 48 | "... passed"); 49 | 50 | if (msgp2.isUnseqToken()) 51 | fail("Incorrect unseq token set"); 52 | System.out.format("%-40s %10s%n", "... testing isUnseqToken()", 53 | "... passed"); 54 | 55 | if (msgp2.isGapToken()) 56 | fail("Incorrect gap token set"); 57 | System.out.format("%-40s %10s%n", "... testing isGapToken()", 58 | "... passed"); 59 | } 60 | 61 | } 62 | 63 | -------------------------------------------------------------------------------- /src/test/org/ietf/jgss/OidTest.java: -------------------------------------------------------------------------------- 1 | package org.ietf.jgss; 2 | 3 | import org.junit.Test; 4 | import junit.framework.TestCase; 5 | import static org.junit.Assert.assertEquals; 6 | 7 | import java.io.*; 8 | import java.util.Arrays; 9 | import org.ietf.jgss.Oid; 10 | import org.ietf.jgss.GSSException; 11 | 12 | public class OidTest extends TestCase { 13 | 14 | public void testOidStringConstructor() throws GSSException { 15 | try { 16 | Oid testOid = new Oid("asdfasdf"); 17 | fail("No exception was thrown"); 18 | } catch (GSSException e) { 19 | // We expect to fail, proceed 20 | } 21 | 22 | try { 23 | Oid testOid = new Oid("1.2.3.4"); 24 | } catch (GSSException e) { 25 | fail("new Oid(String) failed"); 26 | } 27 | } 28 | 29 | public void testOidMethods() throws GSSException { 30 | String oidString = "1.2.840.113554.1.2.2"; 31 | byte[] oidDER = {(byte)0x06, (byte)0x09, (byte)0x2A, (byte)0x86, 32 | (byte)0x48, (byte)0x86, (byte)0xF7, (byte)0x12, 33 | (byte)0x01, (byte)0x02, (byte)0x02}; 34 | 35 | /* incorrect DER-encoded Oid array, bad length value */ 36 | byte[] badOidDER = {(byte)0x06, (byte)0x0A, (byte)0x2A, (byte)0x86, 37 | (byte)0x48, (byte)0x86, (byte)0xF7, (byte)0x12, 38 | (byte)0x01, (byte)0x02, (byte)0x02}; 39 | try { 40 | 41 | /* testing Oid(DER) constructor and Oid.toString() method */ 42 | Oid testoid = new Oid("1.2.840.113554.1.2.2"); 43 | if (!oidString.equals(testoid.toString())) { 44 | fail("Oid.toString failed"); 45 | } 46 | 47 | Oid testoid2 = new Oid(oidDER); 48 | if (!oidString.equals(testoid2.toString())) { 49 | fail("Oid.toString failed using DER-encoded OID, " + 50 | testoid2.toString()); 51 | } 52 | System.out.format("%-40s %10s%n", "... testing toString()", 53 | "... passed"); 54 | 55 | /* testing Oid.getDER() method */ 56 | if (!Arrays.equals(testoid.getDER(), testoid2.getDER())) { 57 | fail("Oid.getDER failed during Oid comparison"); 58 | } 59 | System.out.format("%-40s %10s%n", "... testing getDER()", 60 | "... passed"); 61 | 62 | /* testing Oid.containedIn(Oid[]) method */ 63 | Oid[] oidArray = new Oid[2]; 64 | oidArray[0] = testoid; 65 | oidArray[1] = testoid2; 66 | 67 | if (!testoid.containedIn(oidArray)) { 68 | fail("Oid.containedIn failed"); 69 | } 70 | 71 | Oid testoid3 = new Oid("1.2.3.4"); 72 | if (testoid3.containedIn(oidArray)) { 73 | fail("Oid.containedIn failed"); 74 | } 75 | System.out.format("%-40s %10s%n", "... testing containedIn()", 76 | "... passed"); 77 | 78 | } catch (GSSException e) { 79 | throw e; 80 | } 81 | 82 | try { 83 | Oid testoid3 = new Oid(badOidDER); 84 | fail ("Oid(Oid DER array) validation failed."); 85 | 86 | } catch (GSSException e) { 87 | // We expect this to fail verification 88 | System.out.format("%-40s %10s%n", "... testing Oid DER validation", 89 | "... passed"); 90 | } 91 | } 92 | 93 | public void testOidStreamConstructor() { 94 | String oidString = "1.2.840.113554.1.2.2"; 95 | byte[] oidDER = {(byte)0x06, (byte)0x09, (byte)0x2A, (byte)0x86, 96 | (byte)0x48, (byte)0x86, (byte)0xF7, (byte)0x12, 97 | (byte)0x01, (byte)0x02, (byte)0x02}; 98 | try { 99 | ByteArrayInputStream oidStream = new ByteArrayInputStream(oidDER); 100 | Oid testOid = new Oid(oidStream); 101 | 102 | if (!oidString.equals(testOid.toString())) { 103 | fail("Oid.toString failed using Oid from InputStream"); 104 | } 105 | } catch (GSSException e) { 106 | fail("testOidStreamConstructor() failed"); 107 | } 108 | } 109 | 110 | public void testOidEquals() { 111 | String oidString = "1.2.840.113554.1.2.2"; 112 | 113 | try { 114 | Oid test1 = new Oid(oidString); 115 | Oid test2 = new Oid(oidString); 116 | 117 | if(!test1.equals(test2)) { 118 | fail("Oid equals method failed!"); 119 | } 120 | } catch (GSSException e) { 121 | fail("failed when testing Oid.equals() method"); 122 | } 123 | System.out.format("%-40s %10s%n", "... testing equals()", 124 | "... passed"); 125 | } 126 | 127 | } 128 | --------------------------------------------------------------------------------