diff -ruN curl-7.19.0/include/curl/curl.h curl-7.19.0-new/include/curl/curl.h
--- curl-7.19.0/include/curl/curl.h	2008-08-19 20:02:45.000000000 +0100
+++ curl-7.19.0-new/include/curl/curl.h	2008-09-14 11:43:18.000000000 +0100
@@ -1135,6 +1135,9 @@
   /* (IPv6) Address scope */
   CINIT(ADDRESS_SCOPE, LONG, 171),
 
+  /* (IPv6) Address scope */
+  CINIT(SOCKS5_GSSAPI_SERVICE, OBJECTPOINT, 172),
+
   CURLOPT_LASTENTRY /* the last unused */
 } CURLoption;
 
diff -ruN curl-7.19.0/lib/socks.c curl-7.19.0-new/lib/socks.c
--- curl-7.19.0/lib/socks.c	2008-06-20 11:43:32.000000000 +0100
+++ curl-7.19.0-new/lib/socks.c	2008-09-14 11:53:14.000000000 +0100
@@ -52,6 +52,124 @@
 /* The last #include file should be: */
 #include "memdebug.h"
 
+#ifdef HAVE_GSSAPI
+/*
+ * Helper gssapi error functions. 
+ */
+int check_gss_err(struct SessionHandle *data,OM_uint32 major_status, OM_uint32 minor_status, const char* function){
+    if (GSS_ERROR(major_status)) {
+        OM_uint32 maj_stat,min_stat;
+        OM_uint32 msg_ctx = 0;
+        gss_buffer_desc status_string;
+        char buf[1024];
+        size_t len;
+
+        len = 0;
+        msg_ctx = 0;
+        while (!msg_ctx) {
+            /* convert major status code (GSS-API error) to text */
+            maj_stat = gss_display_status(&min_stat, major_status,
+                                          GSS_C_GSS_CODE,
+                                          GSS_C_NULL_OID,
+                                          &msg_ctx, &status_string);
+            if (maj_stat == GSS_S_COMPLETE) {
+                if (sizeof(buf) > len + status_string.length + 1) {
+                    sprintf(buf+len, "%s", (char*) status_string.value);
+                    len += status_string.length;
+                }
+                gss_release_buffer(&min_stat, &status_string);
+                break;
+            }
+            gss_release_buffer(&min_stat, &status_string);
+        }
+        if (sizeof(buf) > len + 2) {
+            sprintf(buf+len, "%s", ".\n");
+            len += 2;
+        }
+        msg_ctx = 0;
+        while (!msg_ctx) {
+            /* convert minor status code (underlying routine error) to text */
+            maj_stat = gss_display_status(&min_stat, minor_status,
+                                          GSS_C_MECH_CODE,
+                                          GSS_C_NULL_OID,
+                                          &msg_ctx, &status_string);
+            if (maj_stat == GSS_S_COMPLETE) {
+                if (sizeof(buf) > len + status_string.length ) {
+                    sprintf(buf+len, "%s", (char*) status_string.value);
+                    len += status_string.length;
+                }
+                gss_release_buffer(&min_stat, &status_string);
+                break;
+            }
+            gss_release_buffer(&min_stat, &status_string);
+        }
+        failf(data, "GSSAPI error: %s failed:\n%s\n", function, buf);
+        return(1);
+    }
+
+    return(0);
+}
+#endif
+#ifdef USE_WINDOWS_SSPI
+/*
+ * Helper sspi error functions. 
+ */
+typedef long OM_uint32;
+int check_sspi_err(struct SessionHandle *data,OM_uint32 major_status, OM_uint32 minor_status, const char* function) {
+    if (major_status != SEC_E_OK && major_status != SEC_I_COMPLETE_AND_CONTINUE &&
+        major_status != SEC_I_COMPLETE_NEEDED && major_status != SEC_I_CONTINUE_NEEDED ){
+        failf(data, "SSPI error: %s failed: %d\n", function, major_status);
+        switch (major_status) {
+            case SEC_I_COMPLETE_AND_CONTINUE:
+                failf(data, "SSPI error: %s failed: %s\n",  function, "SEC_I_COMPLETE_AND_CONTINUE");
+                break;
+            case SEC_I_COMPLETE_NEEDED:
+                failf(data, "SSPI error: %s failed: %s\n",  function, "SEC_I_COMPLETE_NEEDED");
+                break;
+            case SEC_I_CONTINUE_NEEDED:
+                failf(data, "SSPI error: %s failed: %s\n",  function, "SEC_I_CONTINUE_NEEDED");
+                break;
+            case SEC_I_INCOMPLETE_CREDENTIALS:
+                failf(data, "SSPI error: %s failed: %s\n",  function, "SEC_I_INCOMPLETE_CREDENTIALS");
+                break;
+            case SEC_E_INSUFFICIENT_MEMORY:
+                failf(data, "SSPI error: %s failed: %s\n",  function, "SEC_E_INSUFFICIENT_MEMORY");
+                break;
+            case SEC_E_INTERNAL_ERROR:
+                failf(data, "SSPI error: %s failed: %s\n",  function, "SEC_E_INTERNAL_ERROR");
+                break;
+            case SEC_E_INVALID_HANDLE:
+                failf(data, "SSPI error: %s failed: %s\n",  function, "SEC_E_INVALID_HANDLE");
+                break;
+            case SEC_E_INVALID_TOKEN:
+                failf(data, "SSPI error: %s failed: %s\n",  function, "SEC_E_INVALID_TOKEN");
+                break;
+            case SEC_E_LOGON_DENIED:
+                failf(data, "SSPI error: %s failed: %s\n",  function, "SEC_E_LOGON_DENIED");
+                break;
+            case SEC_E_NO_AUTHENTICATING_AUTHORITY:
+                failf(data, "SSPI error: %s failed: %s\n",  function, "SEC_E_NO_AUTHENTICATING_AUTHORITY");
+                break;
+            case SEC_E_NO_CREDENTIALS:
+                failf(data, "SSPI error: %s failed: %s\n",  function, "SEC_E_NO_CREDENTIALS");
+                break;
+            case SEC_E_TARGET_UNKNOWN:
+                failf(data, "SSPI error: %s failed: %s\n",  function, "SEC_E_TARGET_UNKNOWN");
+                break;
+            case SEC_E_UNSUPPORTED_FUNCTION:
+                failf(data, "SSPI error: %s failed: %s\n",  function, "SEC_E_UNSUPPORTED_FUNCTION");
+                break;
+            case SEC_E_WRONG_PRINCIPAL:
+                failf(data, "SSPI error: %s failed: %s\n",  function, "SEC_E_WRONG_PRINCIPAL");
+                break;
+            default:
+                failf(data, "SSPI error: %s failed: %s\n",  function, "Unknown error");
+        }
+        return(1);
+    }
+    return(0);
+}
+#endif
 /*
  * Helper read-from-socket functions. Does the same as Curl_read() but it
  * blocks until all bytes amount of buffersize will be read. No more, no less.
@@ -379,7 +497,9 @@
     o  X'00' succeeded
   */
 
