http_ntlm.c
Go to the documentation of this file.
00001 /***************************************************************************
00002  *                                  _   _ ____  _
00003  *  Project                     ___| | | |  _ \| |
00004  *                             / __| | | | |_) | |
00005  *                            | (__| |_| |  _ <| |___
00006  *                             \___|\___/|_| \_\_____|
00007  *
00008  * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
00009  *
00010  * This software is licensed as described in the file COPYING, which
00011  * you should have received as part of this distribution. The terms
00012  * are also available at https://curl.haxx.se/docs/copyright.html.
00013  *
00014  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
00015  * copies of the Software, and permit persons to whom the Software is
00016  * furnished to do so, under the terms of the COPYING file.
00017  *
00018  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
00019  * KIND, either express or implied.
00020  *
00021  ***************************************************************************/
00022 
00023 #include "curl_setup.h"
00024 
00025 #if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM)
00026 
00027 /*
00028  * NTLM details:
00029  *
00030  * http://davenport.sourceforge.net/ntlm.html
00031  * https://www.innovation.ch/java/ntlm.html
00032  */
00033 
00034 #define DEBUG_ME 0
00035 
00036 #include "urldata.h"
00037 #include "sendf.h"
00038 #include "strcase.h"
00039 #include "http_ntlm.h"
00040 #include "curl_ntlm_wb.h"
00041 #include "vauth/vauth.h"
00042 #include "url.h"
00043 
00044 #if defined(USE_NSS)
00045 #include "vtls/nssg.h"
00046 #elif defined(USE_WINDOWS_SSPI)
00047 #include "curl_sspi.h"
00048 #endif
00049 
00050 /* The last 3 #include files should be in this order */
00051 #include "curl_printf.h"
00052 #include "curl_memory.h"
00053 #include "memdebug.h"
00054 
00055 #if DEBUG_ME
00056 # define DEBUG_OUT(x) x
00057 #else
00058 # define DEBUG_OUT(x) Curl_nop_stmt
00059 #endif
00060 
00061 CURLcode Curl_input_ntlm(struct connectdata *conn,
00062                          bool proxy,         /* if proxy or not */
00063                          const char *header) /* rest of the www-authenticate:
00064                                                 header */
00065 {
00066   /* point to the correct struct with this */
00067   struct ntlmdata *ntlm;
00068   CURLcode result = CURLE_OK;
00069 
00070   ntlm = proxy ? &conn->proxyntlm : &conn->ntlm;
00071 
00072   if(checkprefix("NTLM", header)) {
00073     header += strlen("NTLM");
00074 
00075     while(*header && ISSPACE(*header))
00076       header++;
00077 
00078     if(*header) {
00079       result = Curl_auth_decode_ntlm_type2_message(conn->data, header, ntlm);
00080       if(result)
00081         return result;
00082 
00083       ntlm->state = NTLMSTATE_TYPE2; /* We got a type-2 message */
00084     }
00085     else {
00086       if(ntlm->state == NTLMSTATE_LAST) {
00087         infof(conn->data, "NTLM auth restarted\n");
00088         Curl_http_ntlm_cleanup(conn);
00089       }
00090       else if(ntlm->state == NTLMSTATE_TYPE3) {
00091         infof(conn->data, "NTLM handshake rejected\n");
00092         Curl_http_ntlm_cleanup(conn);
00093         ntlm->state = NTLMSTATE_NONE;
00094         return CURLE_REMOTE_ACCESS_DENIED;
00095       }
00096       else if(ntlm->state >= NTLMSTATE_TYPE1) {
00097         infof(conn->data, "NTLM handshake failure (internal error)\n");
00098         return CURLE_REMOTE_ACCESS_DENIED;
00099       }
00100 
00101       ntlm->state = NTLMSTATE_TYPE1; /* We should send away a type-1 */
00102     }
00103   }
00104 
00105   return result;
00106 }
00107 
00108 /*
00109  * This is for creating ntlm header output
00110  */
00111 CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy)
00112 {
00113   char *base64 = NULL;
00114   size_t len = 0;
00115   CURLcode result;
00116 
00117   /* point to the address of the pointer that holds the string to send to the
00118      server, which is for a plain host or for a HTTP proxy */
00119   char **allocuserpwd;
00120 
00121   /* point to the name and password for this */
00122   const char *userp;
00123   const char *passwdp;
00124 
00125   /* point to the correct struct with this */
00126   struct ntlmdata *ntlm;
00127   struct auth *authp;
00128 
00129   DEBUGASSERT(conn);
00130   DEBUGASSERT(conn->data);
00131 
00132 #ifdef USE_NSS
00133   if(CURLE_OK != Curl_nss_force_init(conn->data))
00134     return CURLE_OUT_OF_MEMORY;
00135 #endif
00136 
00137   if(proxy) {
00138     allocuserpwd = &conn->allocptr.proxyuserpwd;
00139     userp = conn->http_proxy.user;
00140     passwdp = conn->http_proxy.passwd;
00141     ntlm = &conn->proxyntlm;
00142     authp = &conn->data->state.authproxy;
00143   }
00144   else {
00145     allocuserpwd = &conn->allocptr.userpwd;
00146     userp = conn->user;
00147     passwdp = conn->passwd;
00148     ntlm = &conn->ntlm;
00149     authp = &conn->data->state.authhost;
00150   }
00151   authp->done = FALSE;
00152 
00153   /* not set means empty */
00154   if(!userp)
00155     userp = "";
00156 
00157   if(!passwdp)
00158     passwdp = "";
00159 
00160 #ifdef USE_WINDOWS_SSPI
00161   if(s_hSecDll == NULL) {
00162     /* not thread safe and leaks - use curl_global_init() to avoid */
00163     CURLcode err = Curl_sspi_global_init();
00164     if(s_hSecDll == NULL)
00165       return err;
00166   }
00167 #endif
00168 
00169   switch(ntlm->state) {
00170   case NTLMSTATE_TYPE1:
00171   default: /* for the weird cases we (re)start here */
00172     /* Create a type-1 message */
00173     result = Curl_auth_create_ntlm_type1_message(userp, passwdp, ntlm, &base64,
00174                                                  &len);
00175     if(result)
00176       return result;
00177 
00178     if(base64) {
00179       free(*allocuserpwd);
00180       *allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n",
00181                               proxy ? "Proxy-" : "",
00182                               base64);
00183       free(base64);
00184       if(!*allocuserpwd)
00185         return CURLE_OUT_OF_MEMORY;
00186 
00187       DEBUG_OUT(fprintf(stderr, "**** Header %s\n ", *allocuserpwd));
00188     }
00189     break;
00190 
00191   case NTLMSTATE_TYPE2:
00192     /* We already received the type-2 message, create a type-3 message */
00193     result = Curl_auth_create_ntlm_type3_message(conn->data, userp, passwdp,
00194                                                  ntlm, &base64, &len);
00195     if(result)
00196       return result;
00197 
00198     if(base64) {
00199       free(*allocuserpwd);
00200       *allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n",
00201                               proxy ? "Proxy-" : "",
00202                               base64);
00203       free(base64);
00204       if(!*allocuserpwd)
00205         return CURLE_OUT_OF_MEMORY;
00206 
00207       DEBUG_OUT(fprintf(stderr, "**** %s\n ", *allocuserpwd));
00208 
00209       ntlm->state = NTLMSTATE_TYPE3; /* we send a type-3 */
00210       authp->done = TRUE;
00211     }
00212     break;
00213 
00214   case NTLMSTATE_TYPE3:
00215     /* connection is already authenticated,
00216      * don't send a header in future requests */
00217     ntlm->state = NTLMSTATE_LAST;
00218     /* fall-through */
00219   case NTLMSTATE_LAST:
00220     Curl_safefree(*allocuserpwd);
00221     authp->done = TRUE;
00222     break;
00223   }
00224 
00225   return CURLE_OK;
00226 }
00227 
00228 void Curl_http_ntlm_cleanup(struct connectdata *conn)
00229 {
00230   Curl_auth_ntlm_cleanup(&conn->ntlm);
00231   Curl_auth_ntlm_cleanup(&conn->proxyntlm);
00232 
00233 #if defined(NTLM_WB_ENABLED)
00234   Curl_ntlm_wb_cleanup(conn);
00235 #endif
00236 }
00237 
00238 #endif /* !CURL_DISABLE_HTTP && USE_NTLM */


rc_visard_driver
Author(s): Heiko Hirschmueller , Christian Emmerich , Felix Ruess
autogenerated on Thu Jun 6 2019 20:43:04