26 #if defined(HAVE_GSSAPI) && !defined(CURL_DISABLE_PROXY) 65 &msg_ctx, &status_string);
67 if(
sizeof(buf) > len + status_string.
length + 1) {
68 strcpy(buf + len, (
char *) status_string.
value);
69 len += status_string.
length;
76 if(
sizeof(buf) > len + 3) {
77 strcpy(buf + len,
".\n");
86 &msg_ctx, &status_string);
88 if(
sizeof(buf) > len + status_string.
length)
89 strcpy(buf + len, (
char *) status_string.
value);
95 failf(data,
"GSS-API error: %s failed:\n%s",
function, buf);
102 CURLcode Curl_SOCKS5_gssapi_negotiate(
int sockindex,
111 OM_uint32 gss_major_status, gss_minor_status, gss_status;
113 int gss_conf_state, gss_enc;
121 unsigned short us_length;
123 unsigned char socksreq[4];
124 const char *serviceptr = data->
set.
str[STRING_PROXY_SERVICE_NAME] ?
125 data->
set.
str[STRING_PROXY_SERVICE_NAME] :
"rcmd";
126 const size_t serviceptr_length = strlen(serviceptr);
137 if(strchr(serviceptr,
'/')) {
138 service.
length = serviceptr_length;
152 service.
length = serviceptr_length +
163 if(check_gss_err(data, gss_major_status,
164 gss_minor_status,
"gss_import_name()")) {
165 failf(data,
"Failed to create service name.");
173 gss_major_status = Curl_gss_init_sec_context(data,
186 if(check_gss_err(data, gss_major_status,
187 gss_minor_status,
"gss_init_sec_context")) {
192 failf(data,
"Failed to initial GSS-API token.");
196 if(gss_send_token.
length != 0) {
199 us_length = htons((
short)gss_send_token.
length);
200 memcpy(socksreq + 2, &us_length,
sizeof(
short));
203 if(code || (4 != written)) {
204 failf(data,
"Failed to send GSS-API authentication request.");
213 gss_send_token.
length, &written);
216 failf(data,
"Failed to send GSS-API authentication token.");
241 if(result || (actualread != 4)) {
242 failf(data,
"Failed to receive GSS-API authentication response.");
249 if(socksreq[1] == 255) {
250 failf(data,
"User was rejected by the SOCKS5 server (%d %d).",
251 socksreq[0], socksreq[1]);
257 if(socksreq[1] != 1) {
258 failf(data,
"Invalid GSS-API authentication response type (%d %d).",
259 socksreq[0], socksreq[1]);
265 memcpy(&us_length, socksreq + 2,
sizeof(
short));
266 us_length = ntohs(us_length);
268 gss_recv_token.
length = us_length;
270 if(!gss_recv_token.
value) {
272 "Could not allocate memory for GSS-API authentication " 280 gss_recv_token.
length, &actualread);
282 if(result || (actualread != us_length)) {
283 failf(data,
"Failed to receive GSS-API authentication token.");
290 gss_token = &gss_recv_token;
297 &gss_client_name, NULL, NULL, NULL,
299 if(check_gss_err(data, gss_major_status,
300 gss_minor_status,
"gss_inquire_context")) {
303 failf(data,
"Failed to determine user name.");
307 &gss_send_token, NULL);
308 if(check_gss_err(data, gss_major_status,
309 gss_minor_status,
"gss_display_name")) {
313 failf(data,
"Failed to determine user name.");
325 user[gss_send_token.
length] =
'\0';
328 infof(data,
"SOCKS5 server authencticated user %s with GSS-API.\n",user);
344 infof(data,
"SOCKS5 server supports GSS-API %s data protection.\n",
345 (gss_enc == 0)?
"no":((gss_enc==1)?
"integrity":
"confidentiality"));
378 if(data->
set.socks5_gssapi_nec) {
379 us_length = htons((
short)1);
380 memcpy(socksreq + 2, &us_length,
sizeof(
short));
383 gss_send_token.
length = 1;
385 if(!gss_send_token.
value) {
391 gss_major_status =
gss_wrap(&gss_minor_status, gss_context, 0,
393 &gss_conf_state, &gss_w_token);
395 if(check_gss_err(data, gss_major_status, gss_minor_status,
"gss_wrap")) {
399 failf(data,
"Failed to wrap GSS-API encryption value into token.");
404 us_length = htons((
short)gss_w_token.
length);
405 memcpy(socksreq + 2, &us_length,
sizeof(
short));
409 if(code || (4 != written)) {
410 failf(data,
"Failed to send GSS-API encryption request.");
416 if(data->
set.socks5_gssapi_nec) {
417 memcpy(socksreq, &gss_enc, 1);
419 if(code || ( 1 != written)) {
420 failf(data,
"Failed to send GSS-API encryption type.");
427 gss_w_token.
length, &written);
429 failf(data,
"Failed to send GSS-API encryption type.");
438 if(result || (actualread != 4)) {
439 failf(data,
"Failed to receive GSS-API encryption response.");
445 if(socksreq[1] == 255) {
446 failf(data,
"User was rejected by the SOCKS5 server (%d %d).",
447 socksreq[0], socksreq[1]);
452 if(socksreq[1] != 2) {
453 failf(data,
"Invalid GSS-API encryption response type (%d %d).",
454 socksreq[0], socksreq[1]);
459 memcpy(&us_length, socksreq + 2,
sizeof(
short));
460 us_length = ntohs(us_length);
462 gss_recv_token.
length = us_length;
464 if(!gss_recv_token.
value) {
469 gss_recv_token.
length, &actualread);
471 if(result || (actualread != us_length)) {
472 failf(data,
"Failed to receive GSS-API encryptrion type.");
478 if(!data->
set.socks5_gssapi_nec) {
479 gss_major_status =
gss_unwrap(&gss_minor_status, gss_context,
480 &gss_recv_token, &gss_w_token,
483 if(check_gss_err(data, gss_major_status, gss_minor_status,
"gss_unwrap")) {
487 failf(data,
"Failed to unwrap GSS-API encryption value into token.");
492 if(gss_w_token.
length != 1) {
493 failf(data,
"Invalid GSS-API encryption response length (%d).",
504 if(gss_recv_token.
length != 1) {
505 failf(data,
"Invalid GSS-API encryption response length (%d).",
516 infof(data,
"SOCKS5 access with%s protection granted.\n",
517 (socksreq[0] == 0)?
"out GSS-API data":
518 ((socksreq[0] == 1)?
" GSS-API integrity":
" GSS-API confidentiality"));
520 conn->socks5_gssapi_enctype = socksreq[0];
OM_uint32 gss_release_buffer(OM_uint32 *min, gss_buffer_t buffer)
#define GSS_S_CONTINUE_NEEDED
CURLcode Curl_write_plain(struct connectdata *conn, curl_socket_t sockfd, const void *mem, size_t len, ssize_t *written)
OM_uint32 gss_display_name(OM_uint32 *min, gss_const_name_t input_name, gss_buffer_t output_name_buffer, gss_OID *output_name_type)
struct gss_name_t_desc_struct * gss_name_t
UNITTEST_START int result
#define GSS_C_NT_HOSTBASED_SERVICE
memcpy(filename, filename1, strlen(filename1))
static struct mg_server * server
#define GSS_ERROR(status)
struct proxy_info socks_proxy
OM_uint32 gss_release_name(OM_uint32 *min, gss_name_t *input_name)
int Curl_blockread_all(struct connectdata *conn, curl_socket_t sockfd, char *buf, ssize_t buffersize, ssize_t *n)
#define gss_delete_sec_context
OM_uint32 gss_unwrap(OM_uint32 *min, gss_const_ctx_id_t context_handle, const gss_buffer_t input_message_buffer, gss_buffer_t output_message_buffer, int *conf_state, gss_qop_t *qop_state)
OM_uint32 gss_inquire_context(OM_uint32 *min, gss_const_ctx_id_t context_handle, gss_name_t *src_name, gss_name_t *targ_name, OM_uint32 *lifetime_rec, gss_OID *mech_type, OM_uint32 *ctx_flags, int *locally_initiated, int *open_context)
#define GSS_C_EMPTY_BUFFER
#define gss_display_status
OM_uint32 gss_wrap(OM_uint32 *min, gss_const_ctx_id_t context_handle, int conf_req_flag, gss_qop_t qop_req, const gss_buffer_t input_message_buffer, int *conf_state, gss_buffer_t output_message_buffer)
#define GSS_C_QOP_DEFAULT