gssapi_support.cc
Go to the documentation of this file.
1/*
2 * Copyright (C) 1996-2023 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
9#include "squid.h"
10
11#if HAVE_GSSAPI
12
13#include "base64.h"
15
16#include <iostream>
17
18#if !defined(gss_mech_spnego)
19static gss_OID_desc _gss_mech_spnego = {6, (void *) "\x2b\x06\x01\x05\x05\x02"};
20gss_OID gss_mech_spnego = &_gss_mech_spnego;
21#endif
22
23#define BUFFER_SIZE 8192
24
32bool
33check_gss_err(OM_uint32 major_status, OM_uint32 minor_status, const char *function)
34{
35 if (GSS_ERROR(major_status)) {
36 OM_uint32 maj_stat, min_stat;
37 OM_uint32 msg_ctx = 0;
38 gss_buffer_desc status_string;
39 char buf[BUFFER_SIZE];
40 size_t len;
41
42 len = 0;
43 msg_ctx = 0;
44 while (!msg_ctx) {
45 /* convert major status code (GSS-API error) to text */
46 maj_stat = gss_display_status(&min_stat, major_status,
47 GSS_C_GSS_CODE,
48 GSS_C_NULL_OID,
49 &msg_ctx, &status_string);
50 if (maj_stat == GSS_S_COMPLETE) {
51 snprintf(buf + len, BUFFER_SIZE-len, "%s", (char *) status_string.value);
52 len += status_string.length;
53 gss_release_buffer(&min_stat, &status_string);
54 break;
55 }
56 gss_release_buffer(&min_stat, &status_string);
57 }
58 snprintf(buf + len, BUFFER_SIZE-len, "%s", ". ");
59 len += 2;
60 msg_ctx = 0;
61 while (!msg_ctx) {
62 /* convert minor status code (underlying routine error) to text */
63 maj_stat = gss_display_status(&min_stat, minor_status,
64 GSS_C_MECH_CODE,
65 GSS_C_NULL_OID,
66 &msg_ctx, &status_string);
67 if (maj_stat == GSS_S_COMPLETE) {
68 snprintf(buf + len, BUFFER_SIZE-len,"%s", (char *) status_string.value);
69 len += status_string.length;
70 gss_release_buffer(&min_stat, &status_string);
71 break;
72 }
73 gss_release_buffer(&min_stat, &status_string);
74 }
75 std::cerr << "ERROR: " << function << " failed: " << buf << std::endl;
76 return true;
77 }
78 return false;
79}
80
89char *
90GSSAPI_token(const char *server)
91{
92 OM_uint32 major_status, minor_status;
93 gss_ctx_id_t gss_context = GSS_C_NO_CONTEXT;
94 gss_name_t server_name = GSS_C_NO_NAME;
95 gss_buffer_desc service = GSS_C_EMPTY_BUFFER;
96 gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
97 gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
98 char *token = nullptr;
99
100 setbuf(stdout, nullptr);
101 setbuf(stdin, nullptr);
102
103 if (!server) {
104 std::cerr << "ERROR: GSSAPI: No server name" << std::endl;
105 token = new char[6];
106 memcpy(token, "ERROR", 5);
107 token[5] = '\0';
108 return token;
109 }
110 service.value = xmalloc(strlen("HTTP") + strlen(server) + 2);
111 snprintf((char *) service.value, strlen("HTTP") + strlen(server) + 2, "%s@%s", "HTTP", server);
112 service.length = strlen((char *) service.value);
113
114 major_status = gss_import_name(&minor_status, &service,
115 gss_nt_service_name, &server_name);
116
117 if (!check_gss_err(major_status, minor_status, "gss_import_name()")) {
118
119 major_status = gss_init_sec_context(&minor_status,
120 GSS_C_NO_CREDENTIAL,
121 &gss_context,
122 server_name,
123 gss_mech_spnego,
124 0,
125 0,
126 GSS_C_NO_CHANNEL_BINDINGS,
127 &input_token,
128 nullptr,
129 &output_token,
130 nullptr,
131 nullptr);
132
133 if (!check_gss_err(major_status, minor_status, "gss_init_sec_context()") && output_token.length) {
134 token = new char[base64_encode_len(output_token.length)];
135 struct base64_encode_ctx ctx;
136 base64_encode_init(&ctx);
137 size_t blen = base64_encode_update(&ctx, token, output_token.length, reinterpret_cast<const uint8_t*>(output_token.value));
138 blen += base64_encode_final(&ctx, token+blen);
139 token[blen] = '\0';
140 }
141 }
142
143 if (!output_token.length) {
144 token = new char[6];
145 memcpy(token, "ERROR", 5);
146 token[5] = '\0';
147 }
148
149 gss_delete_sec_context(&minor_status, &gss_context, nullptr);
150 gss_release_buffer(&minor_status, &service);
151 gss_release_buffer(&minor_status, &input_token);
152 gss_release_buffer(&minor_status, &output_token);
153 gss_release_name(&minor_status, &server_name);
154
155 return token;
156}
157
158#endif /* HAVE_GSSAPI */
159
void base64_encode_init(struct base64_encode_ctx *ctx)
Definition: base64.c:232
size_t base64_encode_update(struct base64_encode_ctx *ctx, char *dst, size_t length, const uint8_t *src)
Definition: base64.c:265
size_t base64_encode_final(struct base64_encode_ctx *ctx, char *dst)
Definition: base64.c:308
#define base64_encode_len(length)
Definition: base64.h:169
static char server[MAXLINE]
#define gss_nt_service_name
int check_gss_err(OM_uint32 major_status, OM_uint32 minor_status, const char *function, int log, int sout)
#define xmalloc
#define BUFFER_SIZE
Definition: rredir.cc:52

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors