cURL / Mailing Lists / curl-library / Single Mail

curl-library

Re: problems using negotiate with sspi in 7.21.6

From: Ibraheem <ibraheempindi_at_yahoo.com>
Date: Tue, 24 May 2011 02:01:35 -0700 (PDT)

I did some changes around in couple of files, so that negotiate protocol can deal better with kerberos or ntlm tokens generated through sspi calls. It seems to be working, but it's a hack fix, and may be some one can help me to make it a proper fix. The proper fix should be that we should take account of what InitializeSecurityContext function returns in the http_negotiate_sspi.c file. If it returns SEC_I_COMPLETE_AND_CONTINUE  or SEC_I_CONTINUE_NEEDED  , then we should call again InitializeSecurityContext after getting the next token from the server (both in ntlm and kerbeors token, although in kerberos token server will return 200 instead of 401). But if in kerberos we call again InitializeSecurityContext with server returned token, then there will be no more token generated by this call and output will be empty as the cycle is completed and it will return SEC_E_OK. But libcurl currently tries to call Curl_output_negotiate and try to send
 empty token again........that's why i did it in otherway... (comparing ntlm token....technique). Anyhow if someone have good idea how can i call Curl_input_negotiate to complete the cycle and not calling Curl_output_negotiate as the cycle is completed and auth is done??? @@ -538,7 +538,13 @@      result = Curl_output_negotiate(conn, proxy);      if(result)        return result; -    authstatus->done = TRUE; +if ( negdata->status == SEC_I_CONTINUE_NEEDED || +negdata->status == SEC_I_COMPLETE_AND_CONTINUE ){ +authstatus->done = FALSE; +} +else +authstatus->done = TRUE; +      negdata->state = GSS_AUTHSENT;    }    else @@ -735,7 +741,7 @@      *availp |= CURLAUTH_GSSNEGOTIATE;      authp->avail |= CURLAUTH_GSSNEGOTIATE;   -    if(data->state.negotiate.state == GSS_AUTHSENT) { +if(data->state.negotiate.state == GSS_AUTHSENT && data->state.negotiate.status!=SEC_I_CONTINUE_NEEDED && data->state.negotiate.status!=SEC_I_COMPLETE_AND_CONTINUE) {        /* if we sent GSS authentication in the outgoing request and we get this           back, we're in trouble */        infof(data, "Authentication problem. Ignoring this.\n"); @@ -744,7 +750,7 @@      else {        neg = Curl_input_negotiate(conn, (bool)(httpcode == 407), start);        if(neg == 0) { -        DEBUGASSERT(!data->req.newurl); +  DEBUGASSERT(!data->req.newurl);          data->req.newurl = strdup(data->change.url);          if(!data->req.newurl)            return CURLE_OUT_OF_MEMORY; @@ -3289,9 +3295,10 @@          data->info.filetime = (long)k->timeofdoc;      }      else if((checkprefix("WWW-Authenticate:", k->p) && -             (401 == k->httpcode)) || +(401 == k->httpcode /*|| conn->data->state.negotiate.status==SEC_I_CONTINUE_NEEDED || conn->data->state.negotiate.status==SEC_I_COMPLETE_AND_CONTINUE*/)) ||              (checkprefix("Proxy-authenticate:", k->p) &&               (407 == k->httpcode))) { + //if we deal properly the return codes from negotiate context, then we can uncomment above.        result = Curl_http_input_auth(conn, k->httpcode, k->p);        if(result)          return result; @@ -91,7 +91,6 @@    SecBuffer         in_sec_buff;    ULONG             context_attributes;    TimeStamp         lifetime; -    int ret;    size_t len = 0, input_token_len = 0;    bool gss = FALSE; @@ -121,6 +120,13 @@      neg_ctx->gss = gss;    }   +   if(neg_ctx->output_token) { +  free(neg_ctx->output_token); +  neg_ctx->output_token = 0; +  neg_ctx->output_token_length = 0; +  neg_ctx->max_token_length = 0; +  } +    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 @@ -196,7 +202,7 @@    if (input_token) {      in_buff_desc.ulVersion = 0;      in_buff_desc.cBuffers  = 1; -    in_buff_desc.pBuffers  = &out_sec_buff; +    in_buff_desc.pBuffers  = &in_sec_buff;        in_sec_buff.cbBuffer   = input_token_len;      in_sec_buff.BufferType = SECBUFFER_TOKEN; @@ -222,10 +228,33 @@      if ( neg_ctx->status == SEC_I_COMPLETE_NEEDED ||         neg_ctx->status == SEC_I_COMPLETE_AND_CONTINUE ) { -    neg_ctx->status = s_pSecFn->CompleteAuthToken(neg_ctx->context, +   neg_ctx->status = s_pSecFn->CompleteAuthToken(neg_ctx->context,                                                    &out_buff_desc);      if ( GSS_ERROR(neg_ctx->status) )        return -1; + +  } +  //else if(neg_ctx->status == SEC_E_OK && out_sec_buff.cbBuffer==0) +  //{ + //  //means we are done so no need to continue... +  //Curl_cleanup_negotiate (conn->data); +  //conn->data->state.authhost.done = TRUE;   +  //} +  if ( neg_ctx->status == SEC_I_CONTINUE_NEEDED || +       neg_ctx->status == SEC_I_COMPLETE_AND_CONTINUE ) { +if(out_sec_buff.cbBuffer>0) +{ +   if(!(checkprefix("NTLM",out_sec_buff.pvBuffer))) +   { +neg_ctx->status = SEC_E_OK; +//means we are doing kerberos auth, so we can skipp next cycle. +   } +} +   //    +//   /////we need to continue...not end. +  //  if ( GSS_ERROR(neg_ctx->status) ) +  //    return -1; +    }      neg_ctx->output_token_length = out_sec_buff.cbBuffer; @@ -258,30 +287,35 @@    else      conn->allocptr.userpwd = userp;    free(encoded); +      Curl_cleanup_negotiate (conn->data); +    return (userp == NULL) ? CURLE_OUT_OF_MEMORY : CURLE_OK;  }    static void cleanup(struct negotiatedata *neg_ctx)  { -  if(neg_ctx->context) { -    s_pSecFn->DeleteSecurityContext(neg_ctx->context); -    free(neg_ctx->context); -    neg_ctx->context = 0; -  } +if ( neg_ctx->status != SEC_I_CONTINUE_NEEDED && +neg_ctx->status != SEC_I_COMPLETE_AND_CONTINUE ) { +//delete the context and handle if we are done. +if(neg_ctx->context) { +s_pSecFn->DeleteSecurityContext(neg_ctx->context); +free(neg_ctx->context); +neg_ctx->context = 0; +}   -  if(neg_ctx->credentials) { -    s_pSecFn->FreeCredentialsHandle(neg_ctx->credentials); -    free(neg_ctx->credentials); -    neg_ctx->credentials = 0; -  } - -  if(neg_ctx->output_token) { -    free(neg_ctx->output_token); -    neg_ctx->output_token = 0; -neg_ctx->output_token_length = 0; -neg_ctx->max_token_length = 0; -  } +if(neg_ctx->credentials) { +s_pSecFn->FreeCredentialsHandle(neg_ctx->credentials); +free(neg_ctx->credentials); +neg_ctx->credentials = 0; +} +if(neg_ctx->output_token) { +free(neg_ctx->output_token); +neg_ctx->output_token = 0; +neg_ctx->output_token_length = 0; +neg_ctx->max_token_length = 0; +} +}  }    void Curl_cleanup_negotiate(struct SessionHandle *data)

-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html
Received on 2011-05-24