Author: abartlet Date: 2006-07-24 05:02:38 +0000 (Mon, 24 Jul 2006) New Revision: 17216
WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=17216 Log: >From Kai Blin <[EMAIL PROTECTED]>: A patch to make ntlm_auth recognize three new commands in ntlmssp-client-1 and squid-2.5-ntlmssp: The commands are the following: Command: SF <hex number> Reply: OK Description: Takes feature request flags similar to samba4's gensec_want_feature() call. So far, only NTLMSSP_FEATURE_SESSION_KEY, NTLMSSP_FEATURE_SIGN and NTLMSSP_FEATURE_SEAL are implemented, using the same values as the corresponding GENSEC_FEATURE_* flags in samba4. Command: GF Reply: GF <hex number> Description: Returns the negotiated flags. Command: GK Reply: GK <base64 encoded session key> Description: Returns the negotiated session key. (These commands assist a wine project to use ntlm_auth for signing and sealing of bulk data). Andrew Bartlett Modified: branches/SAMBA_3_0/source/include/ntlmssp.h branches/SAMBA_3_0/source/libsmb/cliconnect.c branches/SAMBA_3_0/source/libsmb/ntlmssp.c branches/SAMBA_3_0/source/utils/ntlm_auth.c Changeset: Modified: branches/SAMBA_3_0/source/include/ntlmssp.h =================================================================== --- branches/SAMBA_3_0/source/include/ntlmssp.h 2006-07-24 00:45:21 UTC (rev 17215) +++ branches/SAMBA_3_0/source/include/ntlmssp.h 2006-07-24 05:02:38 UTC (rev 17216) @@ -65,6 +65,10 @@ #define NTLMSSP_NEGOTIATE_KEY_EXCH 0x40000000 #define NTLMSSP_NEGOTIATE_56 0x80000000 +#define NTLMSSP_FEATURE_SESSION_KEY 0x00000001 +#define NTLMSSP_FEATURE_SIGN 0x00000002 +#define NTLMSSP_FEATURE_SEAL 0x00000004 + #define NTLMSSP_NAME_TYPE_SERVER 0x01 #define NTLMSSP_NAME_TYPE_DOMAIN 0x02 #define NTLMSSP_NAME_TYPE_SERVER_DNS 0x03 Modified: branches/SAMBA_3_0/source/libsmb/cliconnect.c =================================================================== --- branches/SAMBA_3_0/source/libsmb/cliconnect.c 2006-07-24 00:45:21 UTC (rev 17215) +++ branches/SAMBA_3_0/source/libsmb/cliconnect.c 2006-07-24 05:02:38 UTC (rev 17216) @@ -599,6 +599,7 @@ if (!NT_STATUS_IS_OK(nt_status = ntlmssp_client_start(&ntlmssp_state))) { return nt_status; } + ntlmssp_want_feature(ntlmssp_state, NTLMSSP_FEATURE_SESSION_KEY); if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, user))) { return nt_status; Modified: branches/SAMBA_3_0/source/libsmb/ntlmssp.c =================================================================== --- branches/SAMBA_3_0/source/libsmb/ntlmssp.c 2006-07-24 00:45:21 UTC (rev 17215) +++ branches/SAMBA_3_0/source/libsmb/ntlmssp.c 2006-07-24 05:02:38 UTC (rev 17216) @@ -211,6 +211,50 @@ } /** + * Request features for the NTLMSSP negotiation + * + * @param ntlmssp_state NTLMSSP state + * @param feature_list List of space seperated features requested from NTLMSSP. + */ +void ntlmssp_want_feature_list(NTLMSSP_STATE *ntlmssp_state, char *feature_list) +{ + /* + * We need to set this to allow a later SetPassword + * via the SAMR pipe to succeed. Strange.... We could + * also add NTLMSSP_NEGOTIATE_SEAL here. JRA. + */ + if (in_list("NTLMSSP_FEATURE_SESSION_KEY", feature_list, True)) { + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; + } + if (in_list("NTLMSSP_FEATURE_SIGN", feature_list, True)) { + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; + } + if(in_list("NTLMSSP_FEATURE_SEAL", feature_list, True)) { + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; + } +} + +/** + * Request a feature for the NTLMSSP negotiation + * + * @param ntlmssp_state NTLMSSP state + * @param feature Bit flag specifying the requested feature + */ +void ntlmssp_want_feature(NTLMSSP_STATE *ntlmssp_state, uint32 feature) +{ + /* As per JRA's comment above */ + if (feature & NTLMSSP_FEATURE_SESSION_KEY) { + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; + } + if (feature & NTLMSSP_FEATURE_SIGN) { + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; + } + if (feature & NTLMSSP_FEATURE_SEAL) { + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; + } +} + +/** * Next state function for the NTLMSSP state machine * * @param ntlmssp_state NTLMSSP State @@ -1163,12 +1207,6 @@ NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_NTLM2 | NTLMSSP_NEGOTIATE_KEY_EXCH | - /* - * We need to set this to allow a later SetPassword - * via the SAMR pipe to succeed. Strange.... We could - * also add NTLMSSP_NEGOTIATE_SEAL here. JRA. - * */ - NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_REQUEST_TARGET; return NT_STATUS_OK; Modified: branches/SAMBA_3_0/source/utils/ntlm_auth.c =================================================================== --- branches/SAMBA_3_0/source/utils/ntlm_auth.c 2006-07-24 00:45:21 UTC (rev 17215) +++ branches/SAMBA_3_0/source/utils/ntlm_auth.c 2006-07-24 05:02:38 UTC (rev 17216) @@ -621,6 +621,10 @@ char *buf, int length) { static NTLMSSP_STATE *ntlmssp_state = NULL; + static char* want_feature_list = NULL; + static uint32 neg_flags = 0; + static BOOL have_session_key = False; + static DATA_BLOB session_key; DATA_BLOB request, reply; NTSTATUS nt_status; @@ -631,6 +635,13 @@ } if (strlen(buf) > 3) { + if(strncmp(buf, "SF ", 3) == 0){ + DEBUG(10, ("Setting flags to negotioate\n")); + SAFE_FREE(want_feature_list); + want_feature_list = SMB_STRNDUP(buf+3, strlen(buf)-3); + x_fprintf(x_stdout, "OK\n"); + return; + } request = base64_decode_data_blob(buf + 3); } else { request = data_blob(NULL, 0); @@ -658,6 +669,20 @@ ntlmssp_end(&ntlmssp_state); } else if (strncmp(buf, "KK", 2) == 0) { + } else if (strncmp(buf, "GF", 2) == 0) { + DEBUG(10, ("Requested negotiated NTLMSSP flags\n")); + x_fprintf(x_stdout, "GF 0x%08lx\n", have_session_key?neg_flags:0l); + data_blob_free(&request); + return; + } else if (strncmp(buf, "GK", 2) == 0) { + DEBUG(10, ("Requested NTLMSSP session key\n")); + if(have_session_key) + x_fprintf(x_stdout, "GK %s\n", base64_encode_data_blob(session_key)); + else + x_fprintf(x_stdout, "BH\n"); + + data_blob_free(&request); + return; } else { DEBUG(1, ("NTLMSSP query [%s] invalid", buf)); x_fprintf(x_stdout, "BH\n"); @@ -669,6 +694,7 @@ x_fprintf(x_stdout, "BH %s\n", nt_errstr(nt_status)); return; } + ntlmssp_want_feature_list(ntlmssp_state, want_feature_list); } DEBUG(10, ("got NTLMSSP packet:\n")); @@ -693,6 +719,13 @@ } else { x_fprintf(x_stdout, "AF %s\n", (char *)ntlmssp_state->auth_context); DEBUG(10, ("NTLMSSP OK!\n")); + + if(have_session_key) + data_blob_free(&session_key); + session_key = data_blob(ntlmssp_state->session_key.data, + ntlmssp_state->session_key.length); + neg_flags = ntlmssp_state->neg_flags; + have_session_key = True; } data_blob_free(&request); @@ -702,6 +735,10 @@ char *buf, int length) { static NTLMSSP_STATE *ntlmssp_state = NULL; + static char* want_feature_list = NULL; + static uint32 neg_flags = 0; + static BOOL have_session_key = False; + static DATA_BLOB session_key; DATA_BLOB request, reply; NTSTATUS nt_status; BOOL first = False; @@ -713,6 +750,13 @@ } if (strlen(buf) > 3) { + if(strncmp(buf, "SF ", 3) == 0) { + DEBUG(10, ("Looking for flags to negotiate\n")); + SAFE_FREE(want_feature_list); + want_feature_list = SMB_STRNDUP(buf+3, strlen(buf)-3); + x_fprintf(x_stdout, "OK\n"); + return; + } request = base64_decode_data_blob(buf + 3); } else { request = data_blob(NULL, 0); @@ -750,6 +794,23 @@ ntlmssp_end(&ntlmssp_state); } else if (strncmp(buf, "TT", 2) == 0) { + } else if (strncmp(buf, "GF", 2) == 0) { + DEBUG(10, ("Requested negotiated NTLMSSP flags\n")); + x_fprintf(x_stdout, "GF 0x%08lx\n", have_session_key?neg_flags:0l); + data_blob_free(&request); + return; + } else if (strncmp(buf, "GK", 2) == 0 ) { + DEBUG(10, ("Requested session key\n")); + + if(have_session_key) { + x_fprintf(x_stdout, "GK %s\n", base64_encode_data_blob(session_key)); + } + else { + x_fprintf(x_stdout, "BH\n"); + } + + data_blob_free(&request); + return; } else { DEBUG(1, ("NTLMSSP query [%s] invalid", buf)); x_fprintf(x_stdout, "BH\n"); @@ -761,6 +822,7 @@ x_fprintf(x_stdout, "BH %s\n", nt_errstr(nt_status)); return; } + ntlmssp_want_feature_list(ntlmssp_state, want_feature_list); first = True; } @@ -783,6 +845,15 @@ char *reply_base64 = base64_encode_data_blob(reply); x_fprintf(x_stdout, "AF %s\n", reply_base64); SAFE_FREE(reply_base64); + + if(have_session_key) + data_blob_free(&session_key); + + session_key = data_blob(ntlmssp_state->session_key.data, + ntlmssp_state->session_key.length); + neg_flags = ntlmssp_state->neg_flags; + have_session_key = True; + DEBUG(10, ("NTLMSSP OK!\n")); if (ntlmssp_state) ntlmssp_end(&ntlmssp_state);