cURL / Mailing Lists / curl-library / Single Mail

curl-library

[PATCH] Add new CURLOPT_GSSAPI_DELEGATION option.

From: Adam Tkac <atkac_at_redhat.com>
Date: Tue, 19 Jul 2011 19:10:43 +0200

Curl_gss_init_sec_context got new parameter - SessionHandle.

Signed-off-by: Adam Tkac <atkac_at_redhat.com>

---
 RELEASE-NOTES                   |    3 ++-
 docs/libcurl/curl_easy_setopt.3 |    4 ++++
 include/curl/curl.h             |    3 +++
 lib/curl_gssapi.c               |   10 ++++++++--
 lib/curl_gssapi.h               |    2 ++
 lib/http_negotiate.c            |   16 +++++++++-------
 lib/krb5.c                      |    3 ++-
 lib/socks_gssapi.c              |    3 ++-
 lib/url.c                       |    6 ++++++
 lib/urldata.h                   |    2 ++
 10 files changed, 40 insertions(+), 12 deletions(-)
diff --git a/RELEASE-NOTES b/RELEASE-NOTES
index 9ab8716..7272fa8 100644
--- a/RELEASE-NOTES
+++ b/RELEASE-NOTES
@@ -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:
diff --git a/docs/libcurl/curl_easy_setopt.3 b/docs/libcurl/curl_easy_setopt.3
index 014269f..2cdfcf8 100644
--- a/docs/libcurl/curl_easy_setopt.3
+++ b/docs/libcurl/curl_easy_setopt.3
@@ -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
diff --git a/include/curl/curl.h b/include/curl/curl.h
index 998c109..3a510e5 100644
--- a/include/curl/curl.h
+++ b/include/curl/curl.h
@@ -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;
 
diff --git a/lib/curl_gssapi.c b/lib/curl_gssapi.c
index 3b6b189..6b47987 100644
--- a/lib/curl_gssapi.c
+++ b/lib/curl_gssapi.c
@@ -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,
diff --git a/lib/curl_gssapi.h b/lib/curl_gssapi.h
index c5fbefe..6b04373 100644
--- a/lib/curl_gssapi.h
+++ b/lib/curl_gssapi.h
@@ -21,6 +21,7 @@
  ***************************************************************************/
 
 #include "setup.h"
+#include "urldata.h"
 
 #ifdef HAVE_GSSAPI
 
@@ -40,6 +41,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,
diff --git a/lib/http_negotiate.c b/lib/http_negotiate.c
index 36823f8..c2ba548 100644
--- a/lib/http_negotiate.c
+++ b/lib/http_negotiate.c
@@ -135,8 +135,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;
@@ -172,7 +173,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;
   }
 
@@ -221,7 +222,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);
@@ -233,13 +234,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,
@@ -250,7 +252,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;
diff --git a/lib/krb5.c b/lib/krb5.c
index 5c60c8d..83d20ee 100644
--- a/lib/krb5.c
+++ b/lib/krb5.c
@@ -231,7 +231,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,
diff --git a/lib/socks_gssapi.c b/lib/socks_gssapi.c
index 872efb0..27dcab2 100644
--- a/lib/socks_gssapi.c
+++ b/lib/socks_gssapi.c
@@ -184,7 +184,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,
diff --git a/lib/url.c b/lib/url.c
index adb96c4..ce7a04f 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -1993,6 +1993,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.
diff --git a/lib/urldata.h b/lib/urldata.h
index d2638aa..f774a13 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -1526,6 +1526,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 {
-- 
1.7.6
--------------080104090309000403040706
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette:  http://curl.haxx.se/mail/etiquette.html
--------------080104090309000403040706--
Received on 2001-09-17