gss-ntlmssp icon indicating copy to clipboard operation
gss-ntlmssp copied to clipboard

Using gss-ntlmssp from Java

Open nir2 opened this issue 1 year ago • 3 comments

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.

nir2 avatar May 23 '23 10:05 nir2