]> git.ipfire.org Git - thirdparty/squid.git/blame - helpers/negotiate_auth/kerberos/negotiate_kerberos_auth_test.cc
SourceFormat Enforcement
[thirdparty/squid.git] / helpers / negotiate_auth / kerberos / negotiate_kerberos_auth_test.cc
CommitLineData
ca02e0ec
AJ
1/*
2 * Copyright (C) 1996-2014 The Squid Software Foundation and contributors
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
ba4fe07c
AJ
9/*
10 * -----------------------------------------------------------------------------
11 *
12 * Author: Markus Moeller (markus_moeller at compuserve.com)
13 *
14 * Copyright (C) 2007 Markus Moeller. All rights reserved.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
29 *
30 * -----------------------------------------------------------------------------
31 */
ba4fe07c 32
f7f3304a 33#include "squid.h"
d1f95b42 34
3ad12bda 35#if HAVE_GSSAPI
70125c34 36
074d6a40
AJ
37#include <cerrno>
38#include <cstring>
39#include <ctime>
70125c34 40#if HAVE_NETDB_H
ba4fe07c 41#include <netdb.h>
70125c34
AJ
42#endif
43#if HAVE_UNISTD_H
ba4fe07c 44#include <unistd.h>
70125c34 45#endif
ba4fe07c 46
70125c34 47#include "base64.h"
3ad12bda
AJ
48#include "util.h"
49
1a22a39e
MM
50#if USE_HEIMDAL_KRB5
51#if HAVE_GSSAPI_GSSAPI_H
52#include <gssapi/gssapi.h>
53#elif HAVE_GSSAPI_H
54#include <gssapi.h>
55#endif
56#elif USE_GNUGSS
57#if HAVE_GSS_H
58#include <gss.h>
59#endif
60#else
3ad12bda
AJ
61#if HAVE_GSSAPI_GSSAPI_H
62#include <gssapi/gssapi.h>
63#elif HAVE_GSSAPI_H
64#include <gssapi.h>
75a8c92e 65#endif
3ad12bda
AJ
66#if HAVE_GSSAPI_GSSAPI_KRB5_H
67#include <gssapi/gssapi_krb5.h>
75a8c92e 68#endif
3ad12bda
AJ
69#if HAVE_GSSAPI_GSSAPI_GENERIC_H
70#include <gssapi/gssapi_generic.h>
75a8c92e
AJ
71#endif
72#if HAVE_GSSAPI_GSSAPI_EXT_H
73#include <gssapi/gssapi_ext.h>
74#endif
75#endif
76
3d62cc61
FC
77#ifndef gss_nt_service_name
78#define gss_nt_service_name GSS_C_NT_HOSTBASED_SERVICE
79#endif
ba4fe07c 80
ba4fe07c
AJ
81static const char *LogTime(void);
82
3ad12bda 83int check_gss_err(OM_uint32 major_status, OM_uint32 minor_status,
2e881a6f 84 const char *function);
ba4fe07c
AJ
85
86const char *squid_kerb_proxy_auth(char *proxy);
87
70125c34 88#define PROGRAM "negotiate_kerberos_auth_test"
ba4fe07c 89
3ad12bda
AJ
90static const char *
91LogTime()
ba4fe07c
AJ
92{
93 struct tm *tm;
94 struct timeval now;
95 static time_t last_t = 0;
96 static char buf[128];
97
98 gettimeofday(&now, NULL);
99 if (now.tv_sec != last_t) {
2e881a6f
A
100 tm = localtime((const time_t *) &now.tv_sec);
101 strftime(buf, 127, "%Y/%m/%d %H:%M:%S", tm);
102 last_t = now.tv_sec;
ba4fe07c
AJ
103 }
104 return buf;
105}
106
ba4fe07c 107#ifndef gss_mech_spnego
2e881a6f 108static gss_OID_desc _gss_mech_spnego = {6, (void *) "\x2b\x06\x01\x05\x05\x02"};
ba4fe07c
AJ
109gss_OID gss_mech_spnego = &_gss_mech_spnego;
110#endif
ba4fe07c 111
3ad12bda
AJ
112int
113check_gss_err(OM_uint32 major_status, OM_uint32 minor_status,
2e881a6f 114 const char *function)
26ac0430
AJ
115{
116 if (GSS_ERROR(major_status)) {
2e881a6f
A
117 OM_uint32 maj_stat, min_stat;
118 OM_uint32 msg_ctx = 0;
119 gss_buffer_desc status_string;
120 char buf[1024];
121 size_t len;
122
123 len = 0;
124 msg_ctx = 0;
08885c7f 125 do {
2e881a6f
A
126 /* convert major status code (GSS-API error) to text */
127 maj_stat = gss_display_status(&min_stat, major_status,
128 GSS_C_GSS_CODE, GSS_C_NULL_OID, &msg_ctx, &status_string);
08885c7f 129 if (maj_stat == GSS_S_COMPLETE && status_string.length > 0) {
2e881a6f
A
130 if (sizeof(buf) > len + status_string.length + 1) {
131 snprintf(buf + len, (sizeof(buf) - len), "%s", (char *) status_string.value);
132 len += status_string.length;
133 }
08885c7f
MM
134 } else
135 msg_ctx = 0;
2e881a6f 136 gss_release_buffer(&min_stat, &status_string);
08885c7f 137 } while (msg_ctx);
2e881a6f
A
138 if (sizeof(buf) > len + 2) {
139 snprintf(buf + len, (sizeof(buf) - len), "%s", ". ");
140 len += 2;
141 }
142 msg_ctx = 0;
08885c7f 143 do {
2e881a6f
A
144 /* convert minor status code (underlying routine error) to text */
145 maj_stat = gss_display_status(&min_stat, minor_status,
146 GSS_C_MECH_CODE, GSS_C_NULL_OID, &msg_ctx, &status_string);
08885c7f 147 if (maj_stat == GSS_S_COMPLETE && status_string.length > 0) {
2e881a6f
A
148 if (sizeof(buf) > len + status_string.length) {
149 snprintf(buf + len, (sizeof(buf) - len), "%s", (char *) status_string.value);
150 len += status_string.length;
151 }
08885c7f
MM
152 } else
153 msg_ctx = 0;
2e881a6f 154 gss_release_buffer(&min_stat, &status_string);
08885c7f 155 } while (msg_ctx);
2e881a6f
A
156 fprintf(stderr, "%s| %s: %s failed: %s\n", LogTime(), PROGRAM, function,
157 buf);
158 return (1);
ba4fe07c 159 }
3ad12bda 160 return (0);
ba4fe07c
AJ
161}
162
3ad12bda
AJ
163const char *
164squid_kerb_proxy_auth(char *proxy)
26ac0430
AJ
165{
166 OM_uint32 major_status, minor_status;
3ad12bda
AJ
167 gss_ctx_id_t gss_context = GSS_C_NO_CONTEXT;
168 gss_name_t server_name = GSS_C_NO_NAME;
169 gss_buffer_desc service = GSS_C_EMPTY_BUFFER;
170 gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
171 gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
172 char *token = NULL;
173
174 setbuf(stdout, NULL);
175 setbuf(stdin, NULL);
176
177 if (!proxy) {
2e881a6f
A
178 fprintf(stderr, "%s| %s: Error: No proxy server name\n", LogTime(),
179 PROGRAM);
180 return NULL;
26ac0430 181 }
3ad12bda 182 service.value = xmalloc(strlen("HTTP") + strlen(proxy) + 2);
b1218840 183 snprintf((char *) service.value, strlen("HTTP") + strlen(proxy) + 2, "%s@%s", "HTTP", proxy);
3ad12bda 184 service.length = strlen((char *) service.value);
ba4fe07c 185
26ac0430 186 major_status = gss_import_name(&minor_status, &service,
2e881a6f 187 gss_nt_service_name, &server_name);
ba4fe07c 188
3ad12bda 189 if (check_gss_err(major_status, minor_status, "gss_import_name()"))
2e881a6f 190 goto cleanup;
ba4fe07c 191
26ac0430 192 major_status = gss_init_sec_context(&minor_status,
2e881a6f
A
193 GSS_C_NO_CREDENTIAL, &gss_context, server_name,
194 gss_mech_spnego,
195 0,
196 0,
197 GSS_C_NO_CHANNEL_BINDINGS,
198 &input_token, NULL, &output_token, NULL, NULL);
3ad12bda
AJ
199
200 if (check_gss_err(major_status, minor_status, "gss_init_sec_context()"))
2e881a6f 201 goto cleanup;
ba4fe07c 202
26ac0430 203 if (output_token.length) {
4ebcf1ce
MM
204 token = (char *) xmalloc((size_t)base64_encode_len((int)output_token.length));
205 base64_encode_str(token, base64_encode_len((int)output_token.length),
206 (const char *) output_token.value, (int)output_token.length);
26ac0430 207 }
2e881a6f 208cleanup:
26ac0430
AJ
209 gss_delete_sec_context(&minor_status, &gss_context, NULL);
210 gss_release_buffer(&minor_status, &service);
211 gss_release_buffer(&minor_status, &input_token);
212 gss_release_buffer(&minor_status, &output_token);
213 gss_release_name(&minor_status, &server_name);
ba4fe07c 214
26ac0430 215 return token;
ba4fe07c
AJ
216}
217
3ad12bda
AJ
218int
219main(int argc, char *argv[])
26ac0430 220{
26ac0430 221 const char *Token;
3ad12bda 222 int count;
ba4fe07c 223
3ad12bda 224 if (argc < 2) {
2e881a6f
A
225 fprintf(stderr, "%s| %s: Error: No proxy server name given\n",
226 LogTime(), PROGRAM);
bc30ad64 227 return 99;
3ad12bda
AJ
228 }
229 if (argc == 3) {
2e881a6f
A
230 count = atoi(argv[2]);
231 while (count > 0) {
232 Token = (const char *) squid_kerb_proxy_auth(argv[1]);
233 fprintf(stdout, "YR %s\n", Token ? Token : "NULL");
755494da 234 --count;
2e881a6f
A
235 }
236 fprintf(stdout, "QQ\n");
3ad12bda 237 } else {
2e881a6f
A
238 Token = (const char *) squid_kerb_proxy_auth(argv[1]);
239 fprintf(stdout, "Token: %s\n", Token ? Token : "NULL");
26ac0430 240 }
ba4fe07c 241
bc30ad64 242 return 0;
ba4fe07c 243}
b1218840 244
6989c6dc 245#else
074d6a40 246#include <cstdlib>
6989c6dc
AJ
247int
248main(int argc, char *argv[])
249{
bc30ad64 250 return -1;
6989c6dc 251}
b1218840 252
3ad12bda 253#endif /* HAVE_GSSAPI */
f53969cc 254