53#define GSSKRB_APPLE_DEPRECATED(x)
55#if HAVE_GSSAPI_GSSAPI_H
56#include <gssapi/gssapi.h>
60#if HAVE_GSSAPI_GSSAPI_KRB5_H
61#include <gssapi/gssapi_krb5.h>
63#if HAVE_GSSAPI_GSSAPI_GENERIC_H
64#include <gssapi/gssapi_generic.h>
66#if HAVE_GSSAPI_GSSAPI_EXT_H
67#include <gssapi/gssapi_ext.h>
70#ifndef gss_nt_service_name
71#define gss_nt_service_name GSS_C_NT_HOSTBASED_SERVICE
74static const char *
LogTime(
void);
76int check_gss_err(OM_uint32 major_status, OM_uint32 minor_status,
77 const char *function);
79const char *squid_kerb_proxy_auth(
char *proxy);
81#define PROGRAM "negotiate_kerberos_auth_test"
88 static time_t last_t = 0;
91 gettimeofday(&now,
nullptr);
92 if (now.tv_sec != last_t) {
93 tm = localtime((
const time_t *) &now.tv_sec);
94 strftime(buf, 127,
"%Y/%m/%d %H:%M:%S", tm);
100#ifndef gss_mech_spnego
101static gss_OID_desc _gss_mech_spnego = {6, (
void *)
"\x2b\x06\x01\x05\x05\x02"};
102gss_OID gss_mech_spnego = &_gss_mech_spnego;
107 const char *function)
109 if (GSS_ERROR(major_status)) {
110 OM_uint32 maj_stat, min_stat;
111 OM_uint32 msg_ctx = 0;
112 gss_buffer_desc status_string;
120 maj_stat = gss_display_status(&min_stat, major_status,
121 GSS_C_GSS_CODE, GSS_C_NULL_OID, &msg_ctx, &status_string);
122 if (maj_stat == GSS_S_COMPLETE && status_string.length > 0) {
123 if (
sizeof(buf) > len + status_string.length + 1) {
124 snprintf(buf + len, (
sizeof(buf) - len),
"%s", (
char *) status_string.value);
125 len += status_string.length;
129 gss_release_buffer(&min_stat, &status_string);
131 if (
sizeof(buf) > len + 2) {
132 snprintf(buf + len, (
sizeof(buf) - len),
"%s",
". ");
138 maj_stat = gss_display_status(&min_stat, minor_status,
139 GSS_C_MECH_CODE, GSS_C_NULL_OID, &msg_ctx, &status_string);
140 if (maj_stat == GSS_S_COMPLETE && status_string.length > 0) {
141 if (
sizeof(buf) > len + status_string.length) {
142 snprintf(buf + len, (
sizeof(buf) - len),
"%s", (
char *) status_string.value);
143 len += status_string.length;
147 gss_release_buffer(&min_stat, &status_string);
149 fprintf(stderr,
"%s| %s: %s failed: %s\n",
LogTime(),
PROGRAM, function,
157squid_kerb_proxy_auth(
char *proxy)
159 OM_uint32 major_status, minor_status;
160 gss_ctx_id_t gss_context = GSS_C_NO_CONTEXT;
161 gss_name_t server_name = GSS_C_NO_NAME;
162 gss_buffer_desc service = GSS_C_EMPTY_BUFFER;
163 gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
164 gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
165 char *token =
nullptr;
167 setbuf(stdout,
nullptr);
168 setbuf(stdin,
nullptr);
171 fprintf(stderr,
"%s| %s: Error: No proxy server name\n",
LogTime(),
175 service.value =
xmalloc(strlen(
"HTTP") + strlen(proxy) + 2);
176 snprintf((
char *) service.value, strlen(
"HTTP") + strlen(proxy) + 2,
"%s@%s",
"HTTP", proxy);
177 service.length = strlen((
char *) service.value);
179 major_status = gss_import_name(&minor_status, &service,
182 if (!
check_gss_err(major_status, minor_status,
"gss_import_name()")) {
184 major_status = gss_init_sec_context(&minor_status,
185 GSS_C_NO_CREDENTIAL, &gss_context, server_name,
189 GSS_C_NO_CHANNEL_BINDINGS,
190 &input_token,
nullptr, &output_token,
nullptr,
nullptr);
192 if (!
check_gss_err(major_status, minor_status,
"gss_init_sec_context()") && output_token.length) {
196 size_t blen =
base64_encode_update(&ctx, token, output_token.length,
reinterpret_cast<const uint8_t*
>(output_token.value));
201 gss_delete_sec_context(&minor_status, &gss_context,
nullptr);
202 gss_release_buffer(&minor_status, &service);
203 gss_release_buffer(&minor_status, &input_token);
204 gss_release_buffer(&minor_status, &output_token);
205 gss_release_name(&minor_status, &server_name);
211main(
int argc,
char *argv[])
217 fprintf(stderr,
"%s| %s: Error: No proxy server name given\n",
222 count = atoi(argv[2]);
224 Token = (
const char *) squid_kerb_proxy_auth(argv[1]);
225 fprintf(stdout,
"YR %s\n", Token ? Token :
"NULL");
228 fprintf(stdout,
"QQ\n");
230 Token = (
const char *) squid_kerb_proxy_auth(argv[1]);
231 fprintf(stdout,
"Token: %s\n", Token ? Token :
"NULL");
const char * LogTime(void)
void base64_encode_init(struct base64_encode_ctx *ctx)
size_t base64_encode_update(struct base64_encode_ctx *ctx, char *dst, size_t length, const uint8_t *src)
size_t base64_encode_final(struct base64_encode_ctx *ctx, char *dst)
#define base64_encode_len(length)
#define gss_nt_service_name
int check_gss_err(OM_uint32 major_status, OM_uint32 minor_status, const char *function, int log, int sout)
void * xcalloc(size_t n, size_t sz)