Add new CURLOPT_GSSAPI_DELEGATION option.
authorAdam Tkac <atkac@redhat.com>
Tue, 19 Jul 2011 17:10:43 +0000 (19:10 +0200)
committerKamil Dudka <kdudka@redhat.com>
Wed, 3 Aug 2011 08:23:34 +0000 (10:23 +0200)
Curl_gss_init_sec_context got new parameter - SessionHandle.

Signed-off-by: Adam Tkac <atkac@redhat.com>
RELEASE-NOTES
docs/libcurl/curl_easy_setopt.3
include/curl/curl.h
lib/curl_gssapi.c
lib/curl_gssapi.h
lib/http_negotiate.c
lib/krb5.c
lib/socks_gssapi.c
lib/url.c
lib/urldata.h

index 23519d1..d495727 100644 (file)
@@ -2,13 +2,14 @@ Curl and libcurl 7.21.8
 
  Public curl releases:         124
  Command line options:         144
- curl_easy_setopt() options:   186
+ curl_easy_setopt() options:   187
  Public functions in libcurl:  58
  Known libcurl bindings:       39
  Contributors:                 868
 
 This release includes the following changes:
 
+ o Added CURLOPT_GSSAPI_DELEGATION
  o 
 
 This release includes the following bugfixes:
index 014269f..2cdfcf8 100644 (file)
@@ -2109,6 +2109,10 @@ of these, 'private' will be used. Set the string to NULL to disable kerberos
 support for FTP.
 
 (This option was known as CURLOPT_KRB4LEVEL up to 7.16.3)
+.IP CURLOPT_GSSAPI_DELEGATION
+Set the parameter to 1 to allow GSSAPI credential delegation.  The delegation
+is disabled by default since 7.21.7.
+(Added in 7.21.8)
 .SH SSH OPTIONS
 .IP CURLOPT_SSH_AUTH_TYPES
 Pass a long set to a bitmask consisting of one or more of
index 998c109..3a510e5 100644 (file)
@@ -1484,6 +1484,9 @@ typedef enum {
   CINIT(CLOSESOCKETFUNCTION, FUNCTIONPOINT, 208),
   CINIT(CLOSESOCKETDATA, OBJECTPOINT, 209),
 
+  /* allow GSSAPI credential delegation */
+  CINIT(GSSAPI_DELEGATION, LONG, 210),
+
   CURLOPT_LASTENTRY /* the last unused */
 } CURLoption;
 
