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;
23#define BUFFER_SIZE 8192
33check_gss_err(OM_uint32 major_status, OM_uint32 minor_status,
const char *function)
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;
46 maj_stat = gss_display_status(&min_stat, major_status,
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);
56 gss_release_buffer(&min_stat, &status_string);
63 maj_stat = gss_display_status(&min_stat, minor_status,
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);
73 gss_release_buffer(&min_stat, &status_string);
75 std::cerr <<
"ERROR: " << function <<
" failed: " << buf << std::endl;
90GSSAPI_token(
const char *
server)
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;
100 setbuf(stdout,
nullptr);
101 setbuf(stdin,
nullptr);
104 std::cerr <<
"ERROR: GSSAPI: No server name" << std::endl;
106 memcpy(token,
"ERROR", 5);
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);
114 major_status = gss_import_name(&minor_status, &service,
117 if (!
check_gss_err(major_status, minor_status,
"gss_import_name()")) {
119 major_status = gss_init_sec_context(&minor_status,
126 GSS_C_NO_CHANNEL_BINDINGS,
133 if (!
check_gss_err(major_status, minor_status,
"gss_init_sec_context()") && output_token.length) {
137 size_t blen =
base64_encode_update(&ctx, token, output_token.length,
reinterpret_cast<const uint8_t*
>(output_token.value));
143 if (!output_token.length) {
145 memcpy(token,
"ERROR", 5);
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);
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)
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)