-  unsigned char socksreq[600]; /* room for large user/pw (255 max each) */
+
+#define SOCKS5REQLEN 65600
+  unsigned char socksreq[SOCKS5REQLEN]; /* room for GSSAPI token max 65535 */
   ssize_t actualread;
   ssize_t written;
   int result;
@@ -394,7 +514,7 @@
   /* RFC1928 chapter 5 specifies max 255 chars for domain name in packet */
   if(!socks5_resolve_local && hostname_len > 255)
   {
-    infof(conn->data,"SOCKS5: server resolving disabled for hostnames of "
+    infof(data,"SOCKS5: server resolving disabled for hostnames of "
           "length > 255 [actual len=%d]\n", hostname_len);
     socks5_resolve_local = TRUE;
   }
@@ -414,23 +534,30 @@
   result = Curl_socket_ready(CURL_SOCKET_BAD, sock, (int)timeout);
 
   if(-1 == result) {
-    failf(conn->data, "SOCKS5: no connection here");
+    failf(data, "SOCKS5: no connection here");
     return CURLE_COULDNT_CONNECT;
   }
   else if(0 == result) {
-    failf(conn->data, "SOCKS5: connection timeout");
+    failf(data, "SOCKS5: connection timeout");
     return CURLE_OPERATION_TIMEDOUT;
   }
 
   if(result & CURL_CSELECT_ERR) {
-    failf(conn->data, "SOCKS5: error occured during connection");
+    failf(data, "SOCKS5: error occured during connection");
     return CURLE_COULDNT_CONNECT;
   }
 
   socksreq[0] = 5; /* version */
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
+  socksreq[1] = (char)(proxy_name ? 3 : 2); /* number of methods (below) */
+  socksreq[2] = 0; /* no authentication */
+  socksreq[3] = 1; /* gssapi */
+  socksreq[4] = 2; /* username/password */
+#else
   socksreq[1] = (char)(proxy_name ? 2 : 1); /* number of methods (below) */
   socksreq[2] = 0; /* no authentication */
   socksreq[3] = 2; /* username/password */
+#endif
 
   Curl_nonblock(sock, FALSE);
 
@@ -446,16 +573,16 @@
   result = Curl_socket_ready(sock, CURL_SOCKET_BAD, (int)timeout);
 
   if(-1 == result) {
-    failf(conn->data, "SOCKS5 nothing to read");
+    failf(data, "SOCKS5 nothing to read");
     return CURLE_COULDNT_CONNECT;
   }
   else if(0 == result) {
-    failf(conn->data, "SOCKS5 read timeout");
+    failf(data, "SOCKS5 read timeout");
     return CURLE_OPERATION_TIMEDOUT;
   }
 
   if(result & CURL_CSELECT_ERR) {
-    failf(conn->data, "SOCKS5 read error occured");
+    failf(data, "SOCKS5 read error occured");
     return CURLE_RECV_ERROR;
   }
 
@@ -475,6 +602,512 @@
     /* Nothing to do, no authentication needed */
     ;
   }
