--- /dev/null
+#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 */
#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"
#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
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;
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