aboutsummaryrefslogtreecommitdiff
path: root/lib/http_negotiate.c
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2003-09-11 22:21:11 +0000
committerDaniel Stenberg <daniel@haxx.se>2003-09-11 22:21:11 +0000
commitfd42247cacff58fddba6a2629aa2978241f68402 (patch)
tree507cc95f7c9006a3bd072d071e7c8f694b5cc1a4 /lib/http_negotiate.c
parent0efcb57623189dab5b772ca755841ed7494f04ca (diff)
Tim Bartley's patch that makes the GSSNEGOTIATE option work for Microsoft's
"Negotiate" authentication as well.
Diffstat (limited to 'lib/http_negotiate.c')
-rw-r--r--lib/http_negotiate.c41
1 files changed, 36 insertions, 5 deletions
diff --git a/lib/http_negotiate.c b/lib/http_negotiate.c
index 1a0f2dba4..5012b0764 100644
--- a/lib/http_negotiate.c
+++ b/lib/http_negotiate.c
@@ -50,24 +50,35 @@
static int
get_gss_name(struct connectdata *conn, gss_name_t *server)
{
+ struct negotiatedata *neg_ctx = &conn->data->state.negotiate;
OM_uint32 major_status, minor_status;
gss_buffer_desc token = GSS_C_EMPTY_BUFFER;
char name[2048];
+ const char* service;
/* GSSAPI implementation by Globus (known as GSI) requires the name to be
of form "<service>/<fqdn>" instead of <service>@<fqdn> (ie. slash instead
of at-sign). Also GSI servers are often identified as 'host' not 'khttp'.
Change following lines if you want to use GSI */
- token.length = strlen("khttp@") + strlen(conn->hostname) + 1;
+
+ /* 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(conn->hostname) + 1;
if (token.length + 1 > sizeof(name))
return EMSGSIZE;
- sprintf(name, "khttp@%s", conn->hostname);
+ sprintf(name, "%s@%s", service, conn->hostname);
token.value = (void *) name;
major_status = gss_import_name(&minor_status,
&token,
GSS_C_NT_HOSTBASED_SERVICE,
server);
+
return GSS_ERROR(major_status) ? -1 : 0;
}
@@ -107,12 +118,32 @@ int Curl_input_negotiate(struct connectdata *conn, char *header)
gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
int ret;
size_t len;
+ bool gss;
+ const char* protocol;
while(*header && isspace((int)*header))
header++;
- if(!checkprefix("GSS-Negotiate", header))
+ if(checkprefix("GSS-Negotiate", header)) {
+ protocol = "GSS-Negotiate";
+ gss = TRUE;
+ }
+ else if (checkprefix("Negotiate", header)) {
+ protocol = "Negotiate";
+ gss = FALSE;
+ }
+ else
return -1;
+ if (neg_ctx->context) {
+ if (neg_ctx->gss != gss) {
+ return -1;
+ }
+ }
+ else {
+ neg_ctx->protocol = protocol;
+ neg_ctx->gss = gss;
+ }
+
if (neg_ctx->context && neg_ctx->status == GSS_S_COMPLETE) {
/* We finished succesfully our part of authentication, but server
* rejected it (since we're again here). Exit with an error since we
@@ -125,7 +156,7 @@ int Curl_input_negotiate(struct connectdata *conn, char *header)
(ret = get_gss_name(conn, &neg_ctx->server_name)))
return ret;
- header += strlen("GSS-Negotiate");
+ header += strlen(neg_ctx->protocol);
while(*header && isspace((int)*header))
header++;
@@ -188,7 +219,7 @@ CURLcode Curl_output_negotiate(struct connectdata *conn)
return CURLE_OUT_OF_MEMORY;
conn->allocptr.userpwd =
- aprintf("Authorization: GSS-Negotiate %s\r\n", encoded);
+ aprintf("Authorization: %s %s\r\n", neg_ctx->protocol, encoded);
free(encoded);
gss_release_buffer(&minor_status, &neg_ctx->output_token);
return (conn->allocptr.userpwd == NULL) ? CURLE_OUT_OF_MEMORY : CURLE_OK;