]> granicus.if.org Git - curl/commitdiff
http_negotiate_sspi: Fixed specific username and password not working
authorSteve Holme <steve_holme@hotmail.com>
Fri, 11 Jul 2014 20:45:25 +0000 (21:45 +0100)
committerSteve Holme <steve_holme@hotmail.com>
Wed, 6 Aug 2014 19:31:19 +0000 (20:31 +0100)
Bug: http://curl.haxx.se/mail/lib-2014-06/0224.html
Reported-by: Leonardo Rosati
lib/http_negotiate_sspi.c
lib/urldata.h

index 8e639149563cc379bf5b05d253d0124bb2028dae..260c78f061b98210ddc5f1fde9da2e7622766251 100644 (file)
@@ -68,8 +68,6 @@ get_gss_name(struct connectdata *conn, bool proxy,
 int Curl_input_negotiate(struct connectdata *conn, bool proxy,
                          const char *header)
 {
-  struct negotiatedata *neg_ctx = proxy?&conn->data->state.proxyneg:
-    &conn->data->state.negotiate;
   BYTE              *input_token = 0;
   SecBufferDesc     out_buff_desc;
   SecBuffer         out_sec_buff;
@@ -82,6 +80,31 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
   size_t len = 0, input_token_len = 0;
   CURLcode error;
 
+  /* Point to the username and password */
+  const char *userp;
+  const char *passwdp;
+
+  /* Point to the correct struct with this */
+  struct negotiatedata *neg_ctx;
+
+  if(proxy) {
+    userp = conn->proxyuser;
+    passwdp = conn->proxypasswd;
+    neg_ctx = &conn->data->state.proxyneg;
+  }
+  else {
+    userp = conn->user;
+    passwdp = conn->passwd;
+    neg_ctx = &conn->data->state.negotiate;
+  }
+
+  /* Not set means empty */
+  if(!userp)
+    userp = "";
+
+  if(!passwdp)
+    passwdp = "";
+
   if(neg_ctx->context && neg_ctx->status == SEC_E_OK) {
     /* We finished successfully our part of authentication, but server
      * rejected it (since we're again here). Exit with an error since we
@@ -131,12 +154,26 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
     if(!neg_ctx->credentials || !neg_ctx->context)
       return -1;
 
+    if(userp && *userp) {
+      /* Populate our identity structure */
+      error = Curl_create_sspi_identity(userp, passwdp, &neg_ctx->identity);
+      if(error)
+        return -1;
+
+      /* Allow proper cleanup of the identity structure */
+      neg_ctx->p_identity = &neg_ctx->identity;
+    }
+    else
+      /* Use the current Windows user */
+      neg_ctx->p_identity = NULL;
+
+    /* Acquire our credientials handle */
     neg_ctx->status =
       s_pSecFn->AcquireCredentialsHandle(NULL,
                                          (TCHAR *) TEXT("Negotiate"),
-                                         SECPKG_CRED_OUTBOUND, NULL, NULL,
-                                         NULL, NULL, neg_ctx->credentials,
-                                         &lifetime);
+                                         SECPKG_CRED_OUTBOUND, NULL,
+                                         neg_ctx->p_identity, NULL, NULL,
+                                         neg_ctx->credentials, &lifetime);
     if(neg_ctx->status != SEC_E_OK)
       return -1;
   }
@@ -260,6 +297,9 @@ static void cleanup(struct negotiatedata *neg_ctx)
   }
 
   neg_ctx->max_token_length = 0;
+
+  Curl_sspi_free_identity(neg_ctx->p_identity);
+  neg_ctx->p_identity = NULL;
 }
 
 void Curl_cleanup_negotiate(struct SessionHandle *data)
index f32988afad7aa7ff27bee858c7e95f5b564a4127..dcf72dd1dc5169635c9c13f7a21ed6b7e902d3c0 100644 (file)
@@ -459,6 +459,8 @@ struct negotiatedata {
   DWORD status;
   CtxtHandle *context;
   CredHandle *credentials;
+  SEC_WINNT_AUTH_IDENTITY identity;
+  SEC_WINNT_AUTH_IDENTITY *p_identity;
   char server_name[1024];
   size_t max_token_length;
   BYTE *output_token;