+#ifdef HAVE_GSSAPI
+  else if(socksreq[1] == 1) {
+    /* Needs GSSAPI authentication */
+    OM_uint32 gss_major_status, gss_minor_status, gss_status;
+    OM_uint32 ret_flags;
+    gss_buffer_desc  service = GSS_C_EMPTY_BUFFER;
+    gss_buffer_desc  gss_send_token = GSS_C_EMPTY_BUFFER;
+    gss_buffer_desc  gss_recv_token = GSS_C_EMPTY_BUFFER;
+    gss_buffer_desc* gss_token = GSS_C_NO_BUFFER;
+    gss_ctx_id_t     gss_context = GSS_C_NO_CONTEXT;
+    gss_name_t       server;
+    u_short 	     us_length;
+     
+    /*   GSSAPI request looks like
+     * +----+------+-----+----------------+
+     * |VER | MTYP | LEN |     TOKEN      |
+     * +----+------+----------------------+
+     * | 1  |  1   |  2  | up to 2^16 - 1 |
+     * +----+------+-----+----------------+
+     */
+
+    /* prepare service name */
+    service.value = malloc(strlen(data->set.str[STRING_SOCKS5_GSSAPI_SERVICE])+strlen(conn->proxy.name)+2);
+    snprintf(service.value,strlen(data->set.str[STRING_SOCKS5_GSSAPI_SERVICE])+strlen(conn->proxy.name)+2,"%s@%s",data->set.str[STRING_SOCKS5_GSSAPI_SERVICE],conn->proxy.name);
+    service.length = strlen((char *)service.value);
+
+    gss_major_status = gss_import_name(&gss_minor_status, &service, gss_nt_service_name, &server);
+
+    if (check_gss_err(data,gss_major_status,gss_minor_status,"gss_import_name()")) {
+    	    failf(data, "Failed to create service name.");
+            gss_release_buffer(&gss_status, &service);
+            gss_release_name(&gss_status, &server);
+    	    return CURLE_COULDNT_CONNECT;
+    }
+    gss_release_buffer(&gss_status, &service);
+
+    /* As long as we need to keep sending some context info, and there's no  */
+    /* errors, keep sending it...                                            */
+    for (;;) {
+        gss_major_status = gss_init_sec_context(&gss_minor_status, GSS_C_NO_CREDENTIAL, &gss_context, server,
+                                      GSS_C_NULL_OID, GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG,
+                                      0, NULL, gss_token, NULL, &gss_send_token, &ret_flags,
+                                      NULL);
+
+        if (gss_token != GSS_C_NO_BUFFER) gss_release_buffer(&gss_status, &gss_recv_token);
+        if (check_gss_err(data,gss_major_status,gss_minor_status,"gss_init_sec_context")) {
+            gss_release_name(&gss_status, &server);
+            gss_release_buffer(&gss_status, &gss_send_token);
+            gss_delete_sec_context(&gss_status, &gss_context, NULL);
+    	    failf(data, "Failed to initial GSSAPI token.");
+    	    return CURLE_COULDNT_CONNECT;
+        }
+
+        if (gss_send_token.length != 0) {
+    	    socksreq[0] = 1;    /* gssapi subnegotiation version */
+    	    socksreq[1] = 1;    /* authentication message type */
+            us_length = htons((short)gss_send_token.length); 
+            memcpy(socksreq+2,&us_length,sizeof(short)); 
+
+    	    code = Curl_write_plain(conn, sock, (char *)socksreq, 4, &written);
+    	    if((code != CURLE_OK) || (4 != written)) {
+      	    	failf(data, "Failed to send GSSAPI authentication request.");
+                gss_release_name(&gss_status, &server);
+                gss_release_buffer(&gss_status, &gss_send_token);
+                gss_delete_sec_context(&gss_status, &gss_context, NULL);
+      		return CURLE_COULDNT_CONNECT;
+    	    }
+
+            memcpy(socksreq , gss_send_token.value, (int) gss_send_token.length);
+
+    	    code = Curl_write_plain(conn, sock, (char *)socksreq, gss_send_token.length, &written);
+    	    if((code != CURLE_OK) || (gss_send_token.length != written)) {
+      	    	failf(data, "Failed to send GSSAPI authentication token.");
+                gss_release_name(&gss_status, &server);
+                gss_release_buffer(&gss_status, &gss_send_token);
+                gss_delete_sec_context(&gss_status, &gss_context, NULL);
+      		return CURLE_COULDNT_CONNECT;
+    	    }
+
+	}
+
+        gss_release_buffer(&gss_status, &gss_send_token);
+        if (gss_major_status != GSS_S_CONTINUE_NEEDED)  break;
+
+        /* analyse response */
+
+    	/*   GSSAPI response looks like
+     	 * +----+------+-----+----------------+
+     	 * |VER | MTYP | LEN |     TOKEN      |
+     	 * +----+------+----------------------+
+     	 * | 1  |  1   |  2  | up to 2^16 - 1 |
+     	 * +----+------+-----+----------------+
+     	 */
+
+    	result=blockread_all(conn, sock, (char *)socksreq, 4, &actualread,
+	                         timeout);
+    	if(result != CURLE_OK || actualread != 4) {
+      	    failf(data, "Failed to receive GSSAPI authentication response.");
+            gss_release_name(&gss_status, &server);
+            gss_delete_sec_context(&gss_status, &gss_context, NULL);
+      	    return CURLE_COULDNT_CONNECT;
+    	}
+
+    	/* ignore the first (VER) byte */
+    	if(socksreq[1] == 255) { /* status / message type */
+      	    failf(data, "User was rejected by the SOCKS5 server (%d %d).",
+                  socksreq[0], socksreq[1]);
+            gss_release_name(&gss_status, &server);
+            gss_delete_sec_context(&gss_status, &gss_context, NULL);
+      	    return CURLE_COULDNT_CONNECT;
+    	}
+
+    	if(socksreq[1] != 1) { /* status / messgae type */
+      	    failf(data, "Invalid GSSAPI authentication response type (%d %d).",
+                  socksreq[0], socksreq[1]);
+            gss_release_name(&gss_status, &server);
+            gss_delete_sec_context(&gss_status, &gss_context, NULL);
+      	    return CURLE_COULDNT_CONNECT;
+    	}
+
+	memcpy(&us_length, socksreq+2, sizeof(short));
+        us_length = ntohs(us_length);
+
+    	result=blockread_all(conn, sock, (char *)socksreq, us_length, &actualread,
+	                         timeout);
+
+    	if(result != CURLE_OK || actualread != us_length) {
+      	    failf(data, "Failed to receive GSSAPI authentication token.");
+            gss_release_name(&gss_status, &server);
+            gss_delete_sec_context(&gss_status, &gss_context, NULL);
+      	    return CURLE_COULDNT_CONNECT;
+    	}
+
+	gss_recv_token.length=us_length;
+        gss_recv_token.value=malloc(us_length);
+        if (!gss_recv_token.value) {
+            failf(data, "Could not allocate memory for GSSAPI authentication response token.");
+            gss_release_name(&gss_status, &server);
+            return CURLE_COULDNT_CONNECT;	
+	}          	
+        memcpy(gss_recv_token.value,socksreq,gss_recv_token.length);
+        gss_token = &gss_recv_token;
+    }
+
+    gss_release_name(&gss_status, &server);
+
+    /* Everything is good so far, user was authenticated! */
+
+    /* Do encryption */
+    socksreq[0] = 1;    /* gssapi subnegotiation version */
+    socksreq[1] = 2;    /* encryption message type */
+    us_length = htons((short)1);
+    memcpy(socksreq+2,&us_length,sizeof(short));
+
+    code = Curl_write_plain(conn, sock, (char *)socksreq, 4, &written);
+    if((code != CURLE_OK) || (4 != written)) {
+        failf(data, "Failed to send GSSAPI encryption request.");
+        gss_delete_sec_context(&gss_status, &gss_context, NULL);
+        return CURLE_COULDNT_CONNECT;
+    }
+    
+    socksreq[0] = 0; /* no data protection */
+    if      (ret_flags & GSS_C_CONF_FLAG)  socksreq[0] = 2; /* do confidentiality protection if supported */
+    else if (ret_flags & GSS_C_INTEG_FLAG) socksreq[0] = 1; /* else do integrity protection */
+
+    infof(data, "SOCKS5 server supports %s data protection.\n",(socksreq[0]==0)?"no":((socksreq[0]==1)?"integrity":"confidentiality") );
+    socksreq[0] = 0; /* force for the moment to no data protection */
+
+    code = Curl_write_plain(conn, sock, (char *)socksreq, 1, &written);
+    if((code != CURLE_OK) || (1 != written)) {
+        failf(data, "Failed to send GSSAPI encryption type.");
+        gss_delete_sec_context(&gss_status, &gss_context, NULL);
+        return CURLE_COULDNT_CONNECT;
+    }
+
+    result=blockread_all(conn, sock, (char *)socksreq, 4, &actualread,
+                                 timeout);
+    if(result != CURLE_OK || actualread != 4) {
+       failf(data, "Failed to receive GSSAPI encryption response.");
+       gss_delete_sec_context(&gss_status, &gss_context, NULL);
+       return CURLE_COULDNT_CONNECT;
+    }
+
+    /* ignore the first (VER) byte */
+    if(socksreq[1] == 255) { /* status / message type */
+       failf(data, "User was rejected by the SOCKS5 server (%d %d).",
+             socksreq[0], socksreq[1]);
+       return CURLE_COULDNT_CONNECT;
+    }
+
+    if(socksreq[1] != 2) { /* status / messgae type */
+       failf(data, "Invalid GSSAPI encryption response type (%d %d).",
+             socksreq[0], socksreq[1]);
+       return CURLE_COULDNT_CONNECT;
+    }
+
+    memcpy(&us_length, socksreq+2, sizeof(short));
+    us_length = ntohs(us_length);
+
+    result=blockread_all(conn, sock, (char *)socksreq, us_length, &actualread,
+                                 timeout);
+
+    if(result != CURLE_OK || actualread != us_length) {
+       failf(data, "Failed to receive GSSAPI encryptrion type.");
+       gss_delete_sec_context(&gss_status, &gss_context, NULL);
+       return CURLE_COULDNT_CONNECT;
+    }
+
+    infof(data, "SOCKS5 access with%s protection granted.\n",(socksreq[0]==0)?"out data":((socksreq[0]==1)?" integrity":" confidentiality") );
+
+/* For later use if encryption is required
+    conn->socks5_gss_enctype = socksreq[0]; 
+    if (socksreq[0] != 0)
+       conn->socks5_gss_context = gss_context; 
+    else {
+       gss_delete_sec_context(&gss_status, &gss_context, NULL);
+       conn->socks5_gss_context =  GSS_C_NO_CONTEXT;
+    }
+*/
+    
+  }
+#elif USE_WINDOWS_SSPI
+  else if(socksreq[1] == 1) {
+    /* Needs GSSAPI authentication */
+    OM_uint32 sspi_major_status, sspi_minor_status=0;
+    OM_uint32 ret_flags=0;
+    SecBuffer sspi_send_token, sspi_recv_token;
+    SecBufferDesc input_desc, output_desc;
+    CredHandle cred_handle;
+    CtxtHandle sspi_context;
+    PCtxtHandle context_handle = NULL;
+    TimeStamp expiry;
+    char *service_name=NULL;
+    u_short 	     us_length;
+     
+    /*   GSSAPI request looks like
+     * +----+------+-----+----------------+
+     * |VER | MTYP | LEN |     TOKEN      |
+     * +----+------+----------------------+
+     * | 1  |  1   |  2  | up to 2^16 - 1 |
+     * +----+------+-----+----------------+
+     */
+
+    /* prepare service name */
+    service_name = malloc(strlen(data->set.str[STRING_SOCKS5_GSSAPI_SERVICE])+strlen(conn->proxy.name)+2);
+    _snprintf(service_name,strlen(data->set.str[STRING_SOCKS5_GSSAPI_SERVICE])+strlen(conn->proxy.name)+2,"%s/%s",data->set.str[STRING_SOCKS5_GSSAPI_SERVICE],conn->proxy.name);
+
+    input_desc.cBuffers = 1;
+    input_desc.pBuffers = &sspi_recv_token;
+    input_desc.ulVersion = SECBUFFER_VERSION;
+
+    sspi_recv_token.BufferType = SECBUFFER_TOKEN;
+    sspi_recv_token.cbBuffer = 0;
+    sspi_recv_token.pvBuffer = NULL;
+
+    output_desc.cBuffers = 1;
+    output_desc.pBuffers = &sspi_send_token;
+    output_desc.ulVersion = SECBUFFER_VERSION;
+
+    sspi_send_token.BufferType = SECBUFFER_TOKEN;
+    sspi_send_token.cbBuffer = 0;
+    sspi_send_token.pvBuffer = NULL;
+
+    cred_handle.dwLower = 0;
+    cred_handle.dwUpper = 0;
+
+    sspi_major_status = AcquireCredentialsHandle( NULL, "Kerberos", SECPKG_CRED_OUTBOUND,
+                                                 NULL, NULL, NULL, NULL, &cred_handle, &expiry);
+
+    if (check_sspi_err(data, sspi_major_status,sspi_minor_status,"AcquireCredentialsHandle") ) {
+        failf(data, "Failed to acquire credentials.");
+	if (service_name) {
+            free(service_name);
+            service_name=NULL;
+        }
+        return CURLE_COULDNT_CONNECT;
+    }
+
+    /* As long as we need to keep sending some context info, and there's no  */
+    /* errors, keep sending it...                                            */
+    for (;;) {
+
+        sspi_major_status = InitializeSecurityContext( &cred_handle, context_handle, service_name,
+                            ISC_REQ_MUTUAL_AUTH | ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_CONFIDENTIALITY | ISC_REQ_REPLAY_DETECT,
+                            0, SECURITY_NATIVE_DREP, &input_desc, 0, &sspi_context, &output_desc, &ret_flags, &expiry);
+
+         if (sspi_recv_token.pvBuffer) {
+                free(sspi_recv_token.pvBuffer);
+                sspi_recv_token.pvBuffer = NULL;
+                sspi_recv_token.cbBuffer = 0;
+        }
+
+        if (check_sspi_err(data,sspi_major_status,sspi_minor_status,"InitializeSecurityContext") ){
+            if (service_name) {
+                free(service_name);
+                service_name=NULL;
+            }
+            FreeCredentialsHandle(&cred_handle);
+            DeleteSecurityContext(&sspi_context);
+    	    failf(data, "Failed to initialise security context.");
+    	    return CURLE_COULDNT_CONNECT;
+        }
+
+        if (sspi_send_token.cbBuffer != 0) {
+    	    socksreq[0] = 1;    /* gssapi subnegotiation version */
+    	    socksreq[1] = 1;    /* authentication message type */
+            us_length = htons((short)sspi_send_token.cbBuffer); 
+            memcpy(socksreq+2,&us_length,sizeof(short)); 
+
+    	    code = Curl_write_plain(conn, sock, (char *)socksreq, 4, &written);
+    	    if((code != CURLE_OK) || (4 != written)) {
+      	    	failf(data, "Failed to send SSPI authentication request.");
+                if (service_name) {
+                    free(service_name);
+                    service_name=NULL;
+                }
+                FreeContextBuffer(sspi_send_token.pvBuffer);
+                FreeCredentialsHandle(&cred_handle);
+                DeleteSecurityContext(&sspi_context);
+      		return CURLE_COULDNT_CONNECT;
+    	    }
+
+            memcpy(socksreq ,sspi_send_token.pvBuffer , (int) sspi_send_token.cbBuffer);
+
+    	    code = Curl_write_plain(conn, sock, (char *)socksreq, sspi_send_token.cbBuffer, &written);
+    	    if((code != CURLE_OK) || (sspi_send_token.cbBuffer != written)) {
+      	    	failf(data, "Failed to send SSPI authentication token.");
+                if (service_name) {
+                    free(service_name);
+                    service_name=NULL;
+                }
+                FreeContextBuffer(sspi_send_token.pvBuffer);
+                FreeCredentialsHandle(&cred_handle);
+                DeleteSecurityContext(&sspi_context);
+      		return CURLE_COULDNT_CONNECT;
+    	    }
+
+	}
+
+        FreeContextBuffer(sspi_send_token.pvBuffer);
+        sspi_send_token.pvBuffer = NULL;
+        sspi_send_token.cbBuffer = 0;
+        if (sspi_major_status != SEC_I_CONTINUE_NEEDED)  break;
+
+        /* analyse response */
+
+    	/*   GSSAPI response looks like
+     	 * +----+------+-----+----------------+
+     	 * |VER | MTYP | LEN |     TOKEN      |
+     	 * +----+------+----------------------+
+     	 * | 1  |  1   |  2  | up to 2^16 - 1 |
+     	 * +----+------+-----+----------------+
+     	 */
+
+    	result=blockread_all(conn, sock, (char *)socksreq, 4, &actualread,
+	                         timeout);
+    	if(result != CURLE_OK || actualread != 4) {
+      	    failf(data, "Failed to receive SSPI authentication response.");
+            if (service_name) {
+                free(service_name);
+                service_name=NULL;
+            }
+            FreeCredentialsHandle(&cred_handle);
+            DeleteSecurityContext(&sspi_context);
+      	    return CURLE_COULDNT_CONNECT;
+    	}
+
+    	/* ignore the first (VER) byte */
+    	if(socksreq[1] == 255) { /* status / message type */
+      	    failf(data, "User was rejected by the SOCKS5 server (%d %d).",
+                  socksreq[0], socksreq[1]);
+            if (service_name) {
+                free(service_name);
+                service_name=NULL;
+            }
+            FreeCredentialsHandle(&cred_handle);
+            DeleteSecurityContext(&sspi_context);
+      	    return CURLE_COULDNT_CONNECT;
+    	}
+
+    	if(socksreq[1] != 1) { /* status / messgae type */
+      	    failf(data, "Invalid SSPI authentication response type (%d %d).",
+                  socksreq[0], socksreq[1]);
+            if (service_name) {
+                free(service_name);
+                service_name=NULL;
+            }
+            FreeCredentialsHandle(&cred_handle);
+            DeleteSecurityContext(&sspi_context);
+      	    return CURLE_COULDNT_CONNECT;
+    	}
+
+	memcpy(&us_length, socksreq+2, sizeof(short));
+        us_length = ntohs(us_length);
+
+    	result=blockread_all(conn, sock, (char *)socksreq, us_length, &actualread,
+	                         timeout);
+
+    	if(result != CURLE_OK || actualread != us_length) {
+      	    failf(data, "Failed to receive SSPI authentication token.");
+            if (service_name) {
+                free(service_name);
+                service_name=NULL;
+            }
+            FreeCredentialsHandle(&cred_handle);
+            DeleteSecurityContext(&sspi_context);
+      	    return CURLE_COULDNT_CONNECT;
+    	}
+
+	sspi_recv_token.cbBuffer=us_length;
+        sspi_recv_token.pvBuffer=malloc(us_length);
+        if (!sspi_recv_token.pvBuffer) {
+            failf(data, "Could not allocate memory for SSPI authentication response token.");
+            if (service_name) {
+                free(service_name);
+                service_name=NULL;
+            }
+            FreeCredentialsHandle(&cred_handle);
+            DeleteSecurityContext(&sspi_context);
+            return CURLE_COULDNT_CONNECT;	
+	}          	
+        memcpy(sspi_recv_token.pvBuffer,socksreq,sspi_recv_token.cbBuffer);
+        context_handle = &sspi_context;
+    }
+
+    if (service_name) {
+        free(service_name);
+        service_name=NULL;
+    }
+    FreeCredentialsHandle(&cred_handle);
+
+    /* Everything is good so far, user was authenticated! */
+
+    /* Do encryption */
+    socksreq[0] = 1;    /* gssapi subnegotiation version */
+    socksreq[1] = 2;    /* encryption message type */
+    us_length = htons((short)1);
+    memcpy(socksreq+2,&us_length,sizeof(short));
+
+    code = Curl_write_plain(conn, sock, (char *)socksreq, 4, &written);
+    if((code != CURLE_OK) || (4 != written)) {
+        failf(data, "Failed to send SSPI encryption request.");
+        DeleteSecurityContext(&sspi_context);
+        return CURLE_COULDNT_CONNECT;
+    }
+    
+    socksreq[0] = 0; /* no data protection */
+    if      (ret_flags & ISC_REQ_CONFIDENTIALITY)  socksreq[0] = 2; /* do confidentiality protection if supported */
+    else if (ret_flags & ISC_REQ_INTEGRITY) socksreq[0] = 1; /* else do integrity protection */
+
+    infof(data, "SOCKS5 server supports %s data protection.\n",(socksreq[0]==0)?"no":((socksreq[0]==1)?"integrity":"confidentiality") );
+    socksreq[0] = 0; /* force to no data protection, avoid encryption/decryption for now */
+
+    code = Curl_write_plain(conn, sock, (char *)socksreq, 1, &written);
+    if((code != CURLE_OK) || (1 != written)) {
+        failf(data, "Failed to send SSPI encryption type.");
+        DeleteSecurityContext(&sspi_context);
+        return CURLE_COULDNT_CONNECT;
+    }
+
+    result=blockread_all(conn, sock, (char *)socksreq, 4, &actualread,
+                                 timeout);
+    if(result != CURLE_OK || actualread != 4) {
+       failf(data, "Failed to receive SSPI encryption response.");
+       DeleteSecurityContext(&sspi_context);
+       return CURLE_COULDNT_CONNECT;
+    }
+
+    /* ignore the first (VER) byte */
+    if(socksreq[1] == 255) { /* status / message type */
+       failf(data, "User was rejected by the SOCKS5 server (%d %d).",
+             socksreq[0], socksreq[1]);
+       return CURLE_COULDNT_CONNECT;
+    }
+
+    if(socksreq[1] != 2) { /* status / messgae type */
+       failf(data, "Invalid SSPI encryption response type (%d %d).",
+             socksreq[0], socksreq[1]);
+       return CURLE_COULDNT_CONNECT;
+    }
+
+    memcpy(&us_length, socksreq+2, sizeof(short));
+    us_length = ntohs(us_length);
+
+    result=blockread_all(conn, sock, (char *)socksreq, us_length, &actualread,
+                                 timeout);
+
+    if(result != CURLE_OK || actualread != us_length) {
+       failf(data, "Failed to receive SSPI encryptrion type.");
+       DeleteSecurityContext(&sspi_context);
+       return CURLE_COULDNT_CONNECT;
+    }
+
+    infof(data, "SOCKS5 access with%s protection granted.\n",(socksreq[0]==0)?"out data":((socksreq[0]==1)?" integrity":" confidentiality") );
+
+/* For later use if encryption is required
+    conn->socks5_sspi_enctype = socksreq[0]; 
+    if (socksreq[0] != 0)
+       conn->socks5_sspi_context = sspi_context; 
+    else {
+       DeleteSecurityContext(&sspi_context);
+       conn->socks5_sspi_context = sspi_context; 
+    }
+*/    
+  }
+#endif
   else if(socksreq[1] == 2) {
     /* Needs user name and password */
     size_t userlen, pwlen;
@@ -528,12 +1161,16 @@
   }
   else {
     /* error */
+#ifndef HAVE_GSSAPI
     if(socksreq[1] == 1) {
       failf(data,
             "SOCKS5 GSSAPI per-message authentication is not supported.");
       return CURLE_COULDNT_CONNECT;
     }
     else if(socksreq[1] == 255) {
+#else
+    if(socksreq[1] == 255) {
+#endif
       if(!proxy_name || !*proxy_name) {
         failf(data,
               "No authentication method was acceptable. (It is quite likely"
diff -ruN curl-7.19.0/lib/url.c curl-7.19.0-new/lib/url.c
--- curl-7.19.0/lib/url.c	2008-08-28 08:37:29.000000000 +0100
+++ curl-7.19.0-new/lib/url.c	2008-09-14 11:43:45.000000000 +0100
@@ -753,6 +753,9 @@
     data->set.ssl.verifypeer = TRUE;
     data->set.ssl.verifyhost = 2;
     data->set.ssl.sessionid = TRUE; /* session ID caching enabled by default */
+
+    res = setstropt(&data->set.str[STRING_SOCKS5_GSSAPI_SERVICE], (char *) CURL_DEFAULT_SOCKS5_GSSAPI_SERVICE); /* set default gssapi service name */
+
     /* This is our preferred CA cert bundle/path since install time */
 #if defined(CURL_CA_BUNDLE)
     res = setstropt(&data->set.str[STRING_SSL_CAFILE],
@@ -761,7 +764,6 @@
     res = setstropt(&data->set.str[STRING_SSL_CAPATH], (char *) CURL_CA_PATH);
 #endif
   }
-
   if(res) {
     ares_destroy(data->state.areschannel);
     if(data->state.headerbuff)
@@ -1386,6 +1388,14 @@
                        va_arg(param, char *));
     break;
 
+  case CURLOPT_SOCKS5_GSSAPI_SERVICE:
+    /*
+     * Set gssapi service name
+     */
+    result = setstropt(&data->set.str[STRING_SOCKS5_GSSAPI_SERVICE],
+                       va_arg(param, char *));
+    break;
+
   case CURLOPT_WRITEHEADER:
     /*
      * Custom pointer to pass the header write callback function
diff -ruN curl-7.19.0/lib/urldata.h curl-7.19.0-new/lib/urldata.h
--- curl-7.19.0/lib/urldata.h	2008-08-19 20:02:45.000000000 +0100
+++ curl-7.19.0-new/lib/urldata.h	2008-09-14 11:44:52.000000000 +0100
@@ -1331,6 +1331,7 @@
   STRING_SSH_HOST_PUBLIC_KEY_MD5, /* md5 of host public key in ascii hex */
   STRING_SSL_CRLFILE,     /* crl file to check certificate */
   STRING_SSL_ISSUERCERT,  /* issuer cert file to check certificate */
+  STRING_SOCKS5_GSSAPI_SERVICE,  /* GSSAPI service name */
 
   /* -- end of strings -- */
   STRING_LAST /* not used, just an end-of-list marker */
diff -ruN curl-7.19.0/lib/url.h curl-7.19.0-new/lib/url.h
--- curl-7.19.0/lib/url.h	2008-04-05 22:13:31.000000000 +0100
+++ curl-7.19.0-new/lib/url.h	2008-09-14 11:44:45.000000000 +0100
@@ -78,5 +78,6 @@
 void Curl_reset_reqproto(struct connectdata *conn);
 
 #define CURL_DEFAULT_PROXY_PORT 1080 /* default proxy port unless specified */
+#define CURL_DEFAULT_SOCKS5_GSSAPI_SERVICE "rcmd" /* default socks5 gssapi service */
 
 #endif
diff -ruN curl-7.19.0/src/main.c curl-7.19.0-new/src/main.c
--- curl-7.19.0/src/main.c	2008-08-29 09:55:20.000000000 +0100
+++ curl-7.19.0-new/src/main.c	2008-09-14 11:42:43.000000000 +0100
@@ -541,6 +541,7 @@
 
   char *socksproxy; /* set to server string */
   int socksver;     /* set to CURLPROXY_SOCKS* define */
+  char *socks5_gssapi_service;  /* set service name for gssapi principal default rcmd */
 
   bool tcp_nodelay;
   long req_retry;   /* number of retries */
@@ -809,6 +810,7 @@
     "    --socks4a <host[:port]> SOCKS4a proxy on given host + port",
     "    --socks5 <host[:port]> SOCKS5 proxy on given host + port",
     "    --socks5-hostname <host[:port]> SOCKS5 proxy, pass host name to proxy",
+    "    --socks5-gssapi-service <servicename> SOCKS5 proxy service name for gssapi",
     " -Y/--speed-limit   Stop transfer if below speed-limit for 'speed-time' secs",
     " -y/--speed-time    Time needed to trig speed-limit abort. Defaults to 30",
     " -2/--sslv2         Use SSLv2 (SSL)",
@@ -1670,6 +1672,7 @@
     {"$1", "keepalive",   FALSE}, /* listed as --no-keepalive in the help */
     {"$2", "socks5-hostname", TRUE},
     {"$3", "keepalive-time",  TRUE},
+    {"$4", "socks5-gssapi-service",  TRUE},
 
     {"0", "http1.0",     FALSE},
     {"1", "tlsv1",       FALSE},
@@ -2178,6 +2181,9 @@
         if(str2num(&config->alivetime, nextarg))
           return PARAM_BAD_NUMERIC;
         break;
+      case '4': /* --socks5-gssapi-service */
+        GetStr(&config->socks5_gssapi_service, nextarg);
+        break;
       }
       break;
     case '#': /* --progress-bar */
@@ -3691,6 +3697,8 @@
     free(config->referer);
   if (config->hostpubmd5)
     free(config->hostpubmd5);
+  if(config->socks5_gssapi_service)
+    free(config->socks5_gssapi_service);
 
   curl_slist_free_all(config->quote); /* checks for config->quote == NULL */
   curl_slist_free_all(config->prequote);
@@ -4745,6 +4753,11 @@
           my_setopt(curl, CURLOPT_PROXYTYPE, config->socksver);
         }
 
+        /* new in curl 7.19.1 */
+        if(config->socks5_gssapi_service) {
+          my_setopt(curl, CURLOPT_SOCKS5_GSSAPI_SERVICE, config->socks5_gssapi_service);
+        }
+
         /* curl 7.13.0 */
         my_setopt(curl, CURLOPT_FTP_ACCOUNT, config->ftp_account);
 

