]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
squidclient: shuffle GSSAPI logic into separate file(s)
authorAmos Jeffries <squid3@treenet.co.nz>
Sun, 30 Mar 2014 01:47:38 +0000 (18:47 -0700)
committerAmos Jeffries <squid3@treenet.co.nz>
Sun, 30 Mar 2014 01:47:38 +0000 (18:47 -0700)
tools/squidclient/Makefile.am
tools/squidclient/gssapi_support.cc [new file with mode: 0644]
tools/squidclient/gssapi_support.h [new file with mode: 0644]
tools/squidclient/squidclient.cc

index 150613288d62d0c6ba7d67e5b950602d7665fb2d..bd90808b2b52f9b169a56cd266de5f2041dcc2fe 100644 (file)
@@ -41,6 +41,8 @@ CLEANFILES += test_tools.cc stub_debug.cc time.cc
 bin_PROGRAMS = squidclient
 
 squidclient_SOURCES = \
+       gssapi_support.cc \
+       gssapi_support.h \
        Parameters.h \
        Ping.cc \
        Ping.h \
diff --git a/tools/squidclient/gssapi_support.cc b/tools/squidclient/gssapi_support.cc
new file mode 100644 (file)
index 0000000..7f6cf89
--- /dev/null
@@ -0,0 +1,137 @@
+#include "squid.h"
+#include "base64.h"
+#include "tools/squidclient/gssapi_support.h"
+
+#if HAVE_GSSAPI
+
+#if !defined(gss_mech_spnego)
+static gss_OID_desc _gss_mech_spnego = {6, (void *) "\x2b\x06\x01\x05\x05\x02"};
+gss_OID gss_mech_spnego = &_gss_mech_spnego;
+#endif
+
+#define BUFFER_SIZE 8192
+
+/**
+ * Check return valuse major_status, minor_status for error and print error description
+ * in case of an error.
+ *
+ * \retval true in case of gssapi error
+ * \retval false in case of no gssapi error
+ */
+bool
+check_gss_err(OM_uint32 major_status, OM_uint32 minor_status, const char *function)
+{
+    if (GSS_ERROR(major_status)) {
+        OM_uint32 maj_stat, min_stat;
+        OM_uint32 msg_ctx = 0;
+        gss_buffer_desc status_string;
+        char buf[BUFFER_SIZE];
+        size_t len;
+
+        len = 0;
+        msg_ctx = 0;
+        while (!msg_ctx) {
+            /* convert major status code (GSS-API error) to text */
+            maj_stat = gss_display_status(&min_stat, major_status,
+                                          GSS_C_GSS_CODE,
+                                          GSS_C_NULL_OID,
+                                          &msg_ctx, &status_string);
+            if (maj_stat == GSS_S_COMPLETE) {
+                snprintf(buf + len, BUFFER_SIZE-len, "%s", (char *) status_string.value);
+                len += status_string.length;
+                gss_release_buffer(&min_stat, &status_string);
+                break;
+            }
+            gss_release_buffer(&min_stat, &status_string);
+        }
+        snprintf(buf + len, BUFFER_SIZE-len, "%s", ". ");
+        len += 2;
+        msg_ctx = 0;
+        while (!msg_ctx) {
+            /* convert minor status code (underlying routine error) to text */
+            maj_stat = gss_display_status(&min_stat, minor_status,
+                                          GSS_C_MECH_CODE,
+                                          GSS_C_NULL_OID,
+                                          &msg_ctx, &status_string);
+            if (maj_stat == GSS_S_COMPLETE) {
+                snprintf(buf + len, BUFFER_SIZE-len,"%s", (char *) status_string.value);
+                len += status_string.length;
+                gss_release_buffer(&min_stat, &status_string);
+                break;
+            }
+            gss_release_buffer(&min_stat, &status_string);
+        }
+        std::cerr << "ERROR: " << function << " failed: " << buf << std::endl;
+        return true;
+    }
+    return false;
+}
+
+/**
+ * Get gssapi token for service HTTP/<server>
+ * User has to initiate a kinit user@DOMAIN on commandline first for the
+ * function to be successful
+ *
+ * \return base64 encoded token if successful,
+ *         string "ERROR" if unsuccessful
+ */
+char *
+GSSAPI_token(const char *server)
+{
+    OM_uint32 major_status, minor_status;
+    gss_ctx_id_t gss_context = GSS_C_NO_CONTEXT;
+    gss_name_t server_name = GSS_C_NO_NAME;
+    gss_buffer_desc service = GSS_C_EMPTY_BUFFER;
+    gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
+    gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
+    char *token = NULL;
+
+    setbuf(stdout, NULL);
+    setbuf(stdin, NULL);
+
+    if (!server) {
+        std::cerr << "ERROR: GSSAPI: No server name" << std::endl;
+        return (char *)"ERROR";
+    }
+    service.value = xmalloc(strlen("HTTP") + strlen(server) + 2);
+    snprintf((char *) service.value, strlen("HTTP") + strlen(server) + 2, "%s@%s", "HTTP", server);
+    service.length = strlen((char *) service.value);
+
+    major_status = gss_import_name(&minor_status, &service,
+                                   gss_nt_service_name, &server_name);
+
+    if (!check_gss_err(major_status, minor_status, "gss_import_name()")) {
+
+        major_status = gss_init_sec_context(&minor_status,
+                                            GSS_C_NO_CREDENTIAL,
+                                            &gss_context,
+                                            server_name,
+                                            gss_mech_spnego,
+                                            0,
+                                            0,
+                                            GSS_C_NO_CHANNEL_BINDINGS,
+                                            &input_token,
+                                            NULL,
+                                            &output_token,
+                                            NULL,
+                                            NULL);
+
+        if (!check_gss_err(major_status, minor_status, "gss_init_sec_context()")) {
+
+            if (output_token.length)
+                token = (char *) base64_encode_bin((const char *) output_token.value, output_token.length);
+        }
+    }
+
+    if (!output_token.length)
+        token = (char *) "ERROR";
+    gss_delete_sec_context(&minor_status, &gss_context, NULL);
+    gss_release_buffer(&minor_status, &service);
+    gss_release_buffer(&minor_status, &input_token);
+    gss_release_buffer(&minor_status, &output_token);
+    gss_release_name(&minor_status, &server_name);
+
+    return token;
+}
+
+#endif /* HAVE_GSSAPI */
diff --git a/tools/squidclient/gssapi_support.h b/tools/squidclient/gssapi_support.h
new file mode 100644 (file)
index 0000000..5b43922
--- /dev/null
@@ -0,0 +1,32 @@
+#ifndef _SQUID_TOOLS_SQUIDCLIENT_GSSAPI_H
+#define _SQUID_TOOLS_SQUIDCLIENT_GSSAPI_H
+
+#if HAVE_GSSAPI
+
+#if HAVE_GSSAPI_GSSAPI_H
+#include <gssapi/gssapi.h>
+#elif HAVE_GSSAPI_H
+#include <gssapi.h>
+#endif /* HAVE_GSSAPI_GSSAPI_H/HAVE_GSSAPI_H */
+
+#if !HAVE_HEIMDAL_KERBEROS
+#if HAVE_GSSAPI_GSSAPI_KRB5_H
+#include <gssapi/gssapi_krb5.h>
+#endif
+#if HAVE_GSSAPI_GSSAPI_GENERIC_H
+#include <gssapi/gssapi_generic.h>
+#endif
+#if HAVE_GSSAPI_GSSAPI_EXT_H
+#include <gssapi/gssapi_ext.h>
+#endif
+#endif
+
+#ifndef gss_nt_service_name
+#define gss_nt_service_name GSS_C_NT_HOSTBASED_SERVICE
+#endif
+
+bool check_gss_err(OM_uint32 major_status, OM_uint32 minor_status, const char *function);
+char *GSSAPI_token(const char *server);
+
+#endif /* HAVE_GSSAPI */
+#endif /* _SQUID_TOOLS_SQUIDCLIENT_GSSAPI_H */
index 9a3f43b6d6ddc99f0f9db5b01ea3da35531d3399..06019cb15c0a2f7c37cf1eaba476bcdf99e8f783 100644 (file)
@@ -35,6 +35,7 @@
 #include "ip/Address.h"
 #include "ip/tools.h"
 #include "rfc1123.h"
