Changes to make gss-spnego ntlmssp client work against W2k AD.
authorVolker Lendecke <vlendec@samba.org>
Mon, 4 Aug 2003 13:10:43 +0000 (13:10 +0000)
committerVolker Lendecke <vlendec@samba.org>
Mon, 4 Aug 2003 13:10:43 +0000 (13:10 +0000)
Now I know where the mechListMIC changes came from: Ethereal ;-)

Volker
(This used to be commit 4e9eed1273035d09ac3b427b9711327ba8c6ebfc)

source3/libsmb/spnego.c
source3/utils/ntlm_auth.c

index 8cf2413a2150281e0625280af6eaf4d575abfe98..0b2dec7ef84f1239b55b2fd539ae90258254ad71 100644 (file)
@@ -71,7 +71,23 @@ static BOOL read_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token)
                /* Read mecListMIC */
                case ASN1_CONTEXT(3):
                        asn1_start_tag(asn1, ASN1_CONTEXT(3));
-                       asn1_read_OctetString(asn1, &token->mechListMIC);
+                       if (asn1->data[asn1->ofs] == ASN1_OCTET_STRING) {
+                               asn1_read_OctetString(asn1,
+                                                     &token->mechListMIC);
+                       } else {
+                               /* RFC 2478 says we have an Octet String here,
+                                  but W2k sends something different... */
+                               char *mechListMIC;
+                               asn1_push_tag(asn1, ASN1_SEQUENCE(0));
+                               asn1_push_tag(asn1, ASN1_CONTEXT(0));
+                               asn1_read_GeneralString(asn1, &mechListMIC);
+                               asn1_pop_tag(asn1);
+                               asn1_pop_tag(asn1);
+
+                               token->mechListMIC =
+                                       data_blob(mechListMIC, strlen(mechListMIC));
+                               SAFE_FREE(mechListMIC);
+                       }
                        asn1_end_tag(asn1);
                        break;
                default:
index 1d36a7ce521eb3dec759082e62fdaa2a2759ee05..87f49621f49f79d9e2db70b6f2849e836dd33691 100644 (file)
@@ -560,7 +560,7 @@ static void manage_gss_spnego_request(enum squid_mode squid_mode,
 
 static NTLMSSP_CLIENT_STATE *client_ntlmssp_state = NULL;
 
-static void manage_client_ntlmssp_init(SPNEGO_DATA spnego)
+static BOOL manage_client_ntlmssp_init(SPNEGO_DATA spnego)
 {
        NTSTATUS status;
        DATA_BLOB null_blob = data_blob(NULL, 0);
@@ -573,14 +573,12 @@ static void manage_client_ntlmssp_init(SPNEGO_DATA spnego)
        if (client_ntlmssp_state != NULL) {
                DEBUG(1, ("Request for initial SPNEGO request where "
                          "we already have a state\n"));
-               x_fprintf(x_stdout, "BH\n");
-               return;
+               return False;
        }
 
        if ( (opt_username == NULL) || (opt_domain == NULL) ) {
                DEBUG(1, ("Need username and domain for NTLMSSP\n"));
-               x_fprintf(x_stdout, "BH\n");
-               return;
+               return False;
        }
 
        if (opt_password == NULL) {
@@ -591,7 +589,7 @@ static void manage_client_ntlmssp_init(SPNEGO_DATA spnego)
 
                DEBUG(10, ("Requesting password\n"));
                x_fprintf(x_stdout, "PW\n");
-               return;
+               return True;
        }
 
        status = ntlmssp_client_start(&client_ntlmssp_state);
@@ -599,9 +597,8 @@ static void manage_client_ntlmssp_init(SPNEGO_DATA spnego)
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(1, ("Could not start NTLMSSP client: %s\n",
                          nt_errstr(status)));
-               x_fprintf(x_stdout, "BH\n");
                ntlmssp_client_end(&client_ntlmssp_state);
-               return;
+               return False;
        }
 
        status = ntlmssp_set_username(client_ntlmssp_state, opt_username);
@@ -609,9 +606,8 @@ static void manage_client_ntlmssp_init(SPNEGO_DATA spnego)
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(1, ("Could not set username: %s\n",
                          nt_errstr(status)));
-               x_fprintf(x_stdout, "BH\n");
                ntlmssp_client_end(&client_ntlmssp_state);
-               return;
+               return False;
        }
 
        status = ntlmssp_set_domain(client_ntlmssp_state, opt_domain);
