gssapi_support.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2017 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)
19 static gss_OID_desc _gss_mech_spnego = {6, (void *) "\x2b\x06\x01\x05\x05\x02"};
20 gss_OID gss_mech_spnego = &_gss_mech_spnego;
21 #endif
22 
23 #define BUFFER_SIZE 8192
24 
32 bool
33 check_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 
89 char *
90 GSSAPI_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 = NULL;
99 
100  setbuf(stdout, NULL);
101  setbuf(stdin, NULL);
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  NULL,
129  &output_token,
130  NULL,
131  NULL);
132 
133  if (!check_gss_err(major_status, minor_status, "gss_init_sec_context()") && output_token.length) {
134  uint8_t *b64buf = new uint8_t[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, b64buf, output_token.length, reinterpret_cast<const uint8_t*>(output_token.value));
138  blen += base64_encode_final(&ctx, b64buf+blen);
139  b64buf[blen] = '\0';
140 
141  token = reinterpret_cast<char*>(b64buf);
142  }
143  }
144 
145  if (!output_token.length) {
146  token = new char[6];
147  memcpy(token, "ERROR", 5);
148  token[5] = '\0';
149  }
150 
151  gss_delete_sec_context(&minor_status, &gss_context, NULL);
152  gss_release_buffer(&minor_status, &service);
153  gss_release_buffer(&minor_status, &input_token);
154  gss_release_buffer(&minor_status, &output_token);
155  gss_release_name(&minor_status, &server_name);
156 
157  return token;
158 }
159 
160 #endif /* HAVE_GSSAPI */
161 
#define gss_nt_service_name
#define BUFFER_SIZE
Definition: rredir.cc:52
size_t base64_encode_final(struct base64_encode_ctx *ctx, uint8_t *dst)
DST should point to an area of size at least BASE64_ENCODE_FINAL_LENGTH.
Definition: base64.c:253
void base64_encode_init(struct base64_encode_ctx *ctx)
Definition: base64.c:182
int unsigned int const char *desc STUB void int len
Definition: stub_fd.cc:20
#define xmalloc
int check_gss_err(OM_uint32 major_status, OM_uint32 minor_status, const char *function, int log, int sout)
size_t base64_encode_update(struct base64_encode_ctx *ctx, uint8_t *dst, size_t length, const uint8_t *src)
Definition: base64.c:213
#define NULL
Definition: types.h:166
#define base64_encode_len(length)
Definition: base64.h:93

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors