cURL / Mailing Lists / curl-library / Single Mail

curl-library

[patch RFC] Add option to set Kerberos name

From: Pete Zaitcev <zaitcev_at_redhat.com>
Date: Wed, 20 Jul 2011 14:07:50 -0600

This patch comes about because of a need to run a RESTful API service
with Kerberos authentication on a system which already has a webserver.
Specifically this:
 https://fedorahosted.org/pipermail/iwhd-devel/2011-June/000691.html

As you can see, it necesserily conflicts with any patch that adds
new options, since we have them all numbered. For now I'd like someone
to comment if I am even doing the right thing here. I have no problem
maintaining the patch while we discuss it, in particular moving it
on top of Adam's patch if it gets into a release.

-- Pete

diff -urp curl-7.21.7/include/curl/curl.h curl-7.21.7-p3/include/curl/curl.h
--- curl-7.21.7/include/curl/curl.h 2011-05-18 14:56:46.000000000 -0600
+++ curl-7.21.7-p3/include/curl/curl.h 2011-07-06 11:32:23.406124005 -0600
@@ -1483,6 +1483,9 @@ typedef enum {
   CINIT(CLOSESOCKETFUNCTION, FUNCTIONPOINT, 208),
   CINIT(CLOSESOCKETDATA, OBJECTPOINT, 209),
 
+ /* Usually HTTP_at_host.domain, but not always. */
+ CINIT(KRBSVCNAME, OBJECTPOINT, 210),
+
   CURLOPT_LASTENTRY /* the last unused */
 } CURLoption;
 
diff -urp curl-7.21.7/lib/http_negotiate.c curl-7.21.7-p3/lib/http_negotiate.c
--- curl-7.21.7/lib/http_negotiate.c 2011-06-22 15:04:26.000000000 -0600
+++ curl-7.21.7-p3/lib/http_negotiate.c 2011-07-16 20:57:41.298671005 -0600
@@ -69,6 +69,7 @@ get_gss_name(struct connectdata *conn, b
   gss_buffer_desc token = GSS_C_EMPTY_BUFFER;
   char name[2048];
   const char* service;
+ int len;
 
   /* GSSAPI implementation by Globus (known as GSI) requires the name to be
      of form "<service>/<fqdn>" instead of <service>@<fqdn> (ie. slash instead
@@ -77,20 +78,24 @@ get_gss_name(struct connectdata *conn, b
 
   /* IIS uses the <service>@<fqdn> form but uses 'http' as the service name */
 
- if(neg_ctx->gss)
- service = "KHTTP";
- else
- service = "HTTP";
-
- token.length = strlen(service) + 1 + strlen(proxy ? conn->proxy.name :
- conn->host.name) + 1;
- if(token.length + 1 > sizeof(name))
+ service = conn->data->set.str[STRING_KRB_SVCNAME];
+ if(service && (strchr(service,'@') || strchr(service,'/'))) {
+ len = snprintf(name, sizeof(name), "%s", service);
+ } else {
+ if(service == NULL) {
+ if(neg_ctx->gss)
+ service = "KHTTP";
+ else
+ service = "HTTP";
+ }
+ len = snprintf(name, sizeof(name), "%s@%s", service,
+ proxy ? conn->proxy.name : conn->host.name);
+ }
+ if(len >= sizeof(name))
     return EMSGSIZE;
 
- snprintf(name, sizeof(name), "%s@%s", service, proxy ? conn->proxy.name :
- conn->host.name);
-
   token.value = (void *) name;
+ token.length = len;
   major_status = gss_import_name(&minor_status,
                                  &token,
                                  GSS_C_NT_HOSTBASED_SERVICE,
diff -urp curl-7.21.7/lib/url.c curl-7.21.7-p3/lib/url.c
--- curl-7.21.7/lib/url.c 2011-06-13 15:09:52.000000000 -0600
+++ curl-7.21.7-p3/lib/url.c 2011-07-06 11:32:23.427124003 -0600
@@ -1985,6 +1985,14 @@ CURLcode Curl_setopt(struct SessionHandl
                        va_arg(param, char *));
     data->set.krb = (bool)(NULL != data->set.str[STRING_KRB_LEVEL]);
     break;
+ case CURLOPT_KRBSVCNAME:
+ /*
+ * A string that defines the kerberos service name, such as KHTTP.
+ */
+ result = setstropt(&data->set.str[STRING_KRB_SVCNAME],
+ va_arg(param, char *));
+ // data->set.krbsvcname = data->set.str[STRING_KRB_LEVEL];
+ break;
   case CURLOPT_SSL_VERIFYPEER:
     /*
      * Enable peer SSL verifying.
diff -urp curl-7.21.7/lib/urldata.h curl-7.21.7-p3/lib/urldata.h
--- curl-7.21.7/lib/urldata.h 2011-06-07 11:31:53.000000000 -0600
+++ curl-7.21.7-p3/lib/urldata.h 2011-07-06 11:32:23.437124005 -0600
@@ -1283,6 +1283,7 @@ enum dupstring {
   STRING_KEY_PASSWD, /* plain text private key password */
   STRING_KEY_TYPE, /* format for private key (default: PEM) */
   STRING_KRB_LEVEL, /* krb security level */
+ STRING_KRB_SVCNAME, /* krb service */
   STRING_NETRC_FILE, /* if not NULL, use this instead of trying to find
                              $HOME/.netrc */
   STRING_COPYPOSTFIELDS, /* if POST, set the fields' values here */
diff -urp curl-7.21.7/src/main.c curl-7.21.7-p3/src/main.c
--- curl-7.21.7/src/main.c 2011-05-30 03:59:13.000000000 -0600
+++ curl-7.21.7-p3/src/main.c 2011-07-06 11:32:23.440124005 -0600
@@ -580,6 +580,7 @@ struct Configurable {
   bool crlf;
   char *customrequest;
   char *krblevel;
+ char *krbsvcname;
   char *trace_dump; /* file to dump the network trace to, or NULL */
   FILE *trace_stream;
   bool trace_fopened;
@@ -861,6 +862,7 @@ static void help(void)
     " --key <key> Private key file name (SSL/SSH)",
     " --key-type <type> Private key file type (DER/PEM/ENG) (SSL)",
     " --krb <level> Enable Kerberos with specified security level (F)",
+ " --krb-svc-name <name> Set Kerberos name of service (H)",
     " --libcurl <file> Dump libcurl equivalent code of this command line",
     " --limit-rate <rate> Limit transfer speed to this rate",
     " -J/--remote-header-name Use the header-provided filename (H)",
@@ -1904,6 +1906,7 @@ static ParameterError getparameter(char
     {"$h", "retry-delay", TRUE},
     {"$i", "retry-max-time", TRUE},
     {"$k", "proxy-negotiate", FALSE},
+ {"$l", "krb-svc-name", TRUE},
     {"$m", "ftp-account", TRUE},
     {"$n", "proxy-anyauth", FALSE},
     {"$o", "trace-time", FALSE},
@@ -2384,13 +2387,15 @@ static ParameterError getparameter(char
         if(str2num(&config->retry_maxtime, nextarg))
           return PARAM_BAD_NUMERIC;
         break;
-
       case 'k': /* --proxy-negotiate */
         if(curlinfo->features & CURL_VERSION_GSSNEGOTIATE)
           config->proxynegotiate = toggle;
         else
           return PARAM_LIBCURL_DOESNT_SUPPORT;
         break;
+ case 'l': /* --krb-svc-name */
+ GetStr(&config->krbsvcname, nextarg);
+ break;
       case 'm': /* --ftp-account */
         GetStr(&config->ftp_account, nextarg);
         break;
@@ -4086,6 +4091,8 @@ static void free_config_fields(struct Co
     free(config->cookiefile);
   if(config->krblevel)
     free(config->krblevel);
+ if(config->krbsvcname)
+ free(config->krbsvcname);
   if(config->headerfile)
     free(config->headerfile);
   if(config->ftpport)
@@ -5371,6 +5378,7 @@ operate(struct Configurable *config, int
         my_setopt(curl, CURLOPT_HTTPPROXYTUNNEL, config->proxytunnel);
         my_setopt_str(curl, CURLOPT_INTERFACE, config->iface);
         my_setopt_str(curl, CURLOPT_KRBLEVEL, config->krblevel);
+ my_setopt_str(curl, CURLOPT_KRBSVCNAME, config->krbsvcname);
 
         progressbarinit(&progressbar, config);
         if((config->progressmode == CURL_PROGRESS_BAR) &&
-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html
Received on 2011-07-20