1
/***************************************************************************
3
* Project ___| | | | _ \| |
5
* | (__| |_| | _ <| |___
6
* \___|\___/|_| \_\_____|
8
* Copyright (C) 2009, Markus Moeller, <markus_moeller@compuserve.com>
10
* This software is licensed as described in the file COPYING, which
11
* you should have received as part of this distribution. The terms
12
* are also available at http://curl.haxx.se/docs/copyright.html.
14
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
15
* copies of the Software, and permit persons to whom the Software is
16
* furnished to do so, under the terms of the COPYING file.
18
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19
* KIND, either express or implied.
21
* $Id: socks_sspi.c,v 1.6 2009-02-23 01:04:18 yangtse Exp $
22
***************************************************************************/
27
#ifdef USE_WINDOWS_SSPI
43
#include "curl_sspi.h"
45
#define _MPRINTF_REPLACE /* use the internal *printf() functions */
46
#include <curl/mprintf.h>
48
/* The last #include file should be: */
52
* Definitions required from ntsecapi.h are directly provided below this point
53
* to avoid including ntsecapi.h due to a conflict with OpenSSL's safestack.h
55
#define KERB_WRAP_NO_ENCRYPT 0x80000001
58
* Helper sspi error functions.
60
static int check_sspi_err(struct SessionHandle *data,
61
SECURITY_STATUS major_status,
62
SECURITY_STATUS minor_status,
68
if(major_status != SEC_E_OK &&
69
major_status != SEC_I_COMPLETE_AND_CONTINUE &&
70
major_status != SEC_I_COMPLETE_NEEDED &&
71
major_status != SEC_I_CONTINUE_NEEDED) {
72
failf(data, "SSPI error: %s failed: %d\n", function, major_status);
73
switch (major_status) {
74
case SEC_I_COMPLETE_AND_CONTINUE:
75
txt="SEC_I_COMPLETE_AND_CONTINUE";
77
case SEC_I_COMPLETE_NEEDED:
78
txt="SEC_I_COMPLETE_NEEDED";
80
case SEC_I_CONTINUE_NEEDED:
81
txt="SEC_I_CONTINUE_NEEDED";
83
case SEC_I_CONTEXT_EXPIRED:
84
txt="SEC_I_CONTEXT_EXPIRED";
86
case SEC_I_INCOMPLETE_CREDENTIALS:
87
txt="SEC_I_INCOMPLETE_CREDENTIALS";
89
case SEC_I_RENEGOTIATE:
90
txt="SEC_I_RENEGOTIATE";
92
case SEC_E_BUFFER_TOO_SMALL:
93
txt="SEC_E_BUFFER_TOO_SMALL";
95
case SEC_E_CONTEXT_EXPIRED:
96
txt="SEC_E_CONTEXT_EXPIRED";
98
case SEC_E_CRYPTO_SYSTEM_INVALID:
99
txt="SEC_E_CRYPTO_SYSTEM_INVALID";
101
case SEC_E_INCOMPLETE_MESSAGE:
102
txt="SEC_E_INCOMPLETE_MESSAGE";
104
case SEC_E_INSUFFICIENT_MEMORY:
105
txt="SEC_E_INSUFFICIENT_MEMORY";
107
case SEC_E_INTERNAL_ERROR:
108
txt="SEC_E_INTERNAL_ERROR";
110
case SEC_E_INVALID_HANDLE:
111
txt="SEC_E_INVALID_HANDLE";
113
case SEC_E_INVALID_TOKEN:
114
txt="SEC_E_INVALID_TOKEN";
116
case SEC_E_LOGON_DENIED:
117
txt="SEC_E_LOGON_DENIED";
119
case SEC_E_MESSAGE_ALTERED:
120
txt="SEC_E_MESSAGE_ALTERED";
122
case SEC_E_NO_AUTHENTICATING_AUTHORITY:
123
txt="SEC_E_NO_AUTHENTICATING_AUTHORITY";
125
case SEC_E_NO_CREDENTIALS:
126
txt="SEC_E_NO_CREDENTIALS";
128
case SEC_E_NOT_OWNER:
129
txt="SEC_E_NOT_OWNER";
131
case SEC_E_OUT_OF_SEQUENCE:
132
txt="SEC_E_OUT_OF_SEQUENCE";
134
case SEC_E_QOP_NOT_SUPPORTED:
135
txt="SEC_E_QOP_NOT_SUPPORTED";
137
case SEC_E_SECPKG_NOT_FOUND:
138
txt="SEC_E_SECPKG_NOT_FOUND";
140
case SEC_E_TARGET_UNKNOWN:
141
txt="SEC_E_TARGET_UNKNOWN";
143
case SEC_E_UNKNOWN_CREDENTIALS:
144
txt="SEC_E_UNKNOWN_CREDENTIALS";
146
case SEC_E_UNSUPPORTED_FUNCTION:
147
txt="SEC_E_UNSUPPORTED_FUNCTION";
149
case SEC_E_WRONG_PRINCIPAL:
150
txt="SEC_E_WRONG_PRINCIPAL";
156
failf(data, "SSPI error: %s failed: %s\n", function, txt);
162
/* This is the SSPI-using version of this function */
163
CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
164
struct connectdata *conn)
166
struct SessionHandle *data = conn->data;
167
curl_socket_t sock = conn->sock[sockindex];
173
/* Needs GSSAPI authentication */
174
SECURITY_STATUS sspi_major_status, sspi_minor_status=0;
175
unsigned long sspi_ret_flags=0;
177
SecBuffer sspi_send_token, sspi_recv_token, sspi_w_token[3];
178
SecBufferDesc input_desc, output_desc, wrap_desc;
179
SecPkgContext_Sizes sspi_sizes;
180
CredHandle cred_handle;
181
CtxtHandle sspi_context;
182
PCtxtHandle context_handle = NULL;
183
SecPkgCredentials_Names names;
185
char *service_name=NULL;
188
unsigned char socksreq[4]; /* room for gssapi exchange header only */
189
char *service = data->set.str[STRING_SOCKS5_GSSAPI_SERVICE];
192
timeout = Curl_timeleft(conn, NULL, TRUE);
194
/* GSSAPI request looks like
195
* +----+------+-----+----------------+
196
* |VER | MTYP | LEN | TOKEN |
197
* +----+------+----------------------+
198
* | 1 | 1 | 2 | up to 2^16 - 1 |
199
* +----+------+-----+----------------+
202
/* prepare service name */
203
if (strchr(service, '/')) {
204
service_name = malloc(strlen(service));
206
return CURLE_OUT_OF_MEMORY;
207
memcpy(service_name, service, strlen(service));
210
service_name = malloc(strlen(service) + strlen(conn->proxy.name) + 2);
212
return CURLE_OUT_OF_MEMORY;
213
snprintf(service_name,strlen(service) +strlen(conn->proxy.name)+2,"%s/%s",
214
service,conn->proxy.name);
217
input_desc.cBuffers = 1;
218
input_desc.pBuffers = &sspi_recv_token;
219
input_desc.ulVersion = SECBUFFER_VERSION;
221
sspi_recv_token.BufferType = SECBUFFER_TOKEN;
222
sspi_recv_token.cbBuffer = 0;
223
sspi_recv_token.pvBuffer = NULL;
225
output_desc.cBuffers = 1;
226
output_desc.pBuffers = &sspi_send_token;
227
output_desc.ulVersion = SECBUFFER_VERSION;
229
sspi_send_token.BufferType = SECBUFFER_TOKEN;
230
sspi_send_token.cbBuffer = 0;
231
sspi_send_token.pvBuffer = NULL;
233
wrap_desc.cBuffers = 3;
234
wrap_desc.pBuffers = sspi_w_token;
235
wrap_desc.ulVersion = SECBUFFER_VERSION;
237
cred_handle.dwLower = 0;
238
cred_handle.dwUpper = 0;
240
sspi_major_status = s_pSecFn->AcquireCredentialsHandleA( NULL,
242
SECPKG_CRED_OUTBOUND,
250
if(check_sspi_err(data, sspi_major_status,sspi_minor_status,
251
"AcquireCredentialsHandleA") ) {
252
failf(data, "Failed to acquire credentials.");
255
s_pSecFn->FreeCredentialsHandle(&cred_handle);
256
return CURLE_COULDNT_CONNECT;
259
/* As long as we need to keep sending some context info, and there's no */
260
/* errors, keep sending it... */
263
sspi_major_status = s_pSecFn->InitializeSecurityContextA(
267
ISC_REQ_MUTUAL_AUTH |
268
ISC_REQ_ALLOCATE_MEMORY |
269
ISC_REQ_CONFIDENTIALITY |
270
ISC_REQ_REPLAY_DETECT,
272
SECURITY_NATIVE_DREP,
280
if(sspi_recv_token.pvBuffer) {
281
s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer);
282
sspi_recv_token.pvBuffer = NULL;
283
sspi_recv_token.cbBuffer = 0;
286
if(check_sspi_err(data,sspi_major_status,sspi_minor_status,
287
"InitializeSecurityContextA") ){
290
s_pSecFn->FreeCredentialsHandle(&cred_handle);
291
s_pSecFn->DeleteSecurityContext(&sspi_context);
292
s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer);
293
failf(data, "Failed to initialise security context.");
294
return CURLE_COULDNT_CONNECT;
297
if(sspi_send_token.cbBuffer != 0) {
298
socksreq[0] = 1; /* gssapi subnegotiation version */
299
socksreq[1] = 1; /* authentication message type */
300
us_length = htons((short)sspi_send_token.cbBuffer);
301
memcpy(socksreq+2, &us_length, sizeof(short));
303
code = Curl_write_plain(conn, sock, (char *)socksreq, 4, &written);
304
if((code != CURLE_OK) || (4 != written)) {
305
failf(data, "Failed to send SSPI authentication request.");
308
s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer);
309
s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer);
310
s_pSecFn->FreeCredentialsHandle(&cred_handle);
311
s_pSecFn->DeleteSecurityContext(&sspi_context);
312
return CURLE_COULDNT_CONNECT;
315
code = Curl_write_plain(conn, sock, (char *)sspi_send_token.pvBuffer,
316
sspi_send_token.cbBuffer, &written);
317
if((code != CURLE_OK) || (sspi_send_token.cbBuffer != (size_t)written)) {
318
failf(data, "Failed to send SSPI authentication token.");
321
s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer);
322
s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer);
323
s_pSecFn->FreeCredentialsHandle(&cred_handle);
324
s_pSecFn->DeleteSecurityContext(&sspi_context);
325
return CURLE_COULDNT_CONNECT;
330
s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer);
331
sspi_send_token.pvBuffer = NULL;
332
sspi_send_token.cbBuffer = 0;
333
s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer);
334
sspi_recv_token.pvBuffer = NULL;
335
sspi_recv_token.cbBuffer = 0;
336
if(sspi_major_status != SEC_I_CONTINUE_NEEDED) break;
338
/* analyse response */
340
/* GSSAPI response looks like
341
* +----+------+-----+----------------+
342
* |VER | MTYP | LEN | TOKEN |
343
* +----+------+----------------------+
344
* | 1 | 1 | 2 | up to 2^16 - 1 |
345
* +----+------+-----+----------------+
348
result=Curl_blockread_all(conn, sock, (char *)socksreq, 4,
349
&actualread, timeout);
350
if(result != CURLE_OK || actualread != 4) {
351
failf(data, "Failed to receive SSPI authentication response.");
354
s_pSecFn->FreeCredentialsHandle(&cred_handle);
355
s_pSecFn->DeleteSecurityContext(&sspi_context);
356
return CURLE_COULDNT_CONNECT;
359
/* ignore the first (VER) byte */
360
if(socksreq[1] == 255) { /* status / message type */
361
failf(data, "User was rejected by the SOCKS5 server (%d %d).",
362
socksreq[0], socksreq[1]);
365
s_pSecFn->FreeCredentialsHandle(&cred_handle);
366
s_pSecFn->DeleteSecurityContext(&sspi_context);
367
return CURLE_COULDNT_CONNECT;
370
if(socksreq[1] != 1) { /* status / messgae type */
371
failf(data, "Invalid SSPI authentication response type (%d %d).",
372
socksreq[0], socksreq[1]);
375
s_pSecFn->FreeCredentialsHandle(&cred_handle);
376
s_pSecFn->DeleteSecurityContext(&sspi_context);
377
return CURLE_COULDNT_CONNECT;
380
memcpy(&us_length, socksreq+2, sizeof(short));
381
us_length = ntohs(us_length);
383
sspi_recv_token.cbBuffer = us_length;
384
sspi_recv_token.pvBuffer = malloc(us_length);
386
if(!sspi_recv_token.pvBuffer) {
389
s_pSecFn->FreeCredentialsHandle(&cred_handle);
390
s_pSecFn->DeleteSecurityContext(&sspi_context);
391
return CURLE_OUT_OF_MEMORY;
393
result = Curl_blockread_all(conn, sock, (char *)sspi_recv_token.pvBuffer,
394
sspi_recv_token.cbBuffer,
395
&actualread, timeout);
397
if(result != CURLE_OK || actualread != us_length) {
398
failf(data, "Failed to receive SSPI authentication token.");
401
s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer);
402
s_pSecFn->FreeCredentialsHandle(&cred_handle);
403
s_pSecFn->DeleteSecurityContext(&sspi_context);
404
return CURLE_COULDNT_CONNECT;
407
context_handle = &sspi_context;
413
/* Everything is good so far, user was authenticated! */
414
sspi_major_status = s_pSecFn->QueryCredentialsAttributes( &cred_handle,
415
SECPKG_CRED_ATTR_NAMES,
417
s_pSecFn->FreeCredentialsHandle(&cred_handle);
418
if(check_sspi_err(data,sspi_major_status,sspi_minor_status,
419
"QueryCredentialAttributes") ){
420
s_pSecFn->DeleteSecurityContext(&sspi_context);
421
s_pSecFn->FreeContextBuffer(names.sUserName);
422
failf(data, "Failed to determine user name.");
423
return CURLE_COULDNT_CONNECT;
425
infof(data, "SOCKS5 server authencticated user %s with gssapi.\n",
427
s_pSecFn->FreeContextBuffer(names.sUserName);
430
socksreq[0] = 1; /* gssapi subnegotiation version */
431
socksreq[1] = 2; /* encryption message type */
433
gss_enc = 0; /* no data protection */
434
/* do confidentiality protection if supported */
435
if(sspi_ret_flags & ISC_REQ_CONFIDENTIALITY)
437
/* else do integrity protection */
438
else if(sspi_ret_flags & ISC_REQ_INTEGRITY)
441
infof(data, "SOCKS5 server supports gssapi %s data protection.\n",
442
(gss_enc==0)?"no":((gss_enc==1)?"integrity":"confidentiality") );
443
/* force to no data protection, avoid encryption/decryption for now */
446
* Sending the encryption type in clear seems wrong. It should be
447
* protected with gss_seal()/gss_wrap(). See RFC1961 extract below
448
* The NEC reference implementations on which this is based is
451
* +------+------+------+.......................+
452
* + ver | mtyp | len | token |
453
* +------+------+------+.......................+
454
* + 0x01 | 0x02 | 0x02 | up to 2^16 - 1 octets |
455
* +------+------+------+.......................+
459
* - "ver" is the protocol version number, here 1 to represent the
460
* first version of the SOCKS/GSS-API protocol
462
* - "mtyp" is the message type, here 2 to represent a protection
463
* -level negotiation message
465
* - "len" is the length of the "token" field in octets
467
* - "token" is the GSS-API encapsulated protection level
469
* The token is produced by encapsulating an octet containing the
470
* required protection level using gss_seal()/gss_wrap() with conf_req
471
* set to FALSE. The token is verified using gss_unseal()/
476
if(data->set.socks5_gssapi_nec) {
477
us_length = htons((short)1);
478
memcpy(socksreq+2, &us_length, sizeof(short));
481
sspi_major_status = s_pSecFn->QueryContextAttributesA( &sspi_context,
484
if(check_sspi_err(data,sspi_major_status,sspi_minor_status,
485
"QueryContextAttributesA")) {
486
s_pSecFn->DeleteSecurityContext(&sspi_context);
487
failf(data, "Failed to query security context attributes.");
488
return CURLE_COULDNT_CONNECT;
491
sspi_w_token[0].cbBuffer = sspi_sizes.cbSecurityTrailer;
492
sspi_w_token[0].BufferType = SECBUFFER_TOKEN;
493
sspi_w_token[0].pvBuffer = malloc(sspi_sizes.cbSecurityTrailer);
495
if(!sspi_w_token[0].pvBuffer) {
496
s_pSecFn->DeleteSecurityContext(&sspi_context);
497
return CURLE_OUT_OF_MEMORY;
500
sspi_w_token[1].cbBuffer = 1;
501
sspi_w_token[1].pvBuffer = malloc(1);
502
if(!sspi_w_token[1].pvBuffer){
503
s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
504
s_pSecFn->DeleteSecurityContext(&sspi_context);
505
return CURLE_OUT_OF_MEMORY;
508
memcpy(sspi_w_token[1].pvBuffer,&gss_enc,1);
509
sspi_w_token[2].BufferType = SECBUFFER_PADDING;
510
sspi_w_token[2].cbBuffer = sspi_sizes.cbBlockSize;
511
sspi_w_token[2].pvBuffer = malloc(sspi_sizes.cbBlockSize);
512
if(!sspi_w_token[2].pvBuffer) {
513
s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
514
s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer);
515
s_pSecFn->DeleteSecurityContext(&sspi_context);
516
return CURLE_OUT_OF_MEMORY;
518
sspi_major_status = s_pSecFn->EncryptMessage( &sspi_context,
519
KERB_WRAP_NO_ENCRYPT,
522
if(check_sspi_err(data,sspi_major_status,sspi_minor_status,
523
"EncryptMessage") ) {
524
s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
525
s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer);
526
s_pSecFn->FreeContextBuffer(sspi_w_token[2].pvBuffer);
527
s_pSecFn->DeleteSecurityContext(&sspi_context);
528
failf(data, "Failed to query security context attributes.");
529
return CURLE_COULDNT_CONNECT;
531
sspi_send_token.cbBuffer = sspi_w_token[0].cbBuffer
532
+ sspi_w_token[1].cbBuffer
533
+ sspi_w_token[2].cbBuffer;
534
sspi_send_token.pvBuffer = malloc(sspi_send_token.cbBuffer);
535
if(!sspi_send_token.pvBuffer) {
536
s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
537
s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer);
538
s_pSecFn->FreeContextBuffer(sspi_w_token[2].pvBuffer);
539
s_pSecFn->DeleteSecurityContext(&sspi_context);
540
return CURLE_OUT_OF_MEMORY;
543
memcpy(sspi_send_token.pvBuffer, sspi_w_token[0].pvBuffer,
544
sspi_w_token[0].cbBuffer);
545
memcpy((PUCHAR) sspi_send_token.pvBuffer +(int)sspi_w_token[0].cbBuffer,
546
sspi_w_token[1].pvBuffer, sspi_w_token[1].cbBuffer);
547
memcpy((PUCHAR) sspi_send_token.pvBuffer
548
+sspi_w_token[0].cbBuffer
549
+sspi_w_token[1].cbBuffer,
550
sspi_w_token[2].pvBuffer, sspi_w_token[2].cbBuffer);
552
s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
553
sspi_w_token[0].pvBuffer = NULL;
554
sspi_w_token[0].cbBuffer = 0;
555
s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer);
556
sspi_w_token[1].pvBuffer = NULL;
557
sspi_w_token[1].cbBuffer = 0;
558
s_pSecFn->FreeContextBuffer(sspi_w_token[2].pvBuffer);
559
sspi_w_token[2].pvBuffer = NULL;
560
sspi_w_token[2].cbBuffer = 0;
562
us_length = htons((short)sspi_send_token.cbBuffer);
563
memcpy(socksreq+2,&us_length,sizeof(short));
566
code = Curl_write_plain(conn, sock, (char *)socksreq, 4, &written);
567
if((code != CURLE_OK) || (4 != written)) {
568
failf(data, "Failed to send SSPI encryption request.");
569
s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer);
570
s_pSecFn->DeleteSecurityContext(&sspi_context);
571
return CURLE_COULDNT_CONNECT;
574
if(data->set.socks5_gssapi_nec) {
575
memcpy(socksreq,&gss_enc,1);
576
code = Curl_write_plain(conn, sock, (char *)socksreq, 1, &written);
577
if((code != CURLE_OK) || (1 != written)) {
578
failf(data, "Failed to send SSPI encryption type.");
579
s_pSecFn->DeleteSecurityContext(&sspi_context);
580
return CURLE_COULDNT_CONNECT;
583
code = Curl_write_plain(conn, sock, (char *)sspi_send_token.pvBuffer,
584
sspi_send_token.cbBuffer, &written);
585
if((code != CURLE_OK) || (sspi_send_token.cbBuffer != (size_t)written)) {
586
failf(data, "Failed to send SSPI encryption type.");
587
s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer);
588
s_pSecFn->DeleteSecurityContext(&sspi_context);
589
return CURLE_COULDNT_CONNECT;
591
s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer);
594
result=Curl_blockread_all(conn, sock, (char *)socksreq, 4,
595
&actualread, timeout);
596
if(result != CURLE_OK || actualread != 4) {
597
failf(data, "Failed to receive SSPI encryption response.");
598
s_pSecFn->DeleteSecurityContext(&sspi_context);
599
return CURLE_COULDNT_CONNECT;
602
/* ignore the first (VER) byte */
603
if(socksreq[1] == 255) { /* status / message type */
604
failf(data, "User was rejected by the SOCKS5 server (%d %d).",
605
socksreq[0], socksreq[1]);
606
s_pSecFn->DeleteSecurityContext(&sspi_context);
607
return CURLE_COULDNT_CONNECT;
610
if(socksreq[1] != 2) { /* status / message type */
611
failf(data, "Invalid SSPI encryption response type (%d %d).",
612
socksreq[0], socksreq[1]);
613
s_pSecFn->DeleteSecurityContext(&sspi_context);
614
return CURLE_COULDNT_CONNECT;
617
memcpy(&us_length, socksreq+2, sizeof(short));
618
us_length = ntohs(us_length);
620
sspi_w_token[0].cbBuffer = us_length;
621
sspi_w_token[0].pvBuffer = malloc(us_length);
622
if(!sspi_w_token[0].pvBuffer) {
623
s_pSecFn->DeleteSecurityContext(&sspi_context);
624
return CURLE_OUT_OF_MEMORY;
627
result=Curl_blockread_all(conn, sock, (char *)sspi_w_token[0].pvBuffer,
628
sspi_w_token[0].cbBuffer,
629
&actualread, timeout);
631
if(result != CURLE_OK || actualread != us_length) {
632
failf(data, "Failed to receive SSPI encryption type.");
633
s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
634
s_pSecFn->DeleteSecurityContext(&sspi_context);
635
return CURLE_COULDNT_CONNECT;
639
if(!data->set.socks5_gssapi_nec) {
640
wrap_desc.cBuffers = 2;
641
sspi_w_token[0].BufferType = SECBUFFER_STREAM;
642
sspi_w_token[1].BufferType = SECBUFFER_DATA;
643
sspi_w_token[1].cbBuffer = 0;
644
sspi_w_token[1].pvBuffer = NULL;
646
sspi_major_status = s_pSecFn->DecryptMessage( &sspi_context,
651
if(check_sspi_err(data,sspi_major_status,sspi_minor_status,
653
s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
654
s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer);
655
s_pSecFn->DeleteSecurityContext(&sspi_context);
656
failf(data, "Failed to query security context attributes.");
657
return CURLE_COULDNT_CONNECT;
660
if(sspi_w_token[1].cbBuffer != 1) {
661
failf(data, "Invalid SSPI encryption response length (%d).",
662
sspi_w_token[1].cbBuffer);
663
s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
664
s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer);
665
s_pSecFn->DeleteSecurityContext(&sspi_context);
666
return CURLE_COULDNT_CONNECT;
669
memcpy(socksreq,sspi_w_token[1].pvBuffer,sspi_w_token[1].cbBuffer);
670
s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
671
s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer);
673
if(sspi_w_token[0].cbBuffer != 1) {
674
failf(data, "Invalid SSPI encryption response length (%d).",
675
sspi_w_token[0].cbBuffer);
676
s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
677
s_pSecFn->DeleteSecurityContext(&sspi_context);
678
return CURLE_COULDNT_CONNECT;
680
memcpy(socksreq,sspi_w_token[0].pvBuffer,sspi_w_token[0].cbBuffer);
681
s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer);
684
infof(data, "SOCKS5 access with%s protection granted.\n",
685
(socksreq[0]==0)?"out gssapi data":
686
((socksreq[0]==1)?" gssapi integrity":" gssapi confidentiality"));
688
/* For later use if encryption is required
689
conn->socks5_gssapi_enctype = socksreq[0];
690
if (socksreq[0] != 0)
691
conn->socks5_sspi_context = sspi_context;
693
s_pSecFn->DeleteSecurityContext(&sspi_context);
694
conn->socks5_sspi_context = sspi_context;