Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "curl_setup.h"
00024
00025 #if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM)
00026
00027
00028
00029
00030
00031
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
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,
00063 const char *header)
00064
00065 {
00066
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;
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;
00102 }
00103 }
00104
00105 return result;
00106 }
00107
00108
00109
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
00118
00119 char **allocuserpwd;
00120
00121
00122 const char *userp;
00123 const char *passwdp;
00124
00125
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
00154 if(!userp)
00155 userp = "";
00156
00157 if(!passwdp)
00158 passwdp = "";
00159
00160 #ifdef USE_WINDOWS_SSPI
00161 if(s_hSecDll == NULL) {
00162
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:
00172
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
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;
00210 authp->done = TRUE;
00211 }
00212 break;
00213
00214 case NTLMSTATE_TYPE3:
00215
00216
00217 ntlm->state = NTLMSTATE_LAST;
00218
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