gss-ntlmssp
gss-ntlmssp copied to clipboard
Using gss-ntlmssp from Java
I have a problem, maybe you can help me. I am using the gss-ntlmssp GSS plugin from Java on Linux by setting the system property "-Dsun.security.jgss.native=true".
I am testing HTTP proxy authorization with Negotiate (Kerberos), NTLM and Basic. I have set up a test system with multiple docker containers, one with a Samba DC, one with a Squid proxy and one development container with which I test the authorization.
The test setup seems to be ok, I can succesfully do:
[CORP\user1@develop1 proxytest]$ curl -v --proxy-negotiate -u: -x squidserver.corp.example.com:3128 https://<destination>
[CORP\user1@develop1 proxytest]$ curl -v --proxy-ntlm --proxy-user CORP\\user1 -u: -x squidserver.corp.example.com:3128 https://<destination>
Though I must admit challenge/response authorization with wbinfo is only successful if I run it as root, not as CORP\user1 (maybe that's the problem?):
[CORP\user1@develop1 proxytest]$ wbinfo -a CORP\\user1
Enter CORP\user1's password:
plaintext password authentication succeeded
Enter CORP\user1's password:
challenge/response password authentication failed
Could not authenticate user CORP\user1 with challenge/response
In my Java program I create a GSS context with the NTLMSSP Oid and create a token with:
Oid ntlmOid = new Oid("1.3.6.1.4.1.311.2.2.10");
Oid oid = ntlmOid;
String service = "[email protected]";
GSSName serverName = manager.createName(service, GSSName.NT_HOSTBASED_SERVICE);
GSSContext context = manager.createContext(serverName,
oid,
null,
GSSContext.DEFAULT_LIFETIME);
This is successful, and I can create a token which I send Base64 encoded to Squid:
byte[] token = new byte[0];
token = context.initSecContext(token, 0, token.length);
String encodedToken = Base64.getEncoder().encodeToString(token);
The Proxy-authenticate line I send to Squid looks like this:
Proxy-Authorization: NTLM TlRMTVNTUAABAAAAN4II4gAAAAAAAAAAAAAAAAAAAAAGAgAAAAAADw==
Then I get back the following token from Squid:
Proxy-Authenticate: NTLM TlRMTVNTUAACAAAACAAIADgAAAA1goniYTUVUwP3TmIAAAAAAAAAAJYAlgBAAAAABgEAAAAAAA9DAE8AUgBQAAIACABDAE8AUgBQAAEAFgBTAFEAVQBJAEQAUwBFAFIAVgBFAFIABAAgAGMAbwByAHAALgBlAHgAYQBtAHAAbABlAC4AYwBvAG0AAwA4AHMAcQB1AGkAZABzAGUAcgB2AGUAcgAuAGMAbwByAHAALgBlAHgAYQBtAHAAbABlAC4AYwBvAG0ABwAIAHAs/DxdjdkBAAAAAA==
But if I Base64 decode this token and feed it into the GSSContext I get an exception:
...
byte[] tokenBin = Base64.getDecoder().decode(token64);
byte[] token2 = context.initSecContext(tokenBin, 0, tokenBin.length);
Exception:
Exception in thread "main" GSSException: Defective token detected (Mechanism level: Failed to decode data)
at java.security.jgss/sun.security.jgss.wrapper.GSSLibStub.initContext(Native Method)
at java.security.jgss/sun.security.jgss.wrapper.NativeGSSContext.initSecContext(NativeGSSContext.java:277)
at java.security.jgss/sun.security.jgss.GSSContextImpl.initSecContext(GSSContextImpl.java:266)
at java.security.jgss/sun.security.jgss.GSSContextImpl.initSecContext(GSSContextImpl.java:196)
at proxytest.HttpClient.main(HttpClient.java:136)
The gss-ntlmssp Log looks like this:
[CORP\user1@develop1 proxytest]$ cat gssntlm.log
[1684837520] ALLOK: gssntlm_import_name_by_mech() @ src/gss_names.c:355 [0:0]
[1684837520] ALLOK: gssntlm_acquire_cred_from() @ src/gss_creds.c:501 [0:0]
[1684837520] ALLOK: gssntlm_import_name_by_mech() @ src/gss_names.c:355 [0:0]
[1684837520] ALLOK: gssntlm_init_sec_context() @ src/gss_sec_ctx.c:246 [1:0]
[1684837520] ALLOK: gssntlm_release_name() @ src/gss_names.c:633 [0:0]
[1684837520] ALLOK: gssntlm_release_name() @ src/gss_names.c:633 [0:0]
[1684837520] ALLOK: gssntlm_import_name_by_mech() @ src/gss_names.c:355 [0:0]
[1684837520] ALLOK: gssntlm_acquire_cred_from() @ src/gss_creds.c:501 [0:0]
[1684837520] ERROR: gssntlm_init_sec_context() @ src/gss_sec_ctx.c:293 [589824:1314127873]
[1684837520] ALLOK: gssntlm_delete_sec_context() @ src/gss_sec_ctx.c:483 [0:0]
[1684837520] ALLOK: gssntlm_release_name() @ src/gss_names.c:633 [0:0]
[1684837520] ALLOK: gssntlm_release_name() @ src/gss_names.c:633 [0:0]
[1684837520] ALLOK: gssntlm_display_status() @ src/gss_err.c:139 [0:0]
Any idea what I am doing wrong ? Isn't base64 decoding the token I get and feeding it into gss-ntlmssp enough, do I have to do something else ? Btw., if I use the Kerberos Oid, and do a Proxy-Authenticate: Negotiate instead of NTLM, my test program works, so I think principally the Java GSSAPI is working.