From d4b7b722e13ac97aa4ecd6f515c577bc4c40129b Mon Sep 17 00:00:00 2001
From: Julien Chaffraix <julien.chaffraix@gmail.com>
Date: Fri, 10 Jun 2011 08:16:06 -0700
Subject: [PATCH] Added Curl_gss_init_sec_context.

This function wraps our calls to gss_init_sec_context so that we
have a unified way to talk to GSSAPI.

cherry-picked from commit 20485a48858ea35351ca69060f56353eace0521c
---
 lib/Makefile.inc     |    4 +-
 lib/gssapi.c         |   53 ++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/gssapi.h         |   53 ++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/http_negotiate.c |   28 ++++++++++++++------------
 lib/krb5.c           |   36 +++++++++++++--------------------
 lib/socks_gssapi.c   |   27 +++++++++++++------------
 6 files changed, 151 insertions(+), 50 deletions(-)
 create mode 100644 lib/gssapi.c
 create mode 100644 lib/gssapi.h

diff --git a/lib/Makefile.inc b/lib/Makefile.inc
index 1b619a3..343095e 100644
--- a/lib/Makefile.inc
+++ b/lib/Makefile.inc
@@ -11,7 +11,7 @@ CSOURCES = file.c timeval.c base64.c hostip.c progress.c formdata.c	\
   inet_ntop.c parsedate.c select.c gtls.c sslgen.c tftp.c splay.c	\
   strdup.c socks.c ssh.c nss.c qssl.c rawstr.c curl_addrinfo.c          \
   socks_gssapi.c socks_sspi.c curl_sspi.c slist.c nonblock.c		\
-  curl_memrchr.c
+  curl_memrchr.c gssapi.c
 
 HHEADERS = arpa_telnet.h netrc.h file.h timeval.h qssl.h hostip.h	\
   progress.h formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h	\
@@ -23,5 +23,5 @@ HHEADERS = arpa_telnet.h netrc.h file.h timeval.h qssl.h hostip.h	\
   transfer.h select.h easyif.h multiif.h parsedate.h sslgen.h gtls.h	\
   tftp.h sockaddr.h splay.h strdup.h setup_once.h socks.h ssh.h nssg.h	\
   curl_base64.h rawstr.h curl_addrinfo.h curl_sspi.h slist.h nonblock.h	\
-  curl_memrchr.h
+  curl_memrchr.h gssapi.h
 
diff --git a/lib/gssapi.c b/lib/gssapi.c
new file mode 100644
index 0000000..dc777c7
--- /dev/null
+++ b/lib/gssapi.c
@@ -0,0 +1,53 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "gssapi.h"
+
+OM_uint32 Curl_gss_init_sec_context(
+    OM_uint32 * minor_status,
+    gss_cred_id_t cred_handle,
+    gss_ctx_id_t * context,
+    gss_name_t target_name,
+    gss_OID mech_type, /* needed? */
+    OM_uint32 req_flags,          /* TBR. */
+    OM_uint32 time_req,
+    gss_channel_bindings_t input_chan_bindings,
+    gss_buffer_t input_token,
+    gss_OID * actual_mech_type,
+    gss_buffer_t output_token,
+    OM_uint32 * ret_flags,
+    OM_uint32 * time_rec)
+{
+  return gss_init_sec_context(minor_status,
+                              cred_handle,
+                              context,
+                              target_name,
+                              mech_type,
+                              req_flags,
+                              time_req,
+                              input_chan_bindings,
+                              input_token,
+                              actual_mech_type,
+                              output_token,
+                              ret_flags,
+                              time_rec);
+}
diff --git a/lib/gssapi.h b/lib/gssapi.h
new file mode 100644
index 0000000..c2a0797
--- /dev/null
+++ b/lib/gssapi.h
@@ -0,0 +1,53 @@
+/***************************************************************************
+ *                                  _   _ ____  _
+ *  Project                     ___| | | |  _ \| |
+ *                             / __| | | | |_) | |
+ *                            | (__| |_| |  _ <| |___
+ *                             \___|\___/|_| \_\_____|
+ *
+ * Copyright (C) 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://curl.haxx.se/docs/copyright.html.
+ *
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
+ * copies of the Software, and permit persons to whom the Software is
+ * furnished to do so, under the terms of the COPYING file.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ***************************************************************************/
+
+#include "setup.h"
+
+#ifdef HAVE_GSSGNU
+#  include <gss.h>
+#elif defined HAVE_GSSMIT
+   /* MIT style */
+#  include <gssapi/gssapi.h>
+#  include <gssapi/gssapi_generic.h>
+#  include <gssapi/gssapi_krb5.h>
+#else
+   /* Heimdal-style */
+#  include <gssapi.h>
+#endif
+
+
+/* Common method for using gss api */
+
+OM_uint32 Curl_gss_init_sec_context(
+    OM_uint32 * minor_status,
+    gss_cred_id_t cred_handle,
+    gss_ctx_id_t * context,
+    gss_name_t target_name,
+    gss_OID,            /* mech_type (used to be const) */
+    OM_uint32,          /* req_flags */
+    OM_uint32,          /* time_req */
+    gss_channel_bindings_t,     /* input_chan_bindings */
+    gss_buffer_t,       /* input_token */
+    gss_OID *,          /* actual_mech_type */
+    gss_buffer_t,       /* output_token */
+    OM_uint32 *,        /* ret_flags */
+    OM_uint32 *);       /* time_rec */
diff --git a/lib/http_negotiate.c b/lib/http_negotiate.c
index 4a2e9b0..2642481 100644
--- a/lib/http_negotiate.c
+++ b/lib/http_negotiate.c
@@ -37,6 +37,7 @@
 
 #include "urldata.h"
 #include "sendf.h"
+#include "gssapi.h"
 #include "rawstr.h"
 #include "curl_base64.h"
 #include "http_negotiate.h"
@@ -238,19 +239,20 @@ int Curl_input_negotiate(struct connectdata *conn, bool proxy,
 #endif
   }
 
-  major_status = gss_init_sec_context(&minor_status,
-                                      GSS_C_NO_CREDENTIAL,
-                                      &neg_ctx->context,
-                                      neg_ctx->server_name,
-                                      GSS_C_NO_OID,
-                                      GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG,
-                                      0,
-                                      GSS_C_NO_CHANNEL_BINDINGS,
-                                      &input_token,
-                                      NULL,
-                                      &output_token,
-                                      NULL,
-                                      NULL);
+  major_status = Curl_gss_init_sec_context(&minor_status,
+                                           GSS_C_NO_CREDENTIAL,
+                                           &neg_ctx->context,
+                                           neg_ctx->server_name,
+                                           GSS_C_NO_OID,
+                                           GSS_C_MUTUAL_FLAG
+                                           | GSS_C_REPLAY_FLAG,
+                                           0,
+                                           GSS_C_NO_CHANNEL_BINDINGS,
+                                           &input_token,
+                                           NULL,
+                                           &output_token,
+                                           NULL,
+                                           NULL);
   if(input_token.length > 0)
     gss_release_buffer(&minor_status2, &input_token);
   neg_ctx->status = major_status;
diff --git a/lib/krb5.c b/lib/krb5.c
index 8aaa0cb..f599dd1 100644
--- a/lib/krb5.c
+++ b/lib/krb5.c
@@ -46,19 +46,11 @@
 #include <netdb.h>
 #endif
 #include <string.h>
-#ifdef HAVE_GSSMIT
-/* MIT style */
-#include <gssapi/gssapi.h>
-#include <gssapi/gssapi_generic.h>
-#include <gssapi/gssapi_krb5.h>
-#else
-/* Heimdal-style */
-#include <gssapi.h>
-#endif
 
 #include "urldata.h"
 #include "curl_base64.h"
 #include "ftp.h"
+#include "gssapi.h"
 #include "sendf.h"
 #include "krb4.h"
 #include "curl_memory.h"
@@ -228,19 +220,19 @@ 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 = gss_init_sec_context(&min,
-                                 GSS_C_NO_CREDENTIAL,
-                                 context,
-                                 gssname,
-                                 GSS_C_NO_OID,
-                                 GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG,
-                                 0,
-                                 &chan,
-                                 gssresp,
-                                 NULL,
-                                 &output_buffer,
-                                 NULL,
-                                 NULL);
+      maj = Curl_gss_init_sec_context(&min,
+                                      GSS_C_NO_CREDENTIAL,
+                                      context,
+                                      gssname,
+                                      GSS_C_NO_OID,
+                                      GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG,
+                                      0,
+                                      &chan,
+                                      gssresp,
+                                      NULL,
+                                      &output_buffer,
+                                      NULL,
+                                      NULL);
 
       if(gssresp) {
         free(_gssresp.value);
diff --git a/lib/socks_gssapi.c b/lib/socks_gssapi.c
index 8b5ccf7..d9b38f3 100644
--- a/lib/socks_gssapi.c
+++ b/lib/socks_gssapi.c
@@ -38,6 +38,7 @@
 #include <stdlib.h>
 #endif
 
+#include "gssapi.h"
 #include "urldata.h"
 #include "sendf.h"
 #include "connect.h"
@@ -184,19 +185,19 @@ 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 = gss_init_sec_context(&gss_minor_status,
-                                            GSS_C_NO_CREDENTIAL,
-                                            &gss_context, server,
-                                            GSS_C_NULL_OID,
-                                            GSS_C_MUTUAL_FLAG |
-                                            GSS_C_REPLAY_FLAG,
-                                            0,
-                                            NULL,
-                                            gss_token,
-                                            NULL,
-                                            &gss_send_token,
-                                            &gss_ret_flags,
-                                            NULL);
+    gss_major_status = Curl_gss_init_sec_context(&gss_minor_status,
+                                                 GSS_C_NO_CREDENTIAL,
+                                                 &gss_context, server,
+                                                 GSS_C_NULL_OID,
+                                                 GSS_C_MUTUAL_FLAG |
+                                                 GSS_C_REPLAY_FLAG,
+                                                 0,
+                                                 NULL,
+                                                 gss_token,
+                                                 NULL,
+                                                 &gss_send_token,
+                                                 &gss_ret_flags,
+                                                 NULL);
 
     if(gss_token != GSS_C_NO_BUFFER)
       gss_release_buffer(&gss_status, &gss_recv_token);
-- 
1.7.6.1