+#include "tools/squidclient/gssapi_support.h"
 #include "tools/squidclient/Parameters.h"
 #include "tools/squidclient/Ping.h"
 
@@ -73,34 +74,6 @@ using namespace Squid;
 #include <getopt.h>
 #endif
 
-#if HAVE_GSSAPI
-#if HAVE_GSSAPI_GSSAPI_H
-#include <gssapi/gssapi.h>
-#elif HAVE_GSSAPI_H
-#include <gssapi.h>
-#endif /* HAVE_GSSAPI_GSSAPI_H/HAVE_GSSAPI_H */
-#if !HAVE_HEIMDAL_KERBEROS
-#if HAVE_GSSAPI_GSSAPI_KRB5_H
-#include <gssapi/gssapi_krb5.h>
-#endif
-#if HAVE_GSSAPI_GSSAPI_GENERIC_H
-#include <gssapi/gssapi_generic.h>
-#endif
-#if HAVE_GSSAPI_GSSAPI_EXT_H
-#include <gssapi/gssapi_ext.h>
-#endif
-#endif
-
-#ifndef gss_nt_service_name
-#define gss_nt_service_name GSS_C_NT_HOSTBASED_SERVICE
-#endif
-
-#ifndef gss_mech_spnego
-static gss_OID_desc _gss_mech_spnego = {6, (void *) "\x2b\x06\x01\x05\x05\x02"};
-gss_OID gss_mech_spnego = &_gss_mech_spnego;
-#endif
-#endif /* HAVE_GSSAPI */
-
 #ifndef BUFSIZ
 #define BUFSIZ         8192
 #endif
@@ -126,11 +99,6 @@ static void set_our_signal(void);
 static ssize_t myread(int fd, void *buf, size_t len);
 static ssize_t mywrite(int fd, void *buf, size_t len);
 
