6 #include "tools/squidclient/gssapi_support.h"
10 #if !defined(gss_mech_spnego)
11 static gss_OID_desc _gss_mech_spnego
= {6, (void *) "\x2b\x06\x01\x05\x05\x02"};
12 gss_OID gss_mech_spnego
= &_gss_mech_spnego
;
15 #define BUFFER_SIZE 8192
18 * Check return valuse major_status, minor_status for error and print error description
19 * in case of an error.
21 * \retval true in case of gssapi error
22 * \retval false in case of no gssapi error
25 check_gss_err(OM_uint32 major_status
, OM_uint32 minor_status
, const char *function
)
27 if (GSS_ERROR(major_status
)) {
28 OM_uint32 maj_stat
, min_stat
;
29 OM_uint32 msg_ctx
= 0;
30 gss_buffer_desc status_string
;
31 char buf
[BUFFER_SIZE
];
37 /* convert major status code (GSS-API error) to text */
38 maj_stat
= gss_display_status(&min_stat
, major_status
,
41 &msg_ctx
, &status_string
);
42 if (maj_stat
== GSS_S_COMPLETE
) {
43 snprintf(buf
+ len
, BUFFER_SIZE
-len
, "%s", (char *) status_string
.value
);
44 len
+= status_string
.length
;
45 gss_release_buffer(&min_stat
, &status_string
);
48 gss_release_buffer(&min_stat
, &status_string
);
50 snprintf(buf
+ len
, BUFFER_SIZE
-len
, "%s", ". ");
54 /* convert minor status code (underlying routine error) to text */
55 maj_stat
= gss_display_status(&min_stat
, minor_status
,
58 &msg_ctx
, &status_string
);
59 if (maj_stat
== GSS_S_COMPLETE
) {
60 snprintf(buf
+ len
, BUFFER_SIZE
-len
,"%s", (char *) status_string
.value
);
61 len
+= status_string
.length
;
62 gss_release_buffer(&min_stat
, &status_string
);
65 gss_release_buffer(&min_stat
, &status_string
);
67 std::cerr
<< "ERROR: " << function
<< " failed: " << buf
<< std::endl
;
74 * Get gssapi token for service HTTP/<server>
75 * User has to initiate a kinit user@DOMAIN on commandline first for the
76 * function to be successful
78 * \return base64 encoded token if successful,
79 * string "ERROR" if unsuccessful
82 GSSAPI_token(const char *server
)
84 OM_uint32 major_status
, minor_status
;
85 gss_ctx_id_t gss_context
= GSS_C_NO_CONTEXT
;
86 gss_name_t server_name
= GSS_C_NO_NAME
;
87 gss_buffer_desc service
= GSS_C_EMPTY_BUFFER
;
88 gss_buffer_desc input_token
= GSS_C_EMPTY_BUFFER
;
89 gss_buffer_desc output_token
= GSS_C_EMPTY_BUFFER
;
96 std::cerr
<< "ERROR: GSSAPI: No server name" << std::endl
;
97 return (char *)"ERROR";
99 service
.value
= xmalloc(strlen("HTTP") + strlen(server
) + 2);
100 snprintf((char *) service
.value
, strlen("HTTP") + strlen(server
) + 2, "%s@%s", "HTTP", server
);
101 service
.length
= strlen((char *) service
.value
);
103 major_status
= gss_import_name(&minor_status
, &service
,
104 gss_nt_service_name
, &server_name
);
106 if (!check_gss_err(major_status
, minor_status
, "gss_import_name()")) {
108 major_status
= gss_init_sec_context(&minor_status
,
115 GSS_C_NO_CHANNEL_BINDINGS
,
122 if (!check_gss_err(major_status
, minor_status
, "gss_init_sec_context()")) {
124 if (output_token
.length
)
125 token
= (char *) base64_encode_bin((const char *) output_token
.value
, output_token
.length
);
129 if (!output_token
.length
)
130 token
= (char *) "ERROR";
131 gss_delete_sec_context(&minor_status
, &gss_context
, NULL
);
132 gss_release_buffer(&minor_status
, &service
);
133 gss_release_buffer(&minor_status
, &input_token
);
134 gss_release_buffer(&minor_status
, &output_token
);
135 gss_release_name(&minor_status
, &server_name
);
140 #endif /* HAVE_GSSAPI */