r17216: From Kai Blin <kai.blin@gmail.com>:
authorAndrew Bartlett <abartlet@samba.org>
Mon, 24 Jul 2006 05:02:38 +0000 (05:02 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 16:38:19 +0000 (11:38 -0500)
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
(This used to be commit bd3e06a0e4435f1c48fa3b7862333efe273119ee)

source3/include/ntlmssp.h
source3/libsmb/cliconnect.c
source3/libsmb/ntlmssp.c
source3/utils/ntlm_auth.c

index a2dac7dc0ba075340e1f133b6e3b49db93a881ee..a158fb614f5dffe8e2e134547bf55b84bbcce4e7 100644 (file)
@@ -65,6 +65,10 @@ enum NTLM_MESSAGE_TYPE
 #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
index 4c3c4f456508c054127920c2eedcb8249a70e37e..d547bb385406ed180fb816ed80f7458c87af928a 100644 (file)
@@ -599,6 +599,7 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use
        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;
index 986fa8cce9f77ea548a00ae7881ffcb05931f2d0..a6fb3b426b61dfe058e109ece6e83bee0bde999d 100644 (file)
@@ -210,6 +210,50 @@ NTSTATUS ntlmssp_store_response(NTLMSSP_STATE *ntlmssp_state,
        return NT_STATUS_OK;
 }
 
+/**
+ * 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
  * 
@@ -1163,12 +1207,6 @@ NTSTATUS ntlmssp_client_start(NTLMSSP_STATE **ntlmssp_state)
                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;
index 9e178ec9456a0d0544d5f9055e36f4d089a861ca..c33ab9f8acbdbfe40f203d4c6a741488c9f3d556 100644 (file)
@@ -621,6 +621,10 @@ static void manage_squid_ntlmssp_request(enum stdio_helper_mode stdio_helper_mod
                                         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 @@ static void manage_squid_ntlmssp_request(enum stdio_helper_mode stdio_helper_mod
        }
 
        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 @@ static void manage_squid_ntlmssp_request(enum stdio_helper_mode stdio_helper_mod
                        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 @@ static void manage_squid_ntlmssp_request(enum stdio_helper_mode stdio_helper_mod
                        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 @@ static void manage_squid_ntlmssp_request(enum stdio_helper_mode stdio_helper_mod
        } 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 @@ static void manage_client_ntlmssp_request(enum stdio_helper_mode stdio_helper_mo
                                         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 @@ static void manage_client_ntlmssp_request(enum stdio_helper_mode stdio_helper_mo
        }
 
        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 @@ static void manage_client_ntlmssp_request(enum stdio_helper_mode stdio_helper_mo
                        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 @@ static void manage_client_ntlmssp_request(enum stdio_helper_mode stdio_helper_mo
                        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 @@ static void manage_client_ntlmssp_request(enum stdio_helper_mode stdio_helper_mo
                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);