8997807
From 0b164a2c002452d6660d0f745d60686f77060c2d Mon Sep 17 00:00:00 2001
8997807
From: Kamil Dudka <kdudka@redhat.com>
8997807
Date: Wed, 3 Aug 2011 12:48:49 +0200
8997807
Subject: [PATCH] curl - rhbz #719939
8997807
8997807
---
8997807
 docs/libcurl/curl_easy_setopt.3  |    8 ++++++
8997807
 docs/libcurl/symbols-in-versions |    4 +++
8997807
 include/curl/curl.h              |    7 +++++
8997807
 lib/Makefile.in                  |    7 +++++
8997807
 lib/Makefile.inc                 |    4 +-
8997807
 lib/curl_gssapi.c                |   45 +++++++++++++++++++++++++++++++++++++
8997807
 lib/curl_gssapi.h                |   46 ++++++++++++++++++++++++++++++++++++++
8997807
 lib/http_negotiate.c             |    6 ++++-
8997807
 lib/krb5.c                       |    6 ++++-
8997807
 lib/socks_gssapi.c               |    7 ++++-
8997807
 lib/url.c                        |    6 +++++
8997807
 lib/urldata.h                    |    3 ++
8997807
 12 files changed, 143 insertions(+), 6 deletions(-)
8997807
 create mode 100644 lib/curl_gssapi.c
8997807
 create mode 100644 lib/curl_gssapi.h
8997807
8997807
diff --git a/docs/libcurl/curl_easy_setopt.3 b/docs/libcurl/curl_easy_setopt.3
8997807
index a26898f..3c20d29 100644
8997807
--- a/docs/libcurl/curl_easy_setopt.3
8997807
+++ b/docs/libcurl/curl_easy_setopt.3
8997807
@@ -1972,6 +1972,14 @@ of these, 'private' will be used. Set the string to NULL to disable kerberos
8997807
 support for FTP.
8997807
 
8997807
 (This option was known as CURLOPT_KRB4LEVEL up to 7.16.3)
8997807
+.IP CURLOPT_GSSAPI_DELEGATION
8997807
+Set the parameter to CURLGSSAPI_DELEGATION_FLAG to allow unconditional GSSAPI
8997807
+credential delegation.  The delegation is disabled by default since 7.21.7.
8997807
+Set the parameter to CURLGSSAPI_DELEGATION_POLICY_FLAG to delegate only if
8997807
+the OK-AS-DELEGATE flag is set in the service ticket in case this feature is
8997807
+supported by the GSSAPI implementation and the definition of
8997807
+GSS_C_DELEG_POLICY_FLAG was available at compile-time.
8997807
+(Added in 7.21.8)
8997807
 .SH SSH OPTIONS
8997807
 .IP CURLOPT_SSH_AUTH_TYPES
8997807
 Pass a long set to a bitmask consisting of one or more of
8997807
diff --git a/docs/libcurl/symbols-in-versions b/docs/libcurl/symbols-in-versions
8997807
index a02ead4..75c709d 100644
8997807
--- a/docs/libcurl/symbols-in-versions
8997807
+++ b/docs/libcurl/symbols-in-versions
8997807
@@ -131,6 +131,9 @@ CURLFTPSSL_TRY                  7.11.0        7.17.0
8997807
 CURLFTP_CREATE_DIR              7.19.4
8997807
 CURLFTP_CREATE_DIR_NONE         7.19.4
8997807
 CURLFTP_CREATE_DIR_RETRY        7.19.4
8997807
+CURLGSSAPI_DELEGATION_FLAG      7.21.8
8997807
+CURLGSSAPI_DELEGATION_NONE      7.21.8
8997807
+CURLGSSAPI_DELEGATION_POLICY_FLAG 7.21.8
8997807
 CURLINFO_APPCONNECT_TIME        7.19.0
8997807
 CURLINFO_CERTINFO               7.19.1
8997807
 CURLINFO_CONDITION_UNMET        7.19.4
