Skip to content
http_ntlm.c 34.3 KiB
Newer Older
    DEBUGASSERT(size == (size_t)lmrespoff);
    /* We append the binary hashes */
    if(size < (sizeof(ntlmbuf) - 0x18)) {
      memcpy(&ntlmbuf[size], lmresp, 0x18);
      size += 0x18;
    }

    DEBUG_OUT({
        fprintf(stderr, "**** TYPE3 header lmresp=");
        print_hex(stderr, (char *)&ntlmbuf[lmrespoff], 0x18);
    });

#if USE_NTRESPONSES
    if(size < (sizeof(ntlmbuf) - 0x18)) {
      DEBUGASSERT(size == (size_t)ntrespoff);
      memcpy(&ntlmbuf[size], ntresp, 0x18);
      size += 0x18;
    }

    DEBUG_OUT({
        fprintf(stderr, "\n                  ntresp=");
        print_hex(stderr, (char *)&ntlmbuf[ntrespoff], 0x18);
    DEBUG_OUT({
        fprintf(stderr, "\n                  flags=0x%02.2x%02.2x%02.2x%02.2x 0x%08.8x ",
                LONGQUARTET(ntlm->flags), ntlm->flags);
        print_flags(stderr, ntlm->flags);
        fprintf(stderr, "\n****\n");
    });


    /* Make sure that the domain, user and host strings fit in the target
       buffer before we copy them there. */
    if(size + userlen + domlen + hostlen >= sizeof(ntlmbuf)) {
      failf(conn->data, "user + domain + host name too big");
    memcpy(&ntlmbuf[size], domain, domlen);
    memcpy(&ntlmbuf[size], user, userlen);
    memcpy(&ntlmbuf[size], host, hostlen);
    size += hostlen;
#ifdef CURL_DOES_CONVERSIONS
    /* convert domain, user, and host to ASCII but leave the rest as-is */
    if(CURLE_OK != Curl_convert_to_network(conn->data,
                                           (char *)&ntlmbuf[domoff],
                                           size-domoff)) {
      return CURLE_CONV_FAILED;
    }
#endif /* CURL_DOES_CONVERSIONS */

    /* convert the binary blob into base64 */
    size = Curl_base64_encode(NULL, (char *)ntlmbuf, size, &base64);
      Curl_safefree(*allocuserpwd);
      *allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n",
                              proxy?"Proxy-":"",
                              base64);
      DEBUG_OUT(fprintf(stderr, "**** %s\n ", *allocuserpwd));
      free(base64);
    }
    else
      return CURLE_OUT_OF_MEMORY; /* FIX TODO */

    ntlm->state = NTLMSTATE_TYPE3; /* we sent a type-3 */
    authp->done = TRUE;
  }
  break;

  case NTLMSTATE_TYPE3:
    /* connection is already authenticated,
     * don't send a header in future requests */
    if(*allocuserpwd) {
      free(*allocuserpwd);
      *allocuserpwd=NULL;
    authp->done = TRUE;


void
Curl_ntlm_cleanup(struct connectdata *conn)
{
#ifdef USE_WINDOWS_SSPI
  ntlm_sspi_cleanup(&conn->ntlm);
  ntlm_sspi_cleanup(&conn->proxyntlm);
#else
  (void)conn;
#endif
}

#ifdef USE_WINDOWS_SSPI
CURLcode Curl_ntlm_global_init()
{
  /* If security interface is not yet initialized try to do this */
  if(s_hSecDll == NULL) {
    /* Determine Windows version. Security functions are located in
     * security.dll on WinNT 4.0 and in secur32.dll on Win9x. Win2K and XP
     * contain both these DLLs (security.dll just forwards calls to
     * secur32.dll)
     */
    OSVERSIONINFO osver;
    osver.dwOSVersionInfoSize = sizeof(osver);
    GetVersionEx(&osver);
    if(osver.dwPlatformId == VER_PLATFORM_WIN32_NT
      && osver.dwMajorVersion == 4)
      s_hSecDll = LoadLibrary("security.dll");
    else
      s_hSecDll = LoadLibrary("secur32.dll");
    if(s_hSecDll != NULL) {
      INIT_SECURITY_INTERFACE pInitSecurityInterface;
      pInitSecurityInterface =
        (INIT_SECURITY_INTERFACE)GetProcAddress(s_hSecDll,
                                                "InitSecurityInterfaceA");
      if(pInitSecurityInterface != NULL)
        s_pSecFn = pInitSecurityInterface();
    }
  }
  if(s_pSecFn == NULL)
    return CURLE_RECV_ERROR;

  return CURLE_OK;
}

void Curl_ntlm_global_cleanup()
{