-#if HAVE_GSSAPI
-static bool check_gss_err(OM_uint32 major_status, OM_uint32 minor_status, const char *function);
-static char *GSSAPI_token(const char *server);
-#endif
-
 Parameters scParams;
 
 static int put_fd;
@@ -738,129 +706,3 @@ mywrite(int fd, void *buf, size_t len)
     return write(fd, buf, len);
 #endif
 }
-
-#if HAVE_GSSAPI
-#define BUFFER_SIZE 8192
-/**
- * Check return valuse major_status, minor_status for error and print error description
- * in case of an error.
- *
- * \retval true in case of gssapi error
- * \retval false in case of no gssapi error
- */
-static bool
-check_gss_err(OM_uint32 major_status, OM_uint32 minor_status, const char *function)
-{
-    if (GSS_ERROR(major_status)) {
-        OM_uint32 maj_stat, min_stat;
-        OM_uint32 msg_ctx = 0;
-        gss_buffer_desc status_string;
-        char buf[BUFFER_SIZE];
-        size_t len;
-
-        len = 0;
-        msg_ctx = 0;
-        while (!msg_ctx) {
-            /* convert major status code (GSS-API error) to text */
-            maj_stat = gss_display_status(&min_stat, major_status,
-                                          GSS_C_GSS_CODE,
-                                          GSS_C_NULL_OID,
-                                          &msg_ctx, &status_string);
-            if (maj_stat == GSS_S_COMPLETE) {
-                snprintf(buf + len, BUFFER_SIZE-len, "%s", (char *) status_string.value);
-                len += status_string.length;
-                gss_release_buffer(&min_stat, &status_string);
-                break;
-            }
-            gss_release_buffer(&min_stat, &status_string);
-        }
-        snprintf(buf + len, BUFFER_SIZE-len, "%s", ". ");
-        len += 2;
-        msg_ctx = 0;
-        while (!msg_ctx) {
-            /* convert minor status code (underlying routine error) to text */
-            maj_stat = gss_display_status(&min_stat, minor_status,
-                                          GSS_C_MECH_CODE,
-                                          GSS_C_NULL_OID,
-                                          &msg_ctx, &status_string);
-            if (maj_stat == GSS_S_COMPLETE) {
-                snprintf(buf + len, BUFFER_SIZE-len,"%s", (char *) status_string.value);
-                len += status_string.length;
-                gss_release_buffer(&min_stat, &status_string);
-                break;
-            }
-            gss_release_buffer(&min_stat, &status_string);
-        }
-        std::cerr << "ERROR: " << function << " failed: " << buf << std::endl;
-        return true;
-    }
-    return false;
-}
-
-/**
- * Get gssapi token for service HTTP/<server>
- * User has to initiate a kinit user@DOMAIN on commandline first for the
- * function to be successful
- *
- * \return base64 encoded token if successful,
- *         string "ERROR" if unsuccessful
- */
-static char *
-GSSAPI_token(const char *server)
-{
-    OM_uint32 major_status, minor_status;
-    gss_ctx_id_t gss_context = GSS_C_NO_CONTEXT;
-    gss_name_t server_name = GSS_C_NO_NAME;
-    gss_buffer_desc service = GSS_C_EMPTY_BUFFER;
-    gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
-    gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
-    char *token = NULL;
-
-    setbuf(stdout, NULL);
-    setbuf(stdin, NULL);
-
-    if (!server) {
-        std::cerr << "ERROR: GSSAPI: No server name" << std::endl;
-        return (char *)"ERROR";
-    }
-    service.value = xmalloc(strlen("HTTP") + strlen(server) + 2);
-    snprintf((char *) service.value, strlen("HTTP") + strlen(server) + 2, "%s@%s", "HTTP", server);
-    service.length = strlen((char *) service.value);
-
-    major_status = gss_import_name(&minor_status, &service,
-                                   gss_nt_service_name, &server_name);
-
-    if (!check_gss_err(major_status, minor_status, "gss_import_name()")) {
-
-        major_status = gss_init_sec_context(&minor_status,
-                                            GSS_C_NO_CREDENTIAL,
-                                            &gss_context,
-                                            server_name,
-                                            gss_mech_spnego,
-                                            0,
-                                            0,
-                                            GSS_C_NO_CHANNEL_BINDINGS,
-                                            &input_token,
-                                            NULL,
-                                            &output_token,
-                                            NULL,
-                                            NULL);
-
-        if (!check_gss_err(major_status, minor_status, "gss_init_sec_context()")) {
-
-            if (output_token.length)
-                token = (char *) base64_encode_bin((const char *) output_token.value, output_token.length);
-        }
-    }
-
-    if (!output_token.length)
-        token = (char *) "ERROR";
-    gss_delete_sec_context(&minor_status, &gss_context, NULL);
-    gss_release_buffer(&minor_status, &service);
-    gss_release_buffer(&minor_status, &input_token);
-    gss_release_buffer(&minor_status, &output_token);
-    gss_release_name(&minor_status, &server_name);
-
-    return token;
-}
-#endif