@@ -619,9 +615,8 @@ static void manage_client_ntlmssp_init(SPNEGO_DATA spnego)
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(1, ("Could not set domain: %s\n",
                          nt_errstr(status)));
-               x_fprintf(x_stdout, "BH\n");
                ntlmssp_client_end(&client_ntlmssp_state);
-               return;
+               return False;
        }
 
        status = ntlmssp_set_password(client_ntlmssp_state, opt_password);
@@ -629,9 +624,8 @@ static void manage_client_ntlmssp_init(SPNEGO_DATA spnego)
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(1, ("Could not set password: %s\n",
                          nt_errstr(status)));
-               x_fprintf(x_stdout, "BH\n");
                ntlmssp_client_end(&client_ntlmssp_state);
-               return;
+               return False;
        }
 
        spnego.type = SPNEGO_NEG_TOKEN_INIT;
@@ -645,9 +639,8 @@ static void manage_client_ntlmssp_init(SPNEGO_DATA spnego)
        if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
                DEBUG(1, ("Expected MORE_PROCESSING_REQUIRED, got: %s\n",
                          nt_errstr(status)));
-               x_fprintf(x_stdout, "BH\n");
                ntlmssp_client_end(&client_ntlmssp_state);
-               return;
+               return False;
        }
 
        write_spnego_data(&to_server, &spnego);
@@ -657,7 +650,7 @@ static void manage_client_ntlmssp_init(SPNEGO_DATA spnego)
        data_blob_free(&to_server);
        x_fprintf(x_stdout, "KK %s\n", to_server_base64);
        SAFE_FREE(to_server_base64);
-       return;
+       return True;
 }
 
 static void manage_client_ntlmssp_targ(SPNEGO_DATA spnego)
@@ -719,11 +712,10 @@ static void manage_client_ntlmssp_targ(SPNEGO_DATA spnego)
        return;
 }
 
-static void manage_client_krb5_init(SPNEGO_DATA spnego)
+static BOOL manage_client_krb5_init(SPNEGO_DATA spnego)
 {
        DEBUG(1, ("to be done ... \n"));
-       x_fprintf(x_stdout, "BH\n");
-       return;
+       return False;
 }
 
 static void manage_client_krb5_targ(SPNEGO_DATA spnego)
@@ -796,14 +788,15 @@ static void manage_gss_spnego_client_request(enum squid_mode squid_mode,
 
                while (*mechType != NULL) {
 
-                       if (strcmp(*mechType, OID_NTLMSSP) == 0) {
-                               manage_client_ntlmssp_init(spnego);
-                               goto out;
+                       if ( (strcmp(*mechType, OID_KERBEROS5_OLD) == 0) ||
+                            (strcmp(*mechType, OID_KERBEROS5) == 0) ) {
+                               if (manage_client_krb5_init(spnego))
+                                       goto out;
                        }
 
-                       if (strcmp(*mechType, OID_KERBEROS5_OLD) == 0) {
-                               manage_client_krb5_init(spnego);
-                               goto out;
+                       if (strcmp(*mechType, OID_NTLMSSP) == 0) {
+                               if (manage_client_ntlmssp_init(spnego))
+                                       goto out;
                        }
 
                        mechType++;
@@ -816,6 +809,29 @@ static void manage_gss_spnego_client_request(enum squid_mode squid_mode,
 
        if (spnego.type == SPNEGO_NEG_TOKEN_TARG) {
 
+               if (spnego.negTokenTarg.supportedMech == NULL) {
+                       /* On accept/reject Windows does not send the
+                           mechanism anymore. Handle that here and
+                           shut down the mechanisms. */
+
+                       switch (spnego.negTokenTarg.negResult) {
+                       case SPNEGO_ACCEPT_COMPLETED:
+                               x_fprintf(x_stdout, "AF\n");
+                               break;
+                       case SPNEGO_REJECT:
+                               x_fprintf(x_stdout, "NA\n");
+                               break;
+                       default:
+                               DEBUG(1, ("Got a negTokenTarg with no mech and an "
+                                         "unknown negResult: %d\n",
+                                         spnego.negTokenTarg.negResult));
+                               x_fprintf(x_stdout, "BH\n");
+                       }
+
+                       ntlmssp_client_end(&client_ntlmssp_state);
+                       goto out;
+               }
+
                if (strcmp(spnego.negTokenTarg.supportedMech,
                           OID_NTLMSSP) == 0) {
                        manage_client_ntlmssp_targ(spnego);