index 3b6b189..6b47987 100644 (file)
@@ -27,6 +27,7 @@
 #include "curl_gssapi.h"
 
 OM_uint32 Curl_gss_init_sec_context(
+    const struct SessionHandle *data,
     OM_uint32 * minor_status,
     gss_ctx_id_t * context,
     gss_name_t target_name,
@@ -35,13 +36,18 @@ OM_uint32 Curl_gss_init_sec_context(
     gss_buffer_t output_token,
     OM_uint32 * ret_flags)
 {
+  OM_uint32 req_flags;
+
+  req_flags = GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG;
+  if (data->set.gssapi_delegation)
+    req_flags |= GSS_C_DELEG_FLAG;
+
   return gss_init_sec_context(minor_status,
                               GSS_C_NO_CREDENTIAL, /* cred_handle */
                               context,
                               target_name,
                               GSS_C_NO_OID, /* mech_type */
-                              /* req_flags */
-                              GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG,
+                              req_flags,
                               0, /* time_req */
                               input_chan_bindings,
                               input_token,
index 249e864..6103ff1 100644 (file)
@@ -23,6 +23,7 @@
  ***************************************************************************/
 
 #include "setup.h"
+#include "urldata.h"
 
 #ifdef HAVE_GSSAPI
 
@@ -42,6 +43,7 @@
 /* Common method for using gss api */
 
 OM_uint32 Curl_gss_init_sec_context(
+    const struct SessionHandle *data,
     OM_uint32 * minor_status,
     gss_ctx_id_t * context,
     gss_name_t target_name,
index 695ab16..b3d870c 100644 (file)
@@ -131,8 +131,9 @@ log_gss_error(struct connectdata *conn, OM_uint32 error_status,
 int Curl_input_negotiate(struct connectdata *conn, bool proxy,
                          const char *header)
 {
-  struct negotiatedata *neg_ctx = proxy?&conn->data->state.proxyneg:
-    &conn->data->state.negotiate;
+  struct SessionHandle *data = conn->data;
+  struct negotiatedata *neg_ctx = proxy?&data->state.proxyneg:
+    &data->state.negotiate;
   OM_uint32 major_status, minor_status, minor_status2;
   gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
   gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
@@ -168,7 +169,7 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
     /* We finished successfully our part of authentication, but server
      * rejected it (since we're again here). Exit with an error since we
      * can't invent anything better */
-    Curl_cleanup_negotiate(conn->data);
+    Curl_cleanup_negotiate(data);
     return -1;
   }
 
@@ -217,7 +218,7 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
                                  NULL)) {
         free(spnegoToken);
         spnegoToken = NULL;
-        infof(conn->data, "Parse SPNEGO Target Token failed\n");
+        infof(data, "Parse SPNEGO Target Token failed\n");
       }
       else {
         free(input_token.value);
@@ -229,13 +230,14 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
         input_token.length = mechTokenLength;
         free(mechToken);
         mechToken = NULL;
-        infof(conn->data, "Parse SPNEGO Target Token succeeded\n");
+        infof(data, "Parse SPNEGO Target Token succeeded\n");
       }
     }
 #endif
   }
 
-  major_status = Curl_gss_init_sec_context(&minor_status,
+  major_status = Curl_gss_init_sec_context(data,
+                                           &minor_status,
                                            &neg_ctx->context,
                                            neg_ctx->server_name,
                                            GSS_C_NO_CHANNEL_BINDINGS,
@@ -246,7 +248,7 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
     gss_release_buffer(&minor_status2, &input_token);
   neg_ctx->status = major_status;
   if(GSS_ERROR(major_status)) {
-    /* Curl_cleanup_negotiate(conn->data) ??? */
+    /* Curl_cleanup_negotiate(data) ??? */
     log_gss_error(conn, minor_status,
                   "gss_init_sec_context() failed: ");
     return -1;
index 1f7038f..0422cda 100644 (file)
@@ -230,7 +230,8 @@ krb5_auth(void *app_data, struct connectdata *conn)
          taken care by a final gss_release_buffer. */
       gss_release_buffer(&min, &output_buffer);
       ret = AUTH_OK;
-      maj = Curl_gss_init_sec_context(&min,
+      maj = Curl_gss_init_sec_context(data,
+                                      &min,
                                       context,
                                       gssname,
                                       &chan,
index 74b074e..c62bdc9 100644 (file)
@@ -180,7 +180,8 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
   /* As long as we need to keep sending some context info, and there's no  */
   /* errors, keep sending it...                                            */
   for(;;) {
-    gss_major_status = Curl_gss_init_sec_context(&gss_minor_status,
+    gss_major_status = Curl_gss_init_sec_context(data,
+                                                 &gss_minor_status,
                                                  &gss_context,
                                                  server,
                                                  NULL,
index 59da3e9..050be2c 100644 (file)
--- a/lib/url.c
+++ b/lib/url.c
@@ -1975,6 +1975,12 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
                        va_arg(param, char *));
     data->set.krb = (bool)(NULL != data->set.str[STRING_KRB_LEVEL]);
     break;
+  case CURLOPT_GSSAPI_DELEGATION:
+    /*
+     * allow GSSAPI credential delegation
+     */
+    data->set.gssapi_delegation = (bool)(0 != va_arg(param, long));
+    break;
   case CURLOPT_SSL_VERIFYPEER:
     /*
      * Enable peer SSL verifying.
index 6f81153..3db8e2f 100644 (file)
@@ -1525,6 +1525,8 @@ struct UserDefined {
   curl_fnmatch_callback fnmatch; /* callback to decide which file corresponds
                                     to pattern (e.g. if WILDCARDMATCH is on) */
   void *fnmatch_data;
+
+  bool gssapi_delegation;      /* allow GSSAPI credential delegation */
 };
 
 struct Names {