8997807
@@ -244,6 +247,7 @@ CURLOPT_FTP_SSL_CCC             7.16.1
8997807
 CURLOPT_FTP_USE_EPRT            7.10.5
8997807
 CURLOPT_FTP_USE_EPSV            7.9.2
8997807
 CURLOPT_FTP_USE_PRET            7.20.0
8997807
+CURLOPT_GSSAPI_DELEGATION       7.21.8
8997807
 CURLOPT_HEADER                  7.1
8997807
 CURLOPT_HEADERDATA              7.10
8997807
 CURLOPT_HEADERFUNCTION          7.7.2
8997807
diff --git a/include/curl/curl.h b/include/curl/curl.h
8997807
index b19828f..0a0c0b3 100644
8997807
--- a/include/curl/curl.h
8997807
+++ b/include/curl/curl.h
8997807
@@ -596,6 +596,10 @@ typedef enum {
8997807
 #define CURLSSH_AUTH_KEYBOARD  (1<<3) /* keyboard interactive */
8997807
 #define CURLSSH_AUTH_DEFAULT CURLSSH_AUTH_ANY
8997807
 
8997807
+#define CURLGSSAPI_DELEGATION_NONE        0      /* no delegation (default) */
8997807
+#define CURLGSSAPI_DELEGATION_POLICY_FLAG (1<<0) /* if permitted by policy */
8997807
+#define CURLGSSAPI_DELEGATION_FLAG        (1<<1) /* delegate always */
8997807
+
8997807
 #define CURL_ERROR_SIZE 256
8997807
 
8997807
 struct curl_khkey {
8997807
@@ -1435,6 +1439,9 @@ typedef enum {
8997807
   /* FNMATCH_FUNCTION user pointer */
8997807
   CINIT(FNMATCH_DATA, OBJECTPOINT, 202),
8997807
 
8997807
+  /* allow GSSAPI credential delegation */
8997807
+  CINIT(GSSAPI_DELEGATION, LONG, 210),
8997807
+
8997807
   CURLOPT_LASTENTRY /* the last unused */
8997807
 } CURLoption;
8997807
 
8997807
diff --git a/lib/Makefile.in b/lib/Makefile.in
8997807
index e7d451a..a27a417 100644
8997807
--- a/lib/Makefile.in
8997807
+++ b/lib/Makefile.in
8997807
@@ -612,6 +612,13 @@ distclean-compile:
8997807
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
8997807
 @am__fastdepCC_FALSE@	$(LTCOMPILE) -c -o $@ $<
8997807
 
8997807
+libcurlu_la-curl_gssapi.lo: curl_gssapi.c
8997807
+@am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcurlu_la-curl_gssapi.lo -MD -MP -MF $(DEPDIR)/libcurlu_la-curl_gssapi.Tpo -c -o libcurlu_la-curl_gssapi.lo `test -f 'curl_gssapi.c' || echo '$(srcdir)/'`curl_gssapi.c
8997807
+@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libcurlu_la-curl_gssapi.Tpo $(DEPDIR)/libcurlu_la-curl_gssapi.Plo
8997807
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='curl_gssapi.c' object='libcurlu_la-curl_gssapi.lo' libtool=yes @AMDEPBACKSLASH@
8997807
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
8997807
+@am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcurlu_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcurlu_la-curl_gssapi.lo `test -f 'curl_gssapi.c' || echo '$(srcdir)/'`curl_gssapi.c
8997807
+
8997807
 mostlyclean-libtool:
8997807
 	-rm -f *.lo
8997807
 
8997807
diff --git a/lib/Makefile.inc b/lib/Makefile.inc
8997807
index a502e8f..d9360a3 100644
8997807
--- a/lib/Makefile.inc
8997807
+++ b/lib/Makefile.inc
8997807
@@ -13,7 +13,7 @@ CSOURCES = file.c timeval.c base64.c hostip.c progress.c formdata.c	\
8997807
   strdup.c socks.c ssh.c nss.c qssl.c rawstr.c curl_addrinfo.c          \
8997807
   socks_gssapi.c socks_sspi.c curl_sspi.c slist.c nonblock.c		\
8997807
   curl_memrchr.c imap.c pop3.c smtp.c pingpong.c rtsp.c curl_threads.c	\
8997807
-  warnless.c hmac.c polarssl.c curl_rtmp.c openldap.c
8997807
+  warnless.c hmac.c polarssl.c curl_rtmp.c openldap.c curl_gssapi.c
8997807
 
8997807
 HHEADERS = arpa_telnet.h netrc.h file.h timeval.h qssl.h hostip.h	\
8997807
   progress.h formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h	\
8997807
@@ -27,4 +27,4 @@ HHEADERS = arpa_telnet.h netrc.h file.h timeval.h qssl.h hostip.h	\
8997807
   tftp.h sockaddr.h splay.h strdup.h setup_once.h socks.h ssh.h nssg.h	\
8997807
   curl_base64.h rawstr.h curl_addrinfo.h curl_sspi.h slist.h nonblock.h	\
8997807
   curl_memrchr.h imap.h pop3.h smtp.h pingpong.h rtsp.h curl_threads.h	\
8997807
-  warnless.h curl_hmac.h polarssl.h curl_rtmp.h
8997807
+  warnless.h curl_hmac.h polarssl.h curl_rtmp.h curl_gssapi.h
8997807
diff --git a/lib/curl_gssapi.c b/lib/curl_gssapi.c
8997807
new file mode 100644
8997807
index 0000000..914d1a0
8997807
--- /dev/null
8997807
+++ b/lib/curl_gssapi.c
8997807
@@ -0,0 +1,45 @@
8997807
+/***************************************************************************
8997807
+ *                                  _   _ ____  _
8997807
+ *  Project                     ___| | | |  _ \| |
8997807
+ *                             / __| | | | |_) | |
8997807
+ *                            | (__| |_| |  _ <| |___
8997807
+ *                             \___|\___/|_| \_\_____|
8997807
+ *
8997807
+ * Copyright (C) 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
8997807
+ *
8997807
+ * This software is licensed as described in the file COPYING, which
8997807
+ * you should have received as part of this distribution. The terms
8997807
+ * are also available at http://curl.haxx.se/docs/copyright.html.
8997807
+ *
8997807
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
8997807
+ * copies of the Software, and permit persons to whom the Software is
8997807
+ * furnished to do so, under the terms of the COPYING file.
8997807
+ *
8997807
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
8997807
+ * KIND, either express or implied.
8997807
+ *
8997807
+ ***************************************************************************/
8997807
+
8997807
+#include "setup.h"
8997807
+
8997807
+#ifdef HAVE_GSSAPI
8997807
+
8997807
+#include "curl_gssapi.h"
8997807
+#include "sendf.h"
8997807
+
8997807
+void Curl_gss_req_flags(OM_uint32 *req_flags, struct SessionHandle *data)
8997807
+{
8997807
+  if(data->set.gssapi_delegation & CURLGSSAPI_DELEGATION_POLICY_FLAG) {
8997807
+#ifdef GSS_C_DELEG_POLICY_FLAG
8997807
+    *req_flags |= GSS_C_DELEG_POLICY_FLAG;
8997807
+#else
8997807
+    infof(data, "warning: support for CURLGSSAPI_DELEGATION_POLICY_FLAG not "
8997807
+        "compiled in\n");
8997807
+#endif
8997807
+  }
8997807
+
8997807
+  if(data->set.gssapi_delegation & CURLGSSAPI_DELEGATION_FLAG)
8997807
+    *req_flags |= GSS_C_DELEG_FLAG;
8997807
+}
8997807
+
8997807
+#endif /* HAVE_GSSAPI */
8997807
diff --git a/lib/curl_gssapi.h b/lib/curl_gssapi.h
8997807
new file mode 100644
8997807
index 0000000..c8ffefc
8997807
--- /dev/null
8997807
+++ b/lib/curl_gssapi.h
8997807
@@ -0,0 +1,46 @@
8997807
+#ifndef HEADER_CURL_GSSAPI_H
8997807
+#define HEADER_CURL_GSSAPI_H
8997807
+/***************************************************************************
8997807
+ *                                  _   _ ____  _
8997807
+ *  Project                     ___| | | |  _ \| |
8997807
+ *                             / __| | | | |_) | |
8997807
+ *                            | (__| |_| |  _ <| |___
8997807
+ *                             \___|\___/|_| \_\_____|
8997807
+ *
8997807
+ * Copyright (C) 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
8997807
+ *
8997807
+ * This software is licensed as described in the file COPYING, which
8997807
+ * you should have received as part of this distribution. The terms
8997807
+ * are also available at http://curl.haxx.se/docs/copyright.html.
8997807
+ *
8997807
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
8997807
+ * copies of the Software, and permit persons to whom the Software is
8997807
+ * furnished to do so, under the terms of the COPYING file.
8997807
+ *
8997807
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
8997807
+ * KIND, either express or implied.
8997807
+ *
8997807
+ ***************************************************************************/
8997807
+
8997807
+#include "setup.h"
8997807
+#include "urldata.h"
8997807
+
8997807
+#ifdef HAVE_GSSAPI
8997807
+
8997807
+#ifdef HAVE_GSSGNU
8997807
+#  include <gss.h>
8997807
+#elif defined HAVE_GSSMIT
8997807
+   /* MIT style */
8997807
+#  include <gssapi/gssapi.h>
8997807
+#  include <gssapi/gssapi_generic.h>
8997807
+#  include <gssapi/gssapi_krb5.h>
8997807
+#else
8997807
+   /* Heimdal-style */
8997807
+#  include <gssapi.h>
8997807
+#endif
8997807
+
8997807
+void Curl_gss_req_flags(OM_uint32 *req_flags, struct SessionHandle *data);
8997807
+
8997807
+#endif /* HAVE_GSSAPI */
8997807
+
8997807
+#endif /* HEADER_CURL_GSSAPI_H */
8997807
diff --git a/lib/http_negotiate.c b/lib/http_negotiate.c
8997807
index 4b2b254..c33669c 100644
8997807
--- a/lib/http_negotiate.c
8997807
+++ b/lib/http_negotiate.c
8997807
@@ -40,6 +40,7 @@
8997807
 #include "curl_base64.h"
8997807
 #include "http_negotiate.h"
8997807
 #include "curl_memory.h"
8997807
+#include "curl_gssapi.h"
8997807
 
8997807
 #ifdef HAVE_SPNEGO
8997807
 #  include <spnegohelp.h>
8997807
@@ -143,6 +144,9 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
8997807
   bool gss;
8997807
   const char* protocol;
8997807
 
8997807
+  OM_uint32 req_flags = 0;
8997807
+  Curl_gss_req_flags(&req_flags, conn->data);
8997807
+
8997807
   while(*header && ISSPACE(*header))
8997807
     header++;
8997807
   if(checkprefix("GSS-Negotiate", header)) {
8997807
@@ -242,7 +246,7 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
8997807
                                       &neg_ctx->context,
8997807
                                       neg_ctx->server_name,
8997807
                                       GSS_C_NO_OID,
8997807
-                                      0,
8997807
+                                      req_flags,
8997807
                                       0,
8997807
                                       GSS_C_NO_CHANNEL_BINDINGS,
8997807
                                       &input_token,
8997807
diff --git a/lib/krb5.c b/lib/krb5.c
8997807
index 9fb44f2..7e234d1 100644
8997807
--- a/lib/krb5.c
8997807
+++ b/lib/krb5.c
8997807
@@ -65,6 +65,7 @@
8997807
 #include "sendf.h"
8997807
 #include "krb4.h"
8997807
 #include "curl_memory.h"
8997807
+#include "curl_gssapi.h"
8997807
 
8997807
 #define _MPRINTF_REPLACE /* use our functions only */
8997807
 #include <curl/mprintf.h>
8997807
@@ -175,6 +176,9 @@ krb5_auth(void *app_data, struct connectdata *conn)
8997807
   gss_ctx_id_t *context = app_data;
8997807
   struct gss_channel_bindings_struct chan;
8997807
 
8997807
+  OM_uint32 req_flags = GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG;
8997807
+  Curl_gss_req_flags(&req_flags, data);
8997807
+
8997807
   if(getsockname(conn->sock[FIRSTSOCKET],
8997807
                  (struct sockaddr *)LOCAL_ADDR, &l) < 0)
8997807
     perror("getsockname()");
8997807
@@ -233,7 +237,7 @@ krb5_auth(void *app_data, struct connectdata *conn)
8997807
                                  context,
8997807
                                  gssname,
8997807
                                  GSS_C_NO_OID,
8997807
-                                 GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG,
8997807
+                                 req_flags,
8997807
                                  0,
8997807
                                  &chan,
8997807
                                  gssresp,
8997807
diff --git a/lib/socks_gssapi.c b/lib/socks_gssapi.c
8997807
index 1ff6f60..bc7ed85 100644
8997807
--- a/lib/socks_gssapi.c
8997807
+++ b/lib/socks_gssapi.c
8997807
@@ -42,6 +42,7 @@
8997807
 #include "connect.h"
8997807
 #include "timeval.h"
8997807
 #include "socks.h"
8997807
+#include "curl_gssapi.h"
8997807
 
8997807
 static gss_ctx_id_t     gss_context = GSS_C_NO_CONTEXT;
8997807
 
8997807
@@ -138,6 +139,9 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
8997807
   unsigned char socksreq[4]; /* room for gssapi exchange header only */
8997807
   char *serviceptr = data->set.str[STRING_SOCKS5_GSSAPI_SERVICE];
8997807
 
8997807
+  OM_uint32 req_flags = GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG;
8997807
+  Curl_gss_req_flags(&req_flags, data);
8997807
+
8997807
   /* get timeout */
8997807
   timeout = Curl_timeleft(conn, NULL, TRUE);
8997807
 
8997807
@@ -188,8 +192,7 @@ CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex,
8997807
                                             GSS_C_NO_CREDENTIAL,
8997807
                                             &gss_context, server,
8997807
                                             GSS_C_NULL_OID,
8997807
-                                            GSS_C_MUTUAL_FLAG |
8997807
-                                            GSS_C_REPLAY_FLAG,
8997807
+                                            req_flags,
8997807
                                             0,
8997807
                                             NULL,
8997807
                                             gss_token,
8997807
diff --git a/lib/url.c b/lib/url.c
8997807
index 432dac8..ad343ef 100644
8997807
--- a/lib/url.c
8997807
+++ b/lib/url.c
8997807
@@ -1987,6 +1987,12 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
8997807
                        va_arg(param, char *));
8997807
     data->set.krb = (bool)(NULL != data->set.str[STRING_KRB_LEVEL]);
8997807
     break;
8997807
+  case CURLOPT_GSSAPI_DELEGATION:
8997807
+    /*
8997807
+     * GSSAPI credential delegation
8997807
+     */
8997807
+    data->set.gssapi_delegation = va_arg(param, long);
8997807
+    break;
8997807
   case CURLOPT_SSL_VERIFYPEER:
8997807
     /*
8997807
      * Enable peer SSL verifying.
8997807
diff --git a/lib/urldata.h b/lib/urldata.h
8997807
index 7763278..a7df1f2 100644
8997807
--- a/lib/urldata.h
8997807
+++ b/lib/urldata.h
8997807
@@ -1431,6 +1431,9 @@ struct UserDefined {
8997807
   curl_fnmatch_callback fnmatch; /* callback to decide which file corresponds
8997807
                                     to pattern (e.g. if WILDCARDMATCH is on) */
8997807
   void *fnmatch_data;
8997807
+
8997807
+  long gssapi_delegation; /* GSSAPI credential delegation, see the
8997807
+                             documentation of CURLOPT_GSSAPI_DELEGATION */
8997807
 };
8997807
 
8997807
 struct Names {
8997807
-- 
8997807
1.7.4.4
8997807