00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "curl_setup.h"
00025
00026 #if defined(USE_WINDOWS_SSPI) && !defined(CURL_DISABLE_PROXY)
00027
00028 #include "urldata.h"
00029 #include "sendf.h"
00030 #include "connect.h"
00031 #include "strerror.h"
00032 #include "timeval.h"
00033 #include "socks.h"
00034 #include "curl_sspi.h"
00035 #include "curl_multibyte.h"
00036 #include "warnless.h"
00037 #include "strdup.h"
00038
00039 #include "curl_printf.h"
00040 #include "curl_memory.h"
00041 #include "memdebug.h"
00042
00043
00044
00045
00046 static int check_sspi_err(struct connectdata *conn,
00047 SECURITY_STATUS status,
00048 const char *function)
00049 {
00050 if(status != SEC_E_OK &&
00051 status != SEC_I_COMPLETE_AND_CONTINUE &&
00052 status != SEC_I_COMPLETE_NEEDED &&
00053 status != SEC_I_CONTINUE_NEEDED) {
00054 failf(conn->data, "SSPI error: %s failed: %s", function,
00055 Curl_sspi_strerror(conn, status));
00056 return 1;
00057 }
00058 return 0;
00059 }
00060
00061
00062 CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
00063 struct connectdata *conn)
00064 {
00065 struct Curl_easy *data = conn->data;
00066 curl_socket_t sock = conn->sock[sockindex];
00067 CURLcode code;
00068 ssize_t actualread;
00069 ssize_t written;
00070 int result;
00071
00072 SECURITY_STATUS status;
00073 unsigned long sspi_ret_flags = 0;
00074 unsigned char gss_enc;
00075 SecBuffer sspi_send_token, sspi_recv_token, sspi_w_token[3];
00076 SecBufferDesc input_desc, output_desc, wrap_desc;
00077 SecPkgContext_Sizes sspi_sizes;
00078 CredHandle cred_handle;
00079 CtxtHandle sspi_context;
00080 PCtxtHandle context_handle = NULL;
00081 SecPkgCredentials_Names names;
00082 TimeStamp expiry;
00083 char *service_name = NULL;
00084 unsigned short us_length;
00085 unsigned long qop;
00086 unsigned char socksreq[4];
00087 const char *service = data->set.str[STRING_PROXY_SERVICE_NAME] ?
00088 data->set.str[STRING_PROXY_SERVICE_NAME] : "rcmd";
00089 const size_t service_length = strlen(service);
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100 if(strchr(service, '/')) {
00101 service_name = strdup(service);
00102 if(!service_name)
00103 return CURLE_OUT_OF_MEMORY;
00104 }
00105 else {
00106 service_name = malloc(service_length +
00107 strlen(conn->socks_proxy.host.name) + 2);
00108 if(!service_name)
00109 return CURLE_OUT_OF_MEMORY;
00110 snprintf(service_name, service_length +
00111 strlen(conn->socks_proxy.host.name)+2, "%s/%s",
00112 service, conn->socks_proxy.host.name);
00113 }
00114
00115 input_desc.cBuffers = 1;
00116 input_desc.pBuffers = &sspi_recv_token;
00117 input_desc.ulVersion = SECBUFFER_VERSION;
00118
00119 sspi_recv_token.BufferType = SECBUFFER_TOKEN;
00120 sspi_recv_token.cbBuffer = 0;
00121 sspi_recv_token.pvBuffer = NULL;
00122
00123 output_desc.cBuffers = 1;
00124 output_desc.pBuffers = &sspi_send_token;
00125 output_desc.ulVersion = SECBUFFER_VERSION;
00126
00127 sspi_send_token.BufferType = SECBUFFER_TOKEN;
00128 sspi_send_token.cbBuffer = 0;
00129 sspi_send_token.pvBuffer = NULL;
00130
00131 wrap_desc.cBuffers = 3;
00132 wrap_desc.pBuffers = sspi_w_token;
00133 wrap_desc.ulVersion = SECBUFFER_VERSION;
00134
00135 cred_handle.dwLower = 0;
00136 cred_handle.dwUpper = 0;
00137
00138 status = s_pSecFn->AcquireCredentialsHandle(NULL,
00139 (TCHAR *) TEXT("Kerberos"),
00140 SECPKG_CRED_OUTBOUND,
00141 NULL,
00142 NULL,
00143 NULL,
00144 NULL,
00145 &cred_handle,
00146 &expiry);
00147
00148 if(check_sspi_err(conn, status, "AcquireCredentialsHandle")) {
00149 failf(data, "Failed to acquire credentials.");
00150 free(service_name);
00151 s_pSecFn->FreeCredentialsHandle(&cred_handle);
00152 return CURLE_COULDNT_CONNECT;
00153 }
00154
00155
00156
00157 for(;;) {
00158 TCHAR *sname;
00159
00160 sname = Curl_convert_UTF8_to_tchar(service_name);
00161 if(!sname)
00162 return CURLE_OUT_OF_MEMORY;
00163
00164 status = s_pSecFn->InitializeSecurityContext(&cred_handle,
00165 context_handle,
00166 sname,
00167 ISC_REQ_MUTUAL_AUTH |
00168 ISC_REQ_ALLOCATE_MEMORY |
00169 ISC_REQ_CONFIDENTIALITY |
00170 ISC_REQ_REPLAY_DETECT,
00171 0,
00172 SECURITY_NATIVE_DREP,
00173 &input_desc,
00174 0,
00175 &sspi_context,
00176 &output_desc,
00177 &sspi_ret_flags,
00178 &expiry);
00179
00180 Curl_unicodefree(sname);
00181
00182 if(sspi_recv_token.pvBuffer) {
00183 s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer);
00184 sspi_recv_token.pvBuffer = NULL;
00185 sspi_recv_token.cbBuffer = 0;
00186 }
00187
00188 if(check_sspi_err(conn, status, "InitializeSecurityContext")) {
00189 free(service_name);
00190 s_pSecFn->FreeCredentialsHandle(&cred_handle);
00191 s_pSecFn->DeleteSecurityContext(&sspi_context);
00192 if(sspi_recv_token.pvBuffer)
00193 s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer);
00194 failf(data, "Failed to initialise security context.");
00195 return CURLE_COULDNT_CONNECT;
00196 }
00197
00198 if(sspi_send_token.cbBuffer != 0) {
00199 socksreq[0] = 1;
00200 socksreq[1] = 1;
00201 us_length = htons((short)sspi_send_token.cbBuffer);
00202 memcpy(socksreq+2, &us_length, sizeof(short));
00203
00204 code = Curl_write_plain(conn, sock, (char *)socksreq, 4, &written);
00205 if(code || (4 != written)) {
00206 failf(data, "Failed to send SSPI authentication request.");
00207 free(service_name);
00208 if(sspi_send_token.pvBuffer)
00209 s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer);
00210 if(sspi_recv_token.pvBuffer)
00211 s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer);
00212 s_pSecFn->FreeCredentialsHandle(&cred_handle);
00213 s_pSecFn->DeleteSecurityContext(&sspi_context);
00214 return CURLE_COULDNT_CONNECT;
00215 }
00216
00217 code = Curl_write_plain(conn, sock, (char *)sspi_send_token.pvBuffer,
00218 sspi_send_token.cbBuffer, &written);
00219 if(code || (sspi_send_token.cbBuffer != (size_t)written)) {
00220 failf(data, "Failed to send SSPI authentication token.");
00221 free(service_name);
00222 if(sspi_send_token.pvBuffer)
00223 s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer);
00224 if(sspi_recv_token.pvBuffer)
00225 s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer);
00226 s_pSecFn->FreeCredentialsHandle(&cred_handle);
00227 s_pSecFn->DeleteSecurityContext(&sspi_context);
00228 return CURLE_COULDNT_CONNECT;
00229 }
00230
00231 }
00232
00233 if(sspi_send_token.pvBuffer) {
00234 s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer);
00235 sspi_send_token.pvBuffer = NULL;
00236 }
00237 sspi_send_token.cbBuffer = 0;
00238
00239 if(sspi_recv_token.pvBuffer) {
00240 s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer);
00241 sspi_recv_token.pvBuffer = NULL;
00242 }
00243 sspi_recv_token.cbBuffer = 0;
00244
00245 if(status != SEC_I_CONTINUE_NEEDED)
00246 break;
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258 result = Curl_blockread_all(conn, sock, (char *)socksreq, 4, &actualread);
00259 if(result || (actualread != 4)) {
00260 failf(data, "Failed to receive SSPI authentication response.");
00261 free(service_name);
00262 s_pSecFn->FreeCredentialsHandle(&cred_handle);
00263 s_pSecFn->DeleteSecurityContext(&sspi_context);
00264 return CURLE_COULDNT_CONNECT;
00265 }
00266
00267
00268 if(socksreq[1] == 255) {
00269 failf(data, "User was rejected by the SOCKS5 server (%u %u).",
00270 (unsigned int)socksreq[0], (unsigned int)socksreq[1]);
00271 free(service_name);
00272 s_pSecFn->FreeCredentialsHandle(&cred_handle);
00273 s_pSecFn->DeleteSecurityContext(&sspi_context);
00274 return CURLE_COULDNT_CONNECT;
00275 }
00276
00277 if(socksreq[1] != 1) {
00278 failf(data, "Invalid SSPI authentication response type (%u %u).",
00279 (unsigned int)socksreq[0], (unsigned int)socksreq[1]);
00280 free(service_name);
00281 s_pSecFn->FreeCredentialsHandle(&cred_handle);
00282 s_pSecFn->DeleteSecurityContext(&sspi_context);
00283 return CURLE_COULDNT_CONNECT;
00284 }
00285
00286 memcpy(&us_length, socksreq+2, sizeof(short));
00287 us_length = ntohs(us_length);
00288
00289 sspi_recv_token.cbBuffer = us_length;
00290 sspi_recv_token.pvBuffer = malloc(us_length);
00291
00292 if(!sspi_recv_token.pvBuffer) {
00293 free(service_name);
00294 s_pSecFn->FreeCredentialsHandle(&cred_handle);
00295 s_pSecFn->DeleteSecurityContext(&sspi_context);
00296 return CURLE_OUT_OF_MEMORY;
00297 }
00298 result = Curl_blockread_all(conn, sock, (char *)sspi_recv_token.pvBuffer,
00299 sspi_recv_token.cbBuffer, &actualread);
00300
00301 if(result || (actualread != us_length)) {
00302 failf(data, "Failed to receive SSPI authentication token.");
00303 free(service_name);
00304 if(sspi_recv_token.pvBuffer)
00305 s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer);
00306 s_pSecFn->FreeCredentialsHandle(&cred_handle);
00307 s_pSecFn->DeleteSecurityContext(&sspi_context);
00308 return CURLE_COULDNT_CONNECT;
00309 }
00310
00311 context_handle = &sspi_context;
00312 }
00313
00314 free(service_name);
00315
00316
00317 status = s_pSecFn->QueryCredentialsAttributes(&cred_handle,
00318 SECPKG_CRED_ATTR_NAMES,
00319 &names);
00320 s_pSecFn->FreeCredentialsHandle(&cred_handle);
00321 if(check_sspi_err(conn, status, "QueryCredentialAttributes")) {
00322 s_pSecFn->DeleteSecurityContext(&sspi_context);
00323 s_pSecFn->FreeContextBuffer(names.sUserName);
00324 failf(data, "Failed to determine user name.");
00325 return CURLE_COULDNT_CONNECT;
00326 }
00327 infof(data, "SOCKS5 server authencticated user %s with GSS-API.\n",
00328 names.sUserName);
00329 s_pSecFn->FreeContextBuffer(names.sUserName);
00330
00331
00332 socksreq[0] = 1;
00333 socksreq[1] = 2;
00334
00335 gss_enc = 0;
00336
00337 if(sspi_ret_flags & ISC_REQ_CONFIDENTIALITY)
00338 gss_enc = 2;
00339
00340 else if(sspi_ret_flags & ISC_REQ_INTEGRITY)
00341 gss_enc = 1;
00342
00343 infof(data, "SOCKS5 server supports GSS-API %s data protection.\n",
00344 (gss_enc==0)?"no":((gss_enc==1)?"integrity":"confidentiality") );
00345
00346 gss_enc = 0;
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378 if(data->set.socks5_gssapi_nec) {
00379 us_length = htons((short)1);
00380 memcpy(socksreq+2, &us_length, sizeof(short));
00381 }
00382 else {
00383 status = s_pSecFn->QueryContextAttributes(&sspi_context,
00384 SECPKG_ATTR_SIZES,
00385 &sspi_sizes);
00386 if(check_sspi_err(conn, status, "QueryContextAttributes")) {
00387 s_pSecFn->DeleteSecurityContext(&sspi_context);
00388 failf(data, "Failed to query security context attributes.");
00389 return CURLE_COULDNT_CONNECT;
00390 }
00391
00392 sspi_w_token[0].cbBuffer = sspi_sizes.cbSecurityTrailer;
00393 sspi_w_token[0].BufferType = SECBUFFER_TOKEN;
00394 sspi_w_token[0].pvBuffer = malloc(sspi_sizes.cbSecurityTrailer);
00395
00396 if(!sspi_w_token[0].pvBuffer) {
00397 s_pSecFn->DeleteSecurityContext(&sspi_context);
00398 return CURLE_OUT_OF_MEMORY;
00399 }
00400
00401 sspi_w_token[1].cbBuffer = 1;
00402 sspi_w_token[1].pvBuffer = malloc(1);
00403 if(!sspi_w_token[1].pvBuffer) {
00404 s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
00405 s_pSecFn->DeleteSecurityContext(&sspi_context);
00406 return CURLE_OUT_OF_MEMORY;
00407 }
00408
00409 memcpy(sspi_w_token[1].pvBuffer, &gss_enc, 1);
00410 sspi_w_token[2].BufferType = SECBUFFER_PADDING;
00411 sspi_w_token[2].cbBuffer = sspi_sizes.cbBlockSize;
00412 sspi_w_token[2].pvBuffer = malloc(sspi_sizes.cbBlockSize);
00413 if(!sspi_w_token[2].pvBuffer) {
00414 s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
00415 s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer);
00416 s_pSecFn->DeleteSecurityContext(&sspi_context);
00417 return CURLE_OUT_OF_MEMORY;
00418 }
00419 status = s_pSecFn->EncryptMessage(&sspi_context,
00420 KERB_WRAP_NO_ENCRYPT,
00421 &wrap_desc,
00422 0);
00423 if(check_sspi_err(conn, status, "EncryptMessage")) {
00424 s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
00425 s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer);
00426 s_pSecFn->FreeContextBuffer(sspi_w_token[2].pvBuffer);
00427 s_pSecFn->DeleteSecurityContext(&sspi_context);
00428 failf(data, "Failed to query security context attributes.");
00429 return CURLE_COULDNT_CONNECT;
00430 }
00431 sspi_send_token.cbBuffer = sspi_w_token[0].cbBuffer
00432 + sspi_w_token[1].cbBuffer
00433 + sspi_w_token[2].cbBuffer;
00434 sspi_send_token.pvBuffer = malloc(sspi_send_token.cbBuffer);
00435 if(!sspi_send_token.pvBuffer) {
00436 s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
00437 s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer);
00438 s_pSecFn->FreeContextBuffer(sspi_w_token[2].pvBuffer);
00439 s_pSecFn->DeleteSecurityContext(&sspi_context);
00440 return CURLE_OUT_OF_MEMORY;
00441 }
00442
00443 memcpy(sspi_send_token.pvBuffer, sspi_w_token[0].pvBuffer,
00444 sspi_w_token[0].cbBuffer);
00445 memcpy((PUCHAR) sspi_send_token.pvBuffer +(int)sspi_w_token[0].cbBuffer,
00446 sspi_w_token[1].pvBuffer, sspi_w_token[1].cbBuffer);
00447 memcpy((PUCHAR) sspi_send_token.pvBuffer
00448 +sspi_w_token[0].cbBuffer
00449 +sspi_w_token[1].cbBuffer,
00450 sspi_w_token[2].pvBuffer, sspi_w_token[2].cbBuffer);
00451
00452 s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
00453 sspi_w_token[0].pvBuffer = NULL;
00454 sspi_w_token[0].cbBuffer = 0;
00455 s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer);
00456 sspi_w_token[1].pvBuffer = NULL;
00457 sspi_w_token[1].cbBuffer = 0;
00458 s_pSecFn->FreeContextBuffer(sspi_w_token[2].pvBuffer);
00459 sspi_w_token[2].pvBuffer = NULL;
00460 sspi_w_token[2].cbBuffer = 0;
00461
00462 us_length = htons((short)sspi_send_token.cbBuffer);
00463 memcpy(socksreq+2, &us_length, sizeof(short));
00464 }
00465
00466 code = Curl_write_plain(conn, sock, (char *)socksreq, 4, &written);
00467 if(code || (4 != written)) {
00468 failf(data, "Failed to send SSPI encryption request.");
00469 if(sspi_send_token.pvBuffer)
00470 s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer);
00471 s_pSecFn->DeleteSecurityContext(&sspi_context);
00472 return CURLE_COULDNT_CONNECT;
00473 }
00474
00475 if(data->set.socks5_gssapi_nec) {
00476 memcpy(socksreq, &gss_enc, 1);
00477 code = Curl_write_plain(conn, sock, (char *)socksreq, 1, &written);
00478 if(code || (1 != written)) {
00479 failf(data, "Failed to send SSPI encryption type.");
00480 s_pSecFn->DeleteSecurityContext(&sspi_context);
00481 return CURLE_COULDNT_CONNECT;
00482 }
00483 }
00484 else {
00485 code = Curl_write_plain(conn, sock, (char *)sspi_send_token.pvBuffer,
00486 sspi_send_token.cbBuffer, &written);
00487 if(code || (sspi_send_token.cbBuffer != (size_t)written)) {
00488 failf(data, "Failed to send SSPI encryption type.");
00489 if(sspi_send_token.pvBuffer)
00490 s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer);
00491 s_pSecFn->DeleteSecurityContext(&sspi_context);
00492 return CURLE_COULDNT_CONNECT;
00493 }
00494 if(sspi_send_token.pvBuffer)
00495 s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer);
00496 }
00497
00498 result = Curl_blockread_all(conn, sock, (char *)socksreq, 4, &actualread);
00499 if(result || (actualread != 4)) {
00500 failf(data, "Failed to receive SSPI encryption response.");
00501 s_pSecFn->DeleteSecurityContext(&sspi_context);
00502 return CURLE_COULDNT_CONNECT;
00503 }
00504
00505
00506 if(socksreq[1] == 255) {
00507 failf(data, "User was rejected by the SOCKS5 server (%u %u).",
00508 (unsigned int)socksreq[0], (unsigned int)socksreq[1]);
00509 s_pSecFn->DeleteSecurityContext(&sspi_context);
00510 return CURLE_COULDNT_CONNECT;
00511 }
00512
00513 if(socksreq[1] != 2) {
00514 failf(data, "Invalid SSPI encryption response type (%u %u).",
00515 (unsigned int)socksreq[0], (unsigned int)socksreq[1]);
00516 s_pSecFn->DeleteSecurityContext(&sspi_context);
00517 return CURLE_COULDNT_CONNECT;
00518 }
00519
00520 memcpy(&us_length, socksreq+2, sizeof(short));
00521 us_length = ntohs(us_length);
00522
00523 sspi_w_token[0].cbBuffer = us_length;
00524 sspi_w_token[0].pvBuffer = malloc(us_length);
00525 if(!sspi_w_token[0].pvBuffer) {
00526 s_pSecFn->DeleteSecurityContext(&sspi_context);
00527 return CURLE_OUT_OF_MEMORY;
00528 }
00529
00530 result = Curl_blockread_all(conn, sock, (char *)sspi_w_token[0].pvBuffer,
00531 sspi_w_token[0].cbBuffer, &actualread);
00532
00533 if(result || (actualread != us_length)) {
00534 failf(data, "Failed to receive SSPI encryption type.");
00535 s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
00536 s_pSecFn->DeleteSecurityContext(&sspi_context);
00537 return CURLE_COULDNT_CONNECT;
00538 }
00539
00540
00541 if(!data->set.socks5_gssapi_nec) {
00542 wrap_desc.cBuffers = 2;
00543 sspi_w_token[0].BufferType = SECBUFFER_STREAM;
00544 sspi_w_token[1].BufferType = SECBUFFER_DATA;
00545 sspi_w_token[1].cbBuffer = 0;
00546 sspi_w_token[1].pvBuffer = NULL;
00547
00548 status = s_pSecFn->DecryptMessage(&sspi_context,
00549 &wrap_desc,
00550 0,
00551 &qop);
00552
00553 if(check_sspi_err(conn, status, "DecryptMessage")) {
00554 if(sspi_w_token[0].pvBuffer)
00555 s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
00556 if(sspi_w_token[1].pvBuffer)
00557 s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer);
00558 s_pSecFn->DeleteSecurityContext(&sspi_context);
00559 failf(data, "Failed to query security context attributes.");
00560 return CURLE_COULDNT_CONNECT;
00561 }
00562
00563 if(sspi_w_token[1].cbBuffer != 1) {
00564 failf(data, "Invalid SSPI encryption response length (%lu).",
00565 (unsigned long)sspi_w_token[1].cbBuffer);
00566 if(sspi_w_token[0].pvBuffer)
00567 s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
00568 if(sspi_w_token[1].pvBuffer)
00569 s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer);
00570 s_pSecFn->DeleteSecurityContext(&sspi_context);
00571 return CURLE_COULDNT_CONNECT;
00572 }
00573
00574 memcpy(socksreq, sspi_w_token[1].pvBuffer, sspi_w_token[1].cbBuffer);
00575 s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
00576 s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer);
00577 }
00578 else {
00579 if(sspi_w_token[0].cbBuffer != 1) {
00580 failf(data, "Invalid SSPI encryption response length (%lu).",
00581 (unsigned long)sspi_w_token[0].cbBuffer);
00582 s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
00583 s_pSecFn->DeleteSecurityContext(&sspi_context);
00584 return CURLE_COULDNT_CONNECT;
00585 }
00586 memcpy(socksreq, sspi_w_token[0].pvBuffer, sspi_w_token[0].cbBuffer);
00587 s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
00588 }
00589
00590 infof(data, "SOCKS5 access with%s protection granted.\n",
00591 (socksreq[0]==0)?"out GSS-API data":
00592 ((socksreq[0]==1)?" GSS-API integrity":" GSS-API confidentiality"));
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603 return CURLE_OK;
00604 }
00605 #endif