int i;
for (i = 0; i < BASE64_VALUE_SZ; i++)
- base64_value[i] = -1;
+ base64_value[i] = -1;
for (i = 0; i < 64; i++)
- base64_value[(int) base64_code[i]] = i;
+ base64_value[(int) base64_code[i]] = i;
base64_value[(int)'='] = 0;
base64_initialized = 1;
int c;
long val;
if (!data)
- return;
+ return;
if (!base64_initialized)
- ska_base64_init();
+ ska_base64_init();
val = c = 0;
for (j = 0; *data; data++) {
- unsigned int k = ((unsigned char) *data) % BASE64_VALUE_SZ;
- if (base64_value[k] < 0)
- continue;
- val <<= 6;
- val += base64_value[k];
- if (++c < 4)
- continue;
- /* One quantum of four encoding characters/24 bit */
- if (j >= result_size)
- break;
- result[j++] = val >> 16; /* High 8 bits */
- if (j >= result_size)
- break;
- result[j++] = (val >> 8) & 0xff; /* Mid 8 bits */
- if (j >= result_size)
- break;
- result[j++] = val & 0xff; /* Low 8 bits */
- val = c = 0;
+ unsigned int k = ((unsigned char) *data) % BASE64_VALUE_SZ;
+ if (base64_value[k] < 0)
+ continue;
+ val <<= 6;
+ val += base64_value[k];
+ if (++c < 4)
+ continue;
+ /* One quantum of four encoding characters/24 bit */
+ if (j >= result_size)
+ break;
+ result[j++] = val >> 16; /* High 8 bits */
+ if (j >= result_size)
+ break;
+ result[j++] = (val >> 8) & 0xff; /* Mid 8 bits */
+ if (j >= result_size)
+ break;
+ result[j++] = val & 0xff; /* Low 8 bits */
+ val = c = 0;
}
return;
}
/* adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments */
void
ska_base64_encode(char *result, const char *data, int result_size,
- int data_size)
+ int data_size)
{
int bits = 0;
int char_count = 0;
int out_cnt = 0;
if (!data)
- return;
+ return;
if (!base64_initialized)
- ska_base64_init();
+ ska_base64_init();
while (data_size--) {
- int c = (unsigned char) *data++;
- bits += c;
- char_count++;
- if (char_count == 3) {
- if (out_cnt >= result_size)
- break;
- result[out_cnt++] = base64_code[bits >> 18];
- if (out_cnt >= result_size)
- break;
- result[out_cnt++] = base64_code[(bits >> 12) & 0x3f];
- if (out_cnt >= result_size)
- break;
- result[out_cnt++] = base64_code[(bits >> 6) & 0x3f];
- if (out_cnt >= result_size)
- break;
- result[out_cnt++] = base64_code[bits & 0x3f];
- bits = 0;
- char_count = 0;
- } else {
- bits <<= 8;
- }
+ int c = (unsigned char) *data++;
+ bits += c;
+ char_count++;
+ if (char_count == 3) {
+ if (out_cnt >= result_size)
+ break;
+ result[out_cnt++] = base64_code[bits >> 18];
+ if (out_cnt >= result_size)
+ break;
+ result[out_cnt++] = base64_code[(bits >> 12) & 0x3f];
+ if (out_cnt >= result_size)
+ break;
+ result[out_cnt++] = base64_code[(bits >> 6) & 0x3f];
+ if (out_cnt >= result_size)
+ break;
+ result[out_cnt++] = base64_code[bits & 0x3f];
+ bits = 0;
+ char_count = 0;
+ } else {
+ bits <<= 8;
+ }
}
if (char_count != 0) {
- bits <<= 16 - (8 * char_count);
- if (out_cnt >= result_size)
- goto end;
- result[out_cnt++] = base64_code[bits >> 18];
- if (out_cnt >= result_size)
- goto end;
- result[out_cnt++] = base64_code[(bits >> 12) & 0x3f];
- if (char_count == 1) {
- if (out_cnt >= result_size)
- goto end;
- result[out_cnt++] = '=';
- if (out_cnt >= result_size)
- goto end;
- result[out_cnt++] = '=';
- } else {
- if (out_cnt >= result_size)
- goto end;
- result[out_cnt++] = base64_code[(bits >> 6) & 0x3f];
- if (out_cnt >= result_size)
- goto end;
- result[out_cnt++] = '=';
- }
+ bits <<= 16 - (8 * char_count);
+ if (out_cnt >= result_size)
+ goto end;
+ result[out_cnt++] = base64_code[bits >> 18];
+ if (out_cnt >= result_size)
+ goto end;
+ result[out_cnt++] = base64_code[(bits >> 12) & 0x3f];
+ if (char_count == 1) {
+ if (out_cnt >= result_size)
+ goto end;
+ result[out_cnt++] = '=';
+ if (out_cnt >= result_size)
+ goto end;
+ result[out_cnt++] = '=';
+ } else {
+ if (out_cnt >= result_size)
+ goto end;
+ result[out_cnt++] = base64_code[(bits >> 6) & 0x3f];
+ if (out_cnt >= result_size)
+ goto end;
+ result[out_cnt++] = '=';
+ }
}
- end:
+end:
if (out_cnt >= result_size) {
- result[result_size - 1] = '\0'; /* terminate */
+ result[result_size - 1] = '\0'; /* terminate */
} else {
- result[out_cnt] = '\0'; /* terminate */
+ result[out_cnt] = '\0'; /* terminate */
}
return;
}
j = 0;
for (i = strlen(data) - 1; i >= 0; i--) {
- if (data[i] == '=')
- j++;
- if (data[i] != '=')
- break;
+ if (data[i] == '=')
+ j++;
+ if (data[i] != '=')
+ break;
}
return strlen(data) / 4 * 3 - j;
}
void ska_base64_decode(char *result, const char *data, int result_size);
void ska_base64_encode(char *result, const char *data, int result_size,
- int data_size);
+ int data_size);
int ska_base64_encode_len(int len);
int ska_base64_decode_len(const char *data);
#endif
int check_gss_err(OM_uint32 major_status, OM_uint32 minor_status,
- const char *function, int debug, int log);
+ const char *function, int debug, int log);
char *gethost_name(void);
static const char *LogTime(void);
-static const unsigned char ntlmProtocol[] =
- { 'N', 'T', 'L', 'M', 'S', 'S', 'P', 0 };
+static const unsigned char ntlmProtocol[] = { 'N', 'T', 'L', 'M', 'S', 'S', 'P', 0 };
static const char *
LogTime()
gettimeofday(&now, NULL);
if (now.tv_sec != last_t) {
- tm = localtime((time_t *) & now.tv_sec);
- strftime(buf, 127, "%Y/%m/%d %H:%M:%S", tm);
- last_t = now.tv_sec;
+ tm = localtime((time_t *) & now.tv_sec);
+ strftime(buf, 127, "%Y/%m/%d %H:%M:%S", tm);
+ last_t = now.tv_sec;
}
return buf;
}
rc = gethostname(hostname, sysconf(_SC_HOST_NAME_MAX));
if (rc) {
- fprintf(stderr, "%s| %s: error while resolving hostname '%s'\n",
- LogTime(), PROGRAM, hostname);
- return NULL;
+ fprintf(stderr, "%s| %s: error while resolving hostname '%s'\n",
+ LogTime(), PROGRAM, hostname);
+ return NULL;
}
rc = xgetaddrinfo(hostname, NULL, NULL, &hres);
if (rc != 0) {
- fprintf(stderr,
- "%s| %s: error while resolving hostname with getaddrinfo: %s\n",
- LogTime(), PROGRAM, xgai_strerror(rc));
- return NULL;
+ fprintf(stderr,
+ "%s| %s: error while resolving hostname with getaddrinfo: %s\n",
+ LogTime(), PROGRAM, xgai_strerror(rc));
+ return NULL;
}
hres_list = hres;
count = 0;
while (hres_list) {
- count++;
- hres_list = hres_list->ai_next;
+ count++;
+ hres_list = hres_list->ai_next;
}
rc = xgetnameinfo(hres->ai_addr, hres->ai_addrlen, hostname,
- sizeof(hostname), NULL, 0, 0);
+ sizeof(hostname), NULL, 0, 0);
if (rc != 0) {
- fprintf(stderr,
- "%s| %s: error while resolving ip address with getnameinfo: %s\n",
- LogTime(), PROGRAM, xgai_strerror(rc));
- xfreeaddrinfo(hres);
- return NULL;
+ fprintf(stderr,
+ "%s| %s: error while resolving ip address with getnameinfo: %s\n",
+ LogTime(), PROGRAM, xgai_strerror(rc));
+ xfreeaddrinfo(hres);
+ return NULL;
}
xfreeaddrinfo(hres);
int
check_gss_err(OM_uint32 major_status, OM_uint32 minor_status,
- const char *function, int debug, int log)
+ const char *function, int debug, int log)
{
if (GSS_ERROR(major_status)) {
- OM_uint32 maj_stat, min_stat;
- OM_uint32 msg_ctx = 0;
- gss_buffer_desc status_string;
- char buf[1024];
- size_t len;
-
- len = 0;
- msg_ctx = 0;
- while (!msg_ctx) {
- /* convert major status code (GSS-API error) to text */
- maj_stat = gss_display_status(&min_stat, major_status,
- GSS_C_GSS_CODE, GSS_C_NULL_OID, &msg_ctx, &status_string);
- if (maj_stat == GSS_S_COMPLETE) {
- if (sizeof(buf) > len + status_string.length + 1) {
- sprintf(buf + len, "%s", (char *) status_string.value);
- len += status_string.length;
- }
- gss_release_buffer(&min_stat, &status_string);
- break;
- }
- gss_release_buffer(&min_stat, &status_string);
- }
- if (sizeof(buf) > len + 2) {
- sprintf(buf + len, "%s", ". ");
- len += 2;
- }
- msg_ctx = 0;
- while (!msg_ctx) {
- /* convert minor status code (underlying routine error) to text */
- maj_stat = gss_display_status(&min_stat, minor_status,
- GSS_C_MECH_CODE, GSS_C_NULL_OID, &msg_ctx, &status_string);
- if (maj_stat == GSS_S_COMPLETE) {
- if (sizeof(buf) > len + status_string.length) {
- sprintf(buf + len, "%s", (char *) status_string.value);
- len += status_string.length;
- }
- gss_release_buffer(&min_stat, &status_string);
- break;
- }
- gss_release_buffer(&min_stat, &status_string);
- }
- if (debug)
- fprintf(stderr, "%s| %s: %s failed: %s\n", LogTime(), PROGRAM,
- function, buf);
- fprintf(stdout, "BH %s failed: %s\n", function, buf);
- if (log)
- fprintf(stderr, "%s| %s: User not authenticated\n", LogTime(),
- PROGRAM);
- return (1);
+ OM_uint32 maj_stat, min_stat;
+ OM_uint32 msg_ctx = 0;
+ gss_buffer_desc status_string;
+ char buf[1024];
+ size_t len;
+
+ len = 0;
+ msg_ctx = 0;
+ while (!msg_ctx) {
+ /* convert major status code (GSS-API error) to text */
+ maj_stat = gss_display_status(&min_stat, major_status,
+ GSS_C_GSS_CODE, GSS_C_NULL_OID, &msg_ctx, &status_string);
+ if (maj_stat == GSS_S_COMPLETE) {
+ if (sizeof(buf) > len + status_string.length + 1) {
+ sprintf(buf + len, "%s", (char *) status_string.value);
+ len += status_string.length;
+ }
+ gss_release_buffer(&min_stat, &status_string);
+ break;
+ }
+ gss_release_buffer(&min_stat, &status_string);
+ }
+ if (sizeof(buf) > len + 2) {
+ sprintf(buf + len, "%s", ". ");
+ len += 2;
+ }
+ msg_ctx = 0;
+ while (!msg_ctx) {
+ /* convert minor status code (underlying routine error) to text */
+ maj_stat = gss_display_status(&min_stat, minor_status,
+ GSS_C_MECH_CODE, GSS_C_NULL_OID, &msg_ctx, &status_string);
+ if (maj_stat == GSS_S_COMPLETE) {
+ if (sizeof(buf) > len + status_string.length) {
+ sprintf(buf + len, "%s", (char *) status_string.value);
+ len += status_string.length;
+ }
+ gss_release_buffer(&min_stat, &status_string);
+ break;
+ }
+ gss_release_buffer(&min_stat, &status_string);
+ }
+ if (debug)
+ fprintf(stderr, "%s| %s: %s failed: %s\n", LogTime(), PROGRAM,
+ function, buf);
+ fprintf(stdout, "BH %s failed: %s\n", function, buf);
+ if (log)
+ fprintf(stderr, "%s| %s: User not authenticated\n", LogTime(),
+ PROGRAM);
+ return (1);
}
return (0);
}
setbuf(stdin, NULL);
while (-1 != (opt = getopt(argc, argv, "dirs:h"))) {
- switch (opt) {
- case 'd':
- debug = 1;
- break;
- case 'i':
- log = 1;
- break;
- case 'r':
- norealm = 1;
- break;
- case 's':
- service_principal = xstrdup(optarg);
- break;
- case 'h':
- fprintf(stderr, "Usage: \n");
- fprintf(stderr, "squid_kerb_auth [-d] [-i] [-s SPN] [-h]\n");
- fprintf(stderr, "-d full debug\n");
- fprintf(stderr, "-i informational messages\n");
- fprintf(stderr, "-r remove realm from username\n");
- fprintf(stderr, "-s service principal name\n");
- fprintf(stderr, "-h help\n");
- fprintf(stderr,
- "The SPN can be set to GSS_C_NO_NAME to allow any entry from keytab\n");
- fprintf(stderr, "default SPN is HTTP/fqdn@DEFAULT_REALM\n");
- exit(0);
- default:
- fprintf(stderr, "%s| %s: unknown option: -%c.\n", LogTime(),
- PROGRAM, opt);
- }
+ switch (opt) {
+ case 'd':
+ debug = 1;
+ break;
+ case 'i':
+ log = 1;
+ break;
+ case 'r':
+ norealm = 1;
+ break;
+ case 's':
+ service_principal = xstrdup(optarg);
+ break;
+ case 'h':
+ fprintf(stderr, "Usage: \n");
+ fprintf(stderr, "squid_kerb_auth [-d] [-i] [-s SPN] [-h]\n");
+ fprintf(stderr, "-d full debug\n");
+ fprintf(stderr, "-i informational messages\n");
+ fprintf(stderr, "-r remove realm from username\n");
+ fprintf(stderr, "-s service principal name\n");
+ fprintf(stderr, "-h help\n");
+ fprintf(stderr,
+ "The SPN can be set to GSS_C_NO_NAME to allow any entry from keytab\n");
+ fprintf(stderr, "default SPN is HTTP/fqdn@DEFAULT_REALM\n");
+ exit(0);
+ default:
+ fprintf(stderr, "%s| %s: unknown option: -%c.\n", LogTime(),
+ PROGRAM, opt);
+ }
}
if (debug)
- fprintf(stderr, "%s| %s: Starting version %s\n", LogTime(), PROGRAM,
- SQUID_KERB_AUTH_VERSION);
+ fprintf(stderr, "%s| %s: Starting version %s\n", LogTime(), PROGRAM,
+ SQUID_KERB_AUTH_VERSION);
if (service_principal && strcasecmp(service_principal, "GSS_C_NO_NAME")) {
- service.value = service_principal;
- service.length = strlen((char *) service.value);
+ service.value = service_principal;
+ service.length = strlen((char *) service.value);
} else {
- host_name = gethost_name();
- if (!host_name) {
- fprintf(stderr,
- "%s| %s: Local hostname could not be determined. Please specify the service principal\n",
- LogTime(), PROGRAM);
- fprintf(stdout, "BH hostname error\n");
- exit(-1);
- }
- service.value = xmalloc(strlen(service_name) + strlen(host_name) + 2);
- snprintf((char*)service.value, strlen(service_name) + strlen(host_name) + 2,
- "%s@%s", service_name, host_name);
- service.length = strlen((char *) service.value);
+ host_name = gethost_name();
+ if (!host_name) {
+ fprintf(stderr,
+ "%s| %s: Local hostname could not be determined. Please specify the service principal\n",
+ LogTime(), PROGRAM);
+ fprintf(stdout, "BH hostname error\n");
+ exit(-1);
+ }
+ service.value = xmalloc(strlen(service_name) + strlen(host_name) + 2);
+ snprintf((char*)service.value, strlen(service_name) + strlen(host_name) + 2,
+ "%s@%s", service_name, host_name);
+ service.length = strlen((char *) service.value);
}
while (1) {
- if (fgets(buf, sizeof(buf) - 1, stdin) == NULL) {
- if (ferror(stdin)) {
- if (debug)
- fprintf(stderr,
- "%s| %s: fgets() failed! dying..... errno=%d (%s)\n",
- LogTime(), PROGRAM, ferror(stdin),
- strerror(ferror(stdin)));
-
- fprintf(stdout, "BH input error\n");
- exit(1); /* BIIG buffer */
- }
- fprintf(stdout, "BH input error\n");
- exit(0);
- }
-
- c = (char*)memchr(buf, '\n', sizeof(buf) - 1);
- if (c) {
- *c = '\0';
- length = c - buf;
- } else {
- err = 1;
- }
- if (err) {
- if (debug)
- fprintf(stderr, "%s| %s: Oversized message\n", LogTime(),
- PROGRAM);
- fprintf(stdout, "BH Oversized message\n");
- err = 0;
- continue;
- }
-
- if (debug)
- fprintf(stderr, "%s| %s: Got '%s' from squid (length: %d).\n",
- LogTime(), PROGRAM, buf, length);
-
- if (buf[0] == '\0') {
- if (debug)
- fprintf(stderr, "%s| %s: Invalid request\n", LogTime(),
- PROGRAM);
- fprintf(stdout, "BH Invalid request\n");
- continue;
- }
-
- if (strlen(buf) < 2) {
- if (debug)
- fprintf(stderr, "%s| %s: Invalid request [%s]\n", LogTime(),
- PROGRAM, buf);
- fprintf(stdout, "BH Invalid request\n");
- continue;
- }
-
- if (!strncmp(buf, "QQ", 2)) {
- gss_release_buffer(&minor_status, &input_token);
- gss_release_buffer(&minor_status, &output_token);
- gss_release_buffer(&minor_status, &service);
- gss_release_cred(&minor_status, &server_creds);
- if (server_name)
- gss_release_name(&minor_status, &server_name);
- if (client_name)
- gss_release_name(&minor_status, &client_name);
- if (gss_context != GSS_C_NO_CONTEXT)
- gss_delete_sec_context(&minor_status, &gss_context, NULL);
- if (kerberosToken) {
- /* Allocated by parseNegTokenInit, but no matching free function exists.. */
- if (!spnego_flag)
- xfree((char *) kerberosToken);
- kerberosToken = NULL;
- }
- if (spnego_flag) {
- /* Allocated by makeNegTokenTarg, but no matching free function exists.. */
- if (spnegoToken)
- xfree((char *) spnegoToken);
- spnegoToken = NULL;
- }
- if (token) {
- xfree(token);
- token = NULL;
- }
- if (host_name) {
- xfree(host_name);
- host_name = NULL;
- }
- fprintf(stdout, "BH quit command\n");
- exit(0);
- }
-
- if (strncmp(buf, "YR", 2) && strncmp(buf, "KK", 2)) {
- if (debug)
- fprintf(stderr, "%s| %s: Invalid request [%s]\n", LogTime(),
- PROGRAM, buf);
- fprintf(stdout, "BH Invalid request\n");
- continue;
- }
- if (!strncmp(buf, "YR", 2)) {
- if (gss_context != GSS_C_NO_CONTEXT)
- gss_delete_sec_context(&minor_status, &gss_context, NULL);
- gss_context = GSS_C_NO_CONTEXT;
- }
-
- if (strlen(buf) <= 3) {
- if (debug)
- fprintf(stderr, "%s| %s: Invalid negotiate request [%s]\n",
- LogTime(), PROGRAM, buf);
- fprintf(stdout, "BH Invalid negotiate request\n");
- continue;
- }
-
- input_token.length = ska_base64_decode_len(buf + 3);
- if (debug)
- fprintf(stderr, "%s| %s: Decode '%s' (decoded length: %d).\n",
- LogTime(), PROGRAM, buf + 3, (int) input_token.length);
- input_token.value = xmalloc(input_token.length);
-
- ska_base64_decode((char*)input_token.value, buf + 3, input_token.length);
+ if (fgets(buf, sizeof(buf) - 1, stdin) == NULL) {
+ if (ferror(stdin)) {
+ if (debug)
+ fprintf(stderr,
+ "%s| %s: fgets() failed! dying..... errno=%d (%s)\n",
+ LogTime(), PROGRAM, ferror(stdin),
+ strerror(ferror(stdin)));
+
+ fprintf(stdout, "BH input error\n");
+ exit(1); /* BIIG buffer */
+ }
+ fprintf(stdout, "BH input error\n");
+ exit(0);
+ }
+
+ c = (char*)memchr(buf, '\n', sizeof(buf) - 1);
+ if (c) {
+ *c = '\0';
+ length = c - buf;
+ } else {
+ err = 1;
+ }
+ if (err) {
+ if (debug)
+ fprintf(stderr, "%s| %s: Oversized message\n", LogTime(),
+ PROGRAM);
+ fprintf(stdout, "BH Oversized message\n");
+ err = 0;
+ continue;
+ }
+
+ if (debug)
+ fprintf(stderr, "%s| %s: Got '%s' from squid (length: %d).\n",
+ LogTime(), PROGRAM, buf, length);
+
+ if (buf[0] == '\0') {
+ if (debug)
+ fprintf(stderr, "%s| %s: Invalid request\n", LogTime(),
+ PROGRAM);
+ fprintf(stdout, "BH Invalid request\n");
+ continue;
+ }
+
+ if (strlen(buf) < 2) {
+ if (debug)
+ fprintf(stderr, "%s| %s: Invalid request [%s]\n", LogTime(),
+ PROGRAM, buf);
+ fprintf(stdout, "BH Invalid request\n");
+ continue;
+ }
+
+ if (!strncmp(buf, "QQ", 2)) {
+ gss_release_buffer(&minor_status, &input_token);
+ gss_release_buffer(&minor_status, &output_token);
+ gss_release_buffer(&minor_status, &service);
+ gss_release_cred(&minor_status, &server_creds);
+ if (server_name)
+ gss_release_name(&minor_status, &server_name);
+ if (client_name)
+ gss_release_name(&minor_status, &client_name);
+ if (gss_context != GSS_C_NO_CONTEXT)
+ gss_delete_sec_context(&minor_status, &gss_context, NULL);
+ if (kerberosToken) {
+ /* Allocated by parseNegTokenInit, but no matching free function exists.. */
+ if (!spnego_flag)
+ xfree((char *) kerberosToken);
+ kerberosToken = NULL;
+ }
+ if (spnego_flag) {
+ /* Allocated by makeNegTokenTarg, but no matching free function exists.. */
+ if (spnegoToken)
+ xfree((char *) spnegoToken);
+ spnegoToken = NULL;
+ }
+ if (token) {
+ xfree(token);
+ token = NULL;
+ }
+ if (host_name) {
+ xfree(host_name);
+ host_name = NULL;
+ }
+ fprintf(stdout, "BH quit command\n");
+ exit(0);
+ }
+
+ if (strncmp(buf, "YR", 2) && strncmp(buf, "KK", 2)) {
+ if (debug)
+ fprintf(stderr, "%s| %s: Invalid request [%s]\n", LogTime(),
+ PROGRAM, buf);
+ fprintf(stdout, "BH Invalid request\n");
+ continue;
+ }
+ if (!strncmp(buf, "YR", 2)) {
+ if (gss_context != GSS_C_NO_CONTEXT)
+ gss_delete_sec_context(&minor_status, &gss_context, NULL);
+ gss_context = GSS_C_NO_CONTEXT;
+ }
+
+ if (strlen(buf) <= 3) {
+ if (debug)
+ fprintf(stderr, "%s| %s: Invalid negotiate request [%s]\n",
+ LogTime(), PROGRAM, buf);
+ fprintf(stdout, "BH Invalid negotiate request\n");
+ continue;
+ }
+
+ input_token.length = ska_base64_decode_len(buf + 3);
+ if (debug)
+ fprintf(stderr, "%s| %s: Decode '%s' (decoded length: %d).\n",
+ LogTime(), PROGRAM, buf + 3, (int) input_token.length);
+ input_token.value = xmalloc(input_token.length);
+
+ ska_base64_decode((char*)input_token.value, buf + 3, input_token.length);
#if !HAVE_SPNEGO
- if ((rc = parseNegTokenInit(input_token.value,
- input_token.length,
- &kerberosToken, &kerberosTokenLength)) != 0) {
- if (debug)
- fprintf(stderr, "%s| %s: parseNegTokenInit failed with rc=%d\n",
- LogTime(), PROGRAM, rc);
-
- /* if between 100 and 200 it might be a GSSAPI token and not a SPNEGO token */
- if (rc < 100 || rc > 199) {
- if (debug)
- fprintf(stderr, "%s| %s: Invalid GSS-SPNEGO query [%s]\n",
- LogTime(), PROGRAM, buf);
- fprintf(stdout, "BH Invalid GSS-SPNEGO query\n");
- goto cleanup;
- }
- if ((input_token.length >= sizeof ntlmProtocol + 1) &&
- (!memcmp(input_token.value, ntlmProtocol,
- sizeof ntlmProtocol))) {
- if (debug)
- fprintf(stderr, "%s| %s: received type %d NTLM token\n",
- LogTime(), PROGRAM,
- (int) *((unsigned char *) input_token.value +
- sizeof ntlmProtocol));
- fprintf(stdout, "BH received type %d NTLM token\n",
- (int) *((unsigned char *) input_token.value +
- sizeof ntlmProtocol));
- goto cleanup;
- }
- if (debug)
- fprintf(stderr, "%s| %s: Token is possibly a GSSAPI token\n",
- LogTime(), PROGRAM);
- spnego_flag = 0;
- } else {
- gss_release_buffer(&minor_status, &input_token);
- input_token.length = kerberosTokenLength;
- input_token.value = (void *) kerberosToken;
- spnego_flag = 1;
- }
+ if ((rc = parseNegTokenInit(input_token.value,
+ input_token.length,
+ &kerberosToken, &kerberosTokenLength)) != 0) {
+ if (debug)
+ fprintf(stderr, "%s| %s: parseNegTokenInit failed with rc=%d\n",
+ LogTime(), PROGRAM, rc);
+
+ /* if between 100 and 200 it might be a GSSAPI token and not a SPNEGO token */
+ if (rc < 100 || rc > 199) {
+ if (debug)
+ fprintf(stderr, "%s| %s: Invalid GSS-SPNEGO query [%s]\n",
+ LogTime(), PROGRAM, buf);
+ fprintf(stdout, "BH Invalid GSS-SPNEGO query\n");
+ goto cleanup;
+ }
+ if ((input_token.length >= sizeof ntlmProtocol + 1) &&
+ (!memcmp(input_token.value, ntlmProtocol,
+ sizeof ntlmProtocol))) {
+ if (debug)
+ fprintf(stderr, "%s| %s: received type %d NTLM token\n",
+ LogTime(), PROGRAM,
+ (int) *((unsigned char *) input_token.value +
+ sizeof ntlmProtocol));
+ fprintf(stdout, "BH received type %d NTLM token\n",
+ (int) *((unsigned char *) input_token.value +
+ sizeof ntlmProtocol));
+ goto cleanup;
+ }
+ if (debug)
+ fprintf(stderr, "%s| %s: Token is possibly a GSSAPI token\n",
+ LogTime(), PROGRAM);
+ spnego_flag = 0;
+ } else {
+ gss_release_buffer(&minor_status, &input_token);
+ input_token.length = kerberosTokenLength;
+ input_token.value = (void *) kerberosToken;
+ spnego_flag = 1;
+ }
#else
- if ((input_token.length >= sizeof ntlmProtocol + 1) &&
- (!memcmp(input_token.value, ntlmProtocol, sizeof ntlmProtocol))) {
- if (debug)
- fprintf(stderr, "%s| %s: received type %d NTLM token\n",
- LogTime(), PROGRAM,
- (int) *((unsigned char *) input_token.value +
- sizeof ntlmProtocol));
- fprintf(stdout, "BH received type %d NTLM token\n",
- (int) *((unsigned char *) input_token.value +
- sizeof ntlmProtocol));
- goto cleanup;
- }
+ if ((input_token.length >= sizeof ntlmProtocol + 1) &&
+ (!memcmp(input_token.value, ntlmProtocol, sizeof ntlmProtocol))) {
+ if (debug)
+ fprintf(stderr, "%s| %s: received type %d NTLM token\n",
+ LogTime(), PROGRAM,
+ (int) *((unsigned char *) input_token.value +
+ sizeof ntlmProtocol));
+ fprintf(stdout, "BH received type %d NTLM token\n",
+ (int) *((unsigned char *) input_token.value +
+ sizeof ntlmProtocol));
+ goto cleanup;
+ }
#endif
- if (service_principal) {
- if (strcasecmp(service_principal, "GSS_C_NO_NAME")) {
- major_status = gss_import_name(&minor_status, &service,
- (gss_OID) GSS_C_NULL_OID, &server_name);
-
- } else {
- server_name = GSS_C_NO_NAME;
- major_status = GSS_S_COMPLETE;
- }
- } else {
- major_status = gss_import_name(&minor_status, &service,
- gss_nt_service_name, &server_name);
- }
-
- if (check_gss_err(major_status, minor_status, "gss_import_name()",
- debug, log))
- goto cleanup;
-
- major_status =
- gss_acquire_cred(&minor_status, server_name, GSS_C_INDEFINITE,
- GSS_C_NO_OID_SET, GSS_C_ACCEPT, &server_creds, NULL, NULL);
- if (check_gss_err(major_status, minor_status, "gss_acquire_cred()",
- debug, log))
- goto cleanup;
-
- major_status = gss_accept_sec_context(&minor_status,
- &gss_context,
- server_creds,
- &input_token,
- GSS_C_NO_CHANNEL_BINDINGS,
- &client_name, NULL, &output_token, &ret_flags, NULL, NULL);
-
-
- if (output_token.length) {
+ if (service_principal) {
+ if (strcasecmp(service_principal, "GSS_C_NO_NAME")) {
+ major_status = gss_import_name(&minor_status, &service,
+ (gss_OID) GSS_C_NULL_OID, &server_name);
+
+ } else {
+ server_name = GSS_C_NO_NAME;
+ major_status = GSS_S_COMPLETE;
+ }
+ } else {
+ major_status = gss_import_name(&minor_status, &service,
+ gss_nt_service_name, &server_name);
+ }
+
+ if (check_gss_err(major_status, minor_status, "gss_import_name()",
+ debug, log))
+ goto cleanup;
+
+ major_status =
+ gss_acquire_cred(&minor_status, server_name, GSS_C_INDEFINITE,
+ GSS_C_NO_OID_SET, GSS_C_ACCEPT, &server_creds, NULL, NULL);
+ if (check_gss_err(major_status, minor_status, "gss_acquire_cred()",
+ debug, log))
+ goto cleanup;
+
+ major_status = gss_accept_sec_context(&minor_status,
+ &gss_context,
+ server_creds,
+ &input_token,
+ GSS_C_NO_CHANNEL_BINDINGS,
+ &client_name, NULL, &output_token, &ret_flags, NULL, NULL);
+
+
+ if (output_token.length) {
#if !HAVE_SPNEGO
- if (spnego_flag) {
- if ((rc = makeNegTokenTarg(output_token.value,
- output_token.length,
- &spnegoToken, &spnegoTokenLength)) != 0) {
- if (debug)
- fprintf(stderr,
- "%s| %s: makeNegTokenTarg failed with rc=%d\n",
- LogTime(), PROGRAM, rc);
- fprintf(stdout, "BH makeNegTokenTarg failed with rc=%d\n",
- rc);
- goto cleanup;
- }
- } else {
- spnegoToken = output_token.value;
- spnegoTokenLength = output_token.length;
- }
+ if (spnego_flag) {
+ if ((rc = makeNegTokenTarg(output_token.value,
+ output_token.length,
+ &spnegoToken, &spnegoTokenLength)) != 0) {
+ if (debug)
+ fprintf(stderr,
+ "%s| %s: makeNegTokenTarg failed with rc=%d\n",
+ LogTime(), PROGRAM, rc);
+ fprintf(stdout, "BH makeNegTokenTarg failed with rc=%d\n",
+ rc);
+ goto cleanup;
+ }
+ } else {
+ spnegoToken = output_token.value;
+ spnegoTokenLength = output_token.length;
+ }
#else
- spnegoToken = (unsigned char *)output_token.value;
- spnegoTokenLength = output_token.length;
+ spnegoToken = (unsigned char *)output_token.value;
+ spnegoTokenLength = output_token.length;
#endif
- token = (char*)xmalloc(ska_base64_encode_len(spnegoTokenLength));
- if (token == NULL) {
- if (debug)
- fprintf(stderr, "%s| %s: Not enough memory\n", LogTime(),
- PROGRAM);
- fprintf(stdout, "BH Not enough memory\n");
- goto cleanup;
- }
-
- ska_base64_encode(token, (const char *) spnegoToken,
- ska_base64_encode_len(spnegoTokenLength), spnegoTokenLength);
-
- if (check_gss_err(major_status, minor_status,
- "gss_accept_sec_context()", debug, log))
- goto cleanup;
- if (major_status & GSS_S_CONTINUE_NEEDED) {
- if (debug)
- fprintf(stderr, "%s| %s: continuation needed\n", LogTime(),
- PROGRAM);
- fprintf(stdout, "TT %s\n", token);
- goto cleanup;
- }
- gss_release_buffer(&minor_status, &output_token);
- major_status =
- gss_display_name(&minor_status, client_name, &output_token,
- NULL);
-
- if (check_gss_err(major_status, minor_status, "gss_display_name()",
- debug, log))
- goto cleanup;
- user = (char*)xmalloc(output_token.length + 1);
- if (user == NULL) {
- if (debug)
- fprintf(stderr, "%s| %s: Not enough memory\n", LogTime(),
- PROGRAM);
- fprintf(stdout, "BH Not enough memory\n");
- goto cleanup;
- }
- memcpy(user, output_token.value, output_token.length);
- user[output_token.length] = '\0';
- if (norealm && (p = strchr(user, '@')) != NULL) {
- *p = '\0';
- }
- fprintf(stdout, "AF %s %s\n", token, user);
- if (debug)
- fprintf(stderr, "%s| %s: AF %s %s\n", LogTime(), PROGRAM, token,
- user);
- if (log)
- fprintf(stderr, "%s| %s: User %s authenticated\n", LogTime(),
- PROGRAM, user);
- goto cleanup;
- } else {
- if (check_gss_err(major_status, minor_status,
- "gss_accept_sec_context()", debug, log))
- goto cleanup;
- if (major_status & GSS_S_CONTINUE_NEEDED) {
- if (debug)
- fprintf(stderr, "%s| %s: continuation needed\n", LogTime(),
- PROGRAM);
- fprintf(stdout, "NA %s\n", token);
- goto cleanup;
- }
- gss_release_buffer(&minor_status, &output_token);
- major_status =
- gss_display_name(&minor_status, client_name, &output_token,
- NULL);
-
- if (check_gss_err(major_status, minor_status, "gss_display_name()",
- debug, log))
- goto cleanup;
- /*
- * Return dummy token AA. May need an extra return tag then AF
- */
- user = (char*)xmalloc(output_token.length + 1);
- if (user == NULL) {
- if (debug)
- fprintf(stderr, "%s| %s: Not enough memory\n", LogTime(),
- PROGRAM);
- fprintf(stdout, "BH Not enough memory\n");
- goto cleanup;
- }
- memcpy(user, output_token.value, output_token.length);
- user[output_token.length] = '\0';
- if (norealm && (p = strchr(user, '@')) != NULL) {
- *p = '\0';
- }
- fprintf(stdout, "AF %s %s\n", "AA==", user);
- if (debug)
- fprintf(stderr, "%s| %s: AF %s %s\n", LogTime(), PROGRAM,
- "AA==", user);
- if (log)
- fprintf(stderr, "%s| %s: User %s authenticated\n", LogTime(),
- PROGRAM, user);
-
- }
- cleanup:
- gss_release_buffer(&minor_status, &input_token);
- gss_release_buffer(&minor_status, &output_token);
- gss_release_cred(&minor_status, &server_creds);
- if (server_name)
- gss_release_name(&minor_status, &server_name);
- if (client_name)
- gss_release_name(&minor_status, &client_name);
- if (kerberosToken) {
- /* Allocated by parseNegTokenInit, but no matching free function exists.. */
- if (!spnego_flag)
- xfree((char *) kerberosToken);
- kerberosToken = NULL;
- }
- if (spnego_flag) {
- /* Allocated by makeNegTokenTarg, but no matching free function exists.. */
- if (spnegoToken)
- xfree((char *) spnegoToken);
- spnegoToken = NULL;
- }
- if (token) {
- xfree(token);
- token = NULL;
- }
- if (user) {
- xfree(user);
- user = NULL;
- }
- continue;
+ token = (char*)xmalloc(ska_base64_encode_len(spnegoTokenLength));
+ if (token == NULL) {
+ if (debug)
+ fprintf(stderr, "%s| %s: Not enough memory\n", LogTime(),
+ PROGRAM);
+ fprintf(stdout, "BH Not enough memory\n");
+ goto cleanup;
+ }
+
+ ska_base64_encode(token, (const char *) spnegoToken,
+ ska_base64_encode_len(spnegoTokenLength), spnegoTokenLength);
+
+ if (check_gss_err(major_status, minor_status,
+ "gss_accept_sec_context()", debug, log))
+ goto cleanup;
+ if (major_status & GSS_S_CONTINUE_NEEDED) {
+ if (debug)
+ fprintf(stderr, "%s| %s: continuation needed\n", LogTime(),
+ PROGRAM);
+ fprintf(stdout, "TT %s\n", token);
+ goto cleanup;
+ }
+ gss_release_buffer(&minor_status, &output_token);
+ major_status =
+ gss_display_name(&minor_status, client_name, &output_token,
+ NULL);
+
+ if (check_gss_err(major_status, minor_status, "gss_display_name()",
+ debug, log))
+ goto cleanup;
+ user = (char*)xmalloc(output_token.length + 1);
+ if (user == NULL) {
+ if (debug)
+ fprintf(stderr, "%s| %s: Not enough memory\n", LogTime(),
+ PROGRAM);
+ fprintf(stdout, "BH Not enough memory\n");
+ goto cleanup;
+ }
+ memcpy(user, output_token.value, output_token.length);
+ user[output_token.length] = '\0';
+ if (norealm && (p = strchr(user, '@')) != NULL) {
+ *p = '\0';
+ }
+ fprintf(stdout, "AF %s %s\n", token, user);
+ if (debug)
+ fprintf(stderr, "%s| %s: AF %s %s\n", LogTime(), PROGRAM, token,
+ user);
+ if (log)
+ fprintf(stderr, "%s| %s: User %s authenticated\n", LogTime(),
+ PROGRAM, user);
+ goto cleanup;
+ } else {
+ if (check_gss_err(major_status, minor_status,
+ "gss_accept_sec_context()", debug, log))
+ goto cleanup;
+ if (major_status & GSS_S_CONTINUE_NEEDED) {
+ if (debug)
+ fprintf(stderr, "%s| %s: continuation needed\n", LogTime(),
+ PROGRAM);
+ fprintf(stdout, "NA %s\n", token);
+ goto cleanup;
+ }
+ gss_release_buffer(&minor_status, &output_token);
+ major_status =
+ gss_display_name(&minor_status, client_name, &output_token,
+ NULL);
+
+ if (check_gss_err(major_status, minor_status, "gss_display_name()",
+ debug, log))
+ goto cleanup;
+ /*
+ * Return dummy token AA. May need an extra return tag then AF
+ */
+ user = (char*)xmalloc(output_token.length + 1);
+ if (user == NULL) {
+ if (debug)
+ fprintf(stderr, "%s| %s: Not enough memory\n", LogTime(),
+ PROGRAM);
+ fprintf(stdout, "BH Not enough memory\n");
+ goto cleanup;
+ }
+ memcpy(user, output_token.value, output_token.length);
+ user[output_token.length] = '\0';
+ if (norealm && (p = strchr(user, '@')) != NULL) {
+ *p = '\0';
+ }
+ fprintf(stdout, "AF %s %s\n", "AA==", user);
+ if (debug)
+ fprintf(stderr, "%s| %s: AF %s %s\n", LogTime(), PROGRAM,
+ "AA==", user);
+ if (log)
+ fprintf(stderr, "%s| %s: User %s authenticated\n", LogTime(),
+ PROGRAM, user);
+
+ }
+cleanup:
+ gss_release_buffer(&minor_status, &input_token);
+ gss_release_buffer(&minor_status, &output_token);
+ gss_release_cred(&minor_status, &server_creds);
+ if (server_name)
+ gss_release_name(&minor_status, &server_name);
+ if (client_name)
+ gss_release_name(&minor_status, &client_name);
+ if (kerberosToken) {
+ /* Allocated by parseNegTokenInit, but no matching free function exists.. */
+ if (!spnego_flag)
+ xfree((char *) kerberosToken);
+ kerberosToken = NULL;
+ }
+ if (spnego_flag) {
+ /* Allocated by makeNegTokenTarg, but no matching free function exists.. */
+ if (spnegoToken)
+ xfree((char *) spnegoToken);
+ spnegoToken = NULL;
+ }
+ if (token) {
+ xfree(token);
+ token = NULL;
+ }
+ if (user) {
+ xfree(user);
+ user = NULL;
+ }
+ continue;
}
}
#else
static const char *LogTime(void);
int check_gss_err(OM_uint32 major_status, OM_uint32 minor_status,
- const char *function);
+ const char *function);
const char *squid_kerb_proxy_auth(char *proxy);
gettimeofday(&now, NULL);
if (now.tv_sec != last_t) {
- tm = localtime(&now.tv_sec);
- strftime(buf, 127, "%Y/%m/%d %H:%M:%S", tm);
- last_t = now.tv_sec;
+ tm = localtime(&now.tv_sec);
+ strftime(buf, 127, "%Y/%m/%d %H:%M:%S", tm);
+ last_t = now.tv_sec;
}
return buf;
}
#ifdef HAVE_SPNEGO
#ifndef gss_mech_spnego
-static gss_OID_desc _gss_mech_spnego =
- { 6, (void *) "\x2b\x06\x01\x05\x05\x02" };
+static gss_OID_desc _gss_mech_spnego = { 6, (void *) "\x2b\x06\x01\x05\x05\x02" };
gss_OID gss_mech_spnego = &_gss_mech_spnego;
#endif
#endif
int
check_gss_err(OM_uint32 major_status, OM_uint32 minor_status,
- const char *function)
+ const char *function)
{
if (GSS_ERROR(major_status)) {
- OM_uint32 maj_stat, min_stat;
- OM_uint32 msg_ctx = 0;
- gss_buffer_desc status_string;
- char buf[1024];
- size_t len;
+ OM_uint32 maj_stat, min_stat;
+ OM_uint32 msg_ctx = 0;
+ gss_buffer_desc status_string;
+ char buf[1024];
+ size_t len;
- len = 0;
- msg_ctx = 0;
- while (!msg_ctx) {
- /* convert major status code (GSS-API error) to text */
- maj_stat = gss_display_status(&min_stat, major_status,
- GSS_C_GSS_CODE, GSS_C_NULL_OID, &msg_ctx, &status_string);
- if (maj_stat == GSS_S_COMPLETE) {
- if (sizeof(buf) > len + status_string.length + 1) {
- sprintf(buf + len, "%s", (char *) status_string.value);
- len += status_string.length;
- }
- gss_release_buffer(&min_stat, &status_string);
- break;
- }
- gss_release_buffer(&min_stat, &status_string);
- }
- if (sizeof(buf) > len + 2) {
- sprintf(buf + len, "%s", ". ");
- len += 2;
- }
- msg_ctx = 0;
- while (!msg_ctx) {
- /* convert minor status code (underlying routine error) to text */
- maj_stat = gss_display_status(&min_stat, minor_status,
- GSS_C_MECH_CODE, GSS_C_NULL_OID, &msg_ctx, &status_string);
- if (maj_stat == GSS_S_COMPLETE) {
- if (sizeof(buf) > len + status_string.length) {
- sprintf(buf + len, "%s", (char *) status_string.value);
- len += status_string.length;
- }
- gss_release_buffer(&min_stat, &status_string);
- break;
- }
- gss_release_buffer(&min_stat, &status_string);
- }
- fprintf(stderr, "%s| %s: %s failed: %s\n", LogTime(), PROGRAM, function,
- buf);
- return (1);
+ len = 0;
+ msg_ctx = 0;
+ while (!msg_ctx) {
+ /* convert major status code (GSS-API error) to text */
+ maj_stat = gss_display_status(&min_stat, major_status,
+ GSS_C_GSS_CODE, GSS_C_NULL_OID, &msg_ctx, &status_string);
+ if (maj_stat == GSS_S_COMPLETE) {
+ if (sizeof(buf) > len + status_string.length + 1) {
+ sprintf(buf + len, "%s", (char *) status_string.value);
+ len += status_string.length;
+ }
+ gss_release_buffer(&min_stat, &status_string);
+ break;
+ }
+ gss_release_buffer(&min_stat, &status_string);
+ }
+ if (sizeof(buf) > len + 2) {
+ sprintf(buf + len, "%s", ". ");
+ len += 2;
+ }
+ msg_ctx = 0;
+ while (!msg_ctx) {
+ /* convert minor status code (underlying routine error) to text */
+ maj_stat = gss_display_status(&min_stat, minor_status,
+ GSS_C_MECH_CODE, GSS_C_NULL_OID, &msg_ctx, &status_string);
+ if (maj_stat == GSS_S_COMPLETE) {
+ if (sizeof(buf) > len + status_string.length) {
+ sprintf(buf + len, "%s", (char *) status_string.value);
+ len += status_string.length;
+ }
+ gss_release_buffer(&min_stat, &status_string);
+ break;
+ }
+ gss_release_buffer(&min_stat, &status_string);
+ }
+ fprintf(stderr, "%s| %s: %s failed: %s\n", LogTime(), PROGRAM, function,
+ buf);
+ return (1);
}
return (0);
}
setbuf(stdin, NULL);
if (!proxy) {
- fprintf(stderr, "%s| %s: Error: No proxy server name\n", LogTime(),
- PROGRAM);
- return NULL;
+ fprintf(stderr, "%s| %s: Error: No proxy server name\n", LogTime(),
+ PROGRAM);
+ return NULL;
}
service.value = xmalloc(strlen("HTTP") + strlen(proxy) + 2);
service.length = strlen((char *) service.value);
major_status = gss_import_name(&minor_status, &service,
- gss_nt_service_name, &server_name);
+ gss_nt_service_name, &server_name);
if (check_gss_err(major_status, minor_status, "gss_import_name()"))
- goto cleanup;
+ goto cleanup;
major_status = gss_init_sec_context(&minor_status,
- GSS_C_NO_CREDENTIAL, &gss_context, server_name,
+ GSS_C_NO_CREDENTIAL, &gss_context, server_name,
#ifdef HAVE_SPNEGO
- gss_mech_spnego,
+ gss_mech_spnego,
#else
- 0,
+ 0,
#endif
- 0,
- 0,
- GSS_C_NO_CHANNEL_BINDINGS,
- &input_token, NULL, &output_token, NULL, NULL);
+ 0,
+ 0,
+ GSS_C_NO_CHANNEL_BINDINGS,
+ &input_token, NULL, &output_token, NULL, NULL);
if (check_gss_err(major_status, minor_status, "gss_init_sec_context()"))
- goto cleanup;
+ goto cleanup;
if (output_token.length) {
- token = (char*)xmalloc(ska_base64_encode_len(output_token.length));
- ska_base64_encode(token, (const char *) output_token.value,
- ska_base64_encode_len(output_token.length), output_token.length);
+ token = (char*)xmalloc(ska_base64_encode_len(output_token.length));
+ ska_base64_encode(token, (const char *) output_token.value,
+ ska_base64_encode_len(output_token.length), output_token.length);
}
- cleanup:
+cleanup:
gss_delete_sec_context(&minor_status, &gss_context, NULL);
gss_release_buffer(&minor_status, &service);
gss_release_buffer(&minor_status, &input_token);
int count;
if (argc < 2) {
- fprintf(stderr, "%s| %s: Error: No proxy server name given\n",
- LogTime(), PROGRAM);
- exit(99);
+ fprintf(stderr, "%s| %s: Error: No proxy server name given\n",
+ LogTime(), PROGRAM);
+ exit(99);
}
if (argc == 3) {
- count = atoi(argv[2]);
- while (count > 0) {
- Token = (const char *) squid_kerb_proxy_auth(argv[1]);
- fprintf(stdout, "YR %s\n", Token ? Token : "NULL");
- count--;
- }
- fprintf(stdout, "QQ\n");
+ count = atoi(argv[2]);
+ while (count > 0) {
+ Token = (const char *) squid_kerb_proxy_auth(argv[1]);
+ fprintf(stdout, "YR %s\n", Token ? Token : "NULL");
+ count--;
+ }
+ fprintf(stdout, "QQ\n");
} else {
- Token = (const char *) squid_kerb_proxy_auth(argv[1]);
- fprintf(stdout, "Token: %s\n", Token ? Token : "NULL");
+ Token = (const char *) squid_kerb_proxy_auth(argv[1]);
+ fprintf(stdout, "Token: %s\n", Token ? Token : "NULL");
}
exit(0);
int
main(int argc, char *argv[])
{
- exit(-1);
+ exit(-1);
}
#endif /* HAVE_GSSAPI */
// the array below, that a mechanism can be found.
//
MECH_OID g_stcMechOIDList[] = {
- {(unsigned char *) "\x06\x09\x2a\x86\x48\x82\xf7\x12\x01\x02\x02", 11, 9, spnego_mech_oid_Kerberos_V5_Legacy}, // 1.2.840.48018.1.2.2
+ {(unsigned char *) "\x06\x09\x2a\x86\x48\x82\xf7\x12\x01\x02\x02", 11, 9, spnego_mech_oid_Kerberos_V5_Legacy}, // 1.2.840.48018.1.2.2
{(unsigned char *) "\x06\x09\x2a\x86\x48\x86\xf7\x12\x01\x02\x02", 11, 9, spnego_mech_oid_Kerberos_V5}, // 1.2.840.113554.1.2.2
{(unsigned char *) "\x06\x06\x2b\x06\x01\x05\x05\x02", 8, 6, spnego_mech_oid_Spnego}, // 1.3.6.1.1.5.5.2
{(unsigned char *) "", 0, 0, spnego_mech_oid_NotUsed} // Placeholder
int
ASNDerGetLength(unsigned char *pbLengthData, long nBoundaryLength,
- long *pnLength, long *pnNumLengthBytes)
+ long *pnLength, long *pnNumLengthBytes)
{
int nReturn = SPNEGO_E_INVALID_LENGTH;
int nNumLengthBytes = 0;
// First check if the extended length bit is set
if (*pbLengthData & LEN_XTND) {
- // Lower 7 bits contain the number of trailing bytes that describe the length
- nNumLengthBytes = *pbLengthData & LEN_MASK;
+ // Lower 7 bits contain the number of trailing bytes that describe the length
+ nNumLengthBytes = *pbLengthData & LEN_MASK;
- // Check that the number of bytes we are about to read is within our boundary
- // constraints
+ // Check that the number of bytes we are about to read is within our boundary
+ // constraints
- if (nNumLengthBytes <= nBoundaryLength - 1) {
+ if (nNumLengthBytes <= nBoundaryLength - 1) {
- // For now, our handler won't deal with lengths greater than 4 bytes
- if (nNumLengthBytes >= 1 && nNumLengthBytes <= 4) {
- // 0 out the initial length
- *pnLength = 0L;
+ // For now, our handler won't deal with lengths greater than 4 bytes
+ if (nNumLengthBytes >= 1 && nNumLengthBytes <= 4) {
+ // 0 out the initial length
+ *pnLength = 0L;
- // Bump by 1 byte
- pbLengthData++;
+ // Bump by 1 byte
+ pbLengthData++;
#if defined(__LITTLE_ENDIAN__) || !defined(WORDS_BIGENDIAN)
- // There may be a cleaner way to do this, but for now, this seems to be
- // an easy way to do the transformation
- switch (nNumLengthBytes) {
- case 1:
- {
- *(((unsigned char *) pnLength)) = *pbLengthData;
- break;
- }
-
- case 2:
- {
- *(((unsigned char *) pnLength)) = *(pbLengthData + 1);
- *(((unsigned char *) pnLength) + 1) = *(pbLengthData);
-
- break;
- }
-
- case 3:
- {
- *(((unsigned char *) pnLength)) = *(pbLengthData + 2);
- *(((unsigned char *) pnLength) + 2) =
- *(pbLengthData + 1);
- *(((unsigned char *) pnLength) + 3) = *(pbLengthData);
- break;
- }
-
- case 4:
- {
- *(((unsigned char *) pnLength)) = *(pbLengthData + 3);
- *(((unsigned char *) pnLength) + 1) =
- *(pbLengthData + 2);
- *(((unsigned char *) pnLength) + 2) =
- *(pbLengthData + 1);
- *(((unsigned char *) pnLength) + 3) = *(pbLengthData);
- break;
- }
-
- } // SWITCH ( nNumLengthBytes )
+ // There may be a cleaner way to do this, but for now, this seems to be
+ // an easy way to do the transformation
+ switch (nNumLengthBytes) {
+ case 1: {
+ *(((unsigned char *) pnLength)) = *pbLengthData;
+ break;
+ }
+
+ case 2: {
+ *(((unsigned char *) pnLength)) = *(pbLengthData + 1);
+ *(((unsigned char *) pnLength) + 1) = *(pbLengthData);
+
+ break;
+ }
+
+ case 3: {
+ *(((unsigned char *) pnLength)) = *(pbLengthData + 2);
+ *(((unsigned char *) pnLength) + 2) =
+ *(pbLengthData + 1);
+ *(((unsigned char *) pnLength) + 3) = *(pbLengthData);
+ break;
+ }
+
+ case 4: {
+ *(((unsigned char *) pnLength)) = *(pbLengthData + 3);
+ *(((unsigned char *) pnLength) + 1) =
+ *(pbLengthData + 2);
+ *(((unsigned char *) pnLength) + 2) =
+ *(pbLengthData + 1);
+ *(((unsigned char *) pnLength) + 3) = *(pbLengthData);
+ break;
+ }
+
+ } // SWITCH ( nNumLengthBytes )
#else
- // We are Big-Endian, so the length can be copied in from the source
- // as is. Ensure that we adjust for the number of bytes we actually
- // copy.
+ // We are Big-Endian, so the length can be copied in from the source
+ // as is. Ensure that we adjust for the number of bytes we actually
+ // copy.
- memcpy(((unsigned char *) pnLength) + (4 - nNumLengthBytes),
- pbLengthData, nNumLengthBytes);
+ memcpy(((unsigned char *) pnLength) + (4 - nNumLengthBytes),
+ pbLengthData, nNumLengthBytes);
#endif
- // Account for the initial length byte
- *pnNumLengthBytes = nNumLengthBytes + 1;
- nReturn = SPNEGO_E_SUCCESS;
+ // Account for the initial length byte
+ *pnNumLengthBytes = nNumLengthBytes + 1;
+ nReturn = SPNEGO_E_SUCCESS;
- } // IF Valid Length
+ } // IF Valid Length
- } // IF num bytes to read is within the boundary length
+ } // IF num bytes to read is within the boundary length
} // IF xtended length
else {
- // Extended bit is not set, so the length is in the value and the one
- // byte describes the length
- *pnLength = *pbLengthData & LEN_MASK;
- *pnNumLengthBytes = 1;
- nReturn = SPNEGO_E_SUCCESS;
+ // Extended bit is not set, so the length is in the value and the one
+ // byte describes the length
+ *pnLength = *pbLengthData & LEN_MASK;
+ *pnNumLengthBytes = 1;
+ nReturn = SPNEGO_E_SUCCESS;
}
LOG(("ASNDerGetLength returned %d\n", nReturn));
// [in] nLengthWithToken - Expected token length (with data)
// [in] nBoundaryLength - Length that value must not exceed.
// [out] pnLength - Filled out with data length
-// [out] pnTokenLength - Filled out with number of bytes
+// [out] pnTokenLength - Filled out with number of bytes
// consumed by token identifier and length.
//
// Returns:
int
ASNDerCheckToken(unsigned char *pbTokenData, unsigned char nToken,
- long nLengthWithToken, long nBoundaryLength,
- long *pnLength, long *pnTokenLength)
+ long nLengthWithToken, long nBoundaryLength,
+ long *pnLength, long *pnTokenLength)
{
int nReturn = SPNEGO_E_INVALID_LENGTH;
// Make sure that we've at least got 2 bytes of room to work with
if (nBoundaryLength >= 2) {
- // The first byte of the token data MUST match the specified token
- if (*pbTokenData == nToken) {
- // Next byte indicates the length
- pbTokenData++;
+ // The first byte of the token data MUST match the specified token
+ if (*pbTokenData == nToken) {
+ // Next byte indicates the length
+ pbTokenData++;
- // Get the length described by the token
- if ((nReturn =
- ASNDerGetLength(pbTokenData, nBoundaryLength, pnLength,
- &nNumLengthBytes)) == SPNEGO_E_SUCCESS) {
- // Verify that the length is LESS THAN the boundary length
- // (this should prevent us walking out of our buffer)
- if ((nBoundaryLength - (nNumLengthBytes + 1) < *pnLength)) {
+ // Get the length described by the token
+ if ((nReturn =
+ ASNDerGetLength(pbTokenData, nBoundaryLength, pnLength,
+ &nNumLengthBytes)) == SPNEGO_E_SUCCESS) {
+ // Verify that the length is LESS THAN the boundary length
+ // (this should prevent us walking out of our buffer)
+ if ((nBoundaryLength - (nNumLengthBytes + 1) < *pnLength)) {
- nReturn = SPNEGO_E_INVALID_LENGTH;
+ nReturn = SPNEGO_E_INVALID_LENGTH;
- }
- // If we were passed a length to check, do so now
- if (nLengthWithToken > 0L) {
+ }
+ // If we were passed a length to check, do so now
+ if (nLengthWithToken > 0L) {
- // Check that the expected length matches
- if ((nLengthWithToken - (nNumLengthBytes + 1)) != *pnLength) {
+ // Check that the expected length matches
+ if ((nLengthWithToken - (nNumLengthBytes + 1)) != *pnLength) {
- nReturn = SPNEGO_E_INVALID_LENGTH;
+ nReturn = SPNEGO_E_INVALID_LENGTH;
- }
+ }
- } // IF need to validate length
+ } // IF need to validate length
- if (SPNEGO_E_SUCCESS == nReturn) {
- *pnTokenLength = nNumLengthBytes + 1;
- }
+ if (SPNEGO_E_SUCCESS == nReturn) {
+ *pnTokenLength = nNumLengthBytes + 1;
+ }
- } // IF ASNDerGetLength
+ } // IF ASNDerGetLength
- } // IF token matches
- else {
- nReturn = SPNEGO_E_TOKEN_NOT_FOUND;
- }
+ } // IF token matches
+ else {
+ nReturn = SPNEGO_E_TOKEN_NOT_FOUND;
+ }
- } // IF Boundary Length is at least 2 bytes
+ } // IF Boundary Length is at least 2 bytes
LOG(("ASNDerCheckToken returned %d\n", nReturn));
return nReturn;
int
ASNDerCheckOID(unsigned char *pbTokenData, SPNEGO_MECH_OID nMechOID,
- long nBoundaryLength, long *pnTokenLength)
+ long nBoundaryLength, long *pnTokenLength)
{
int nReturn = 0L;
long nLength = 0L;
// Verify that we have an OID token
if ((nReturn = ASNDerCheckToken(pbTokenData, OID, 0L, nBoundaryLength,
- &nLength, pnTokenLength)) == SPNEGO_E_SUCCESS) {
- // Add the data length to the Token Length
- *pnTokenLength += nLength;
-
- // Token Lengths plus the actual length must match the length in our OID list element.
- // If it doesn't, we're done
- if (*pnTokenLength == g_stcMechOIDList[nMechOID].iLen) {
- // Memcompare the token and the expected field
- if (memcmp(pbTokenData, g_stcMechOIDList[nMechOID].ucOid,
- *pnTokenLength) != 0) {
- LOG(("ASNDerCheckOID memcmp failed\n"));
- nReturn = SPNEGO_E_UNEXPECTED_OID;
- }
- } else {
- LOG(("ASNDerCheckOID token length failed\n"));
- nReturn = SPNEGO_E_UNEXPECTED_OID;
- }
+ &nLength, pnTokenLength)) == SPNEGO_E_SUCCESS) {
+ // Add the data length to the Token Length
+ *pnTokenLength += nLength;
+
+ // Token Lengths plus the actual length must match the length in our OID list element.
+ // If it doesn't, we're done
+ if (*pnTokenLength == g_stcMechOIDList[nMechOID].iLen) {
+ // Memcompare the token and the expected field
+ if (memcmp(pbTokenData, g_stcMechOIDList[nMechOID].ucOid,
+ *pnTokenLength) != 0) {
+ LOG(("ASNDerCheckOID memcmp failed\n"));
+ nReturn = SPNEGO_E_UNEXPECTED_OID;
+ }
+ } else {
+ LOG(("ASNDerCheckOID token length failed\n"));
+ nReturn = SPNEGO_E_UNEXPECTED_OID;
+ }
} // IF OID Token CHecks
ASNDerCalcNumLengthBytes(long nLength)
{
if (nLength <= 0x7F) {
- // A single byte will be sufficient for describing this length.
- // The byte will simply contain the length
- return 1;
+ // A single byte will be sufficient for describing this length.
+ // The byte will simply contain the length
+ return 1;
} else if (nLength <= 0xFF) {
- // Two bytes are necessary, one to say how many following bytes
- // describe the length, and one to give the length
- return 2;
+ // Two bytes are necessary, one to say how many following bytes
+ // describe the length, and one to give the length
+ return 2;
} else if (nLength <= 0xFFFF) {
- // Three bytes are necessary, one to say how many following bytes
- // describe the length, and two to give the length
- return 3;
+ // Three bytes are necessary, one to say how many following bytes
+ // describe the length, and two to give the length
+ return 3;
} else if (nLength <= 0xFFFFFF) {
- // Four bytes are necessary, one to say how many following bytes
- // describe the length, and three to give the length
- return 4;
+ // Four bytes are necessary, one to say how many following bytes
+ // describe the length, and three to give the length
+ return 4;
} else {
- // Five bytes are necessary, one to say how many following bytes
- // describe the length, and four to give the length
- return 5;
+ // Five bytes are necessary, one to say how many following bytes
+ // describe the length, and four to give the length
+ return 5;
}
}
// Internal length is the length without the element sequence token
if (NULL != pnInternalLength) {
- *pnInternalLength = nTotalLength;
+ *pnInternalLength = nTotalLength;
}
// Next add in the element's sequence token (remember that its
// length is the total length of the type token and data)
// Internal length is the length without the element sequence token
if (NULL != pnInternalLength) {
- *pnInternalLength = nTotalLength;
+ *pnInternalLength = nTotalLength;
}
// Finally add in the element's sequence token
nTotalLength += ASNDerCalcTokenLength(nTotalLength, 0L);
if (nNumBytesRequired > 1) {
- // Write out the number of bytes following which will be used
- *pbData = (unsigned char) (LEN_XTND | nNumLengthBytes);
+ // Write out the number of bytes following which will be used
+ *pbData = (unsigned char) (LEN_XTND | nNumLengthBytes);
- // Point to where we'll actually write the length
- pbData++;
+ // Point to where we'll actually write the length
+ pbData++;
#if defined(__LITTLE_ENDIAN__) || !defined(WORDS_BIGENDIAN)
- // There may be a cleaner way to do this, but for now, this seems to be
- // an easy way to do the transformation
- switch (nNumLengthBytes) {
- case 1:
- {
- // Cast the length to a single byte, since we know that it
- // is 0x7F or less (or we wouldn't only need a single byte).
-
- *pbData = (unsigned char) nLength;
- break;
- }
-
- case 2:
- {
- *pbData = *(((unsigned char *) &nLength) + 1);
- *(pbData + 1) = *(((unsigned char *) &nLength));
- break;
- }
-
- case 3:
- {
- *pbData = *(((unsigned char *) &nLength) + 3);
- *(pbData + 1) = *(((unsigned char *) &nLength) + 2);
- *(pbData + 2) = *(((unsigned char *) &nLength));
- break;
- }
-
- case 4:
- {
- *pbData = *(((unsigned char *) &nLength) + 3);
- *(pbData + 1) = *(((unsigned char *) &nLength) + 2);
- *(pbData + 2) = *(((unsigned char *) &nLength) + 1);
- *(pbData + 3) = *(((unsigned char *) &nLength));
- break;
- }
-
- } // SWITCH ( nNumLengthBytes )
+ // There may be a cleaner way to do this, but for now, this seems to be
+ // an easy way to do the transformation
+ switch (nNumLengthBytes) {
+ case 1: {
+ // Cast the length to a single byte, since we know that it
+ // is 0x7F or less (or we wouldn't only need a single byte).
+
+ *pbData = (unsigned char) nLength;
+ break;
+ }
+
+ case 2: {
+ *pbData = *(((unsigned char *) &nLength) + 1);
+ *(pbData + 1) = *(((unsigned char *) &nLength));
+ break;
+ }
+
+ case 3: {
+ *pbData = *(((unsigned char *) &nLength) + 3);
+ *(pbData + 1) = *(((unsigned char *) &nLength) + 2);
+ *(pbData + 2) = *(((unsigned char *) &nLength));
+ break;
+ }
+
+ case 4: {
+ *pbData = *(((unsigned char *) &nLength) + 3);
+ *(pbData + 1) = *(((unsigned char *) &nLength) + 2);
+ *(pbData + 2) = *(((unsigned char *) &nLength) + 1);
+ *(pbData + 3) = *(((unsigned char *) &nLength));
+ break;
+ }
+
+ } // SWITCH ( nNumLengthBytes )
#else
- // We are Big-Endian, so the length can be copied in from the source
- // as is. Ensure that we adjust for the number of bytes we actually
- // copy.
+ // We are Big-Endian, so the length can be copied in from the source
+ // as is. Ensure that we adjust for the number of bytes we actually
+ // copy.
- memcpy(pbData,
- ((unsigned char *) &nLength) + (4 - nNumLengthBytes),
- nNumLengthBytes);
+ memcpy(pbData,
+ ((unsigned char *) &nLength) + (4 - nNumLengthBytes),
+ nNumLengthBytes);
#endif
} // IF > 1 byte for length
else {
- // Cast the length to a single byte, since we know that it
- // is 0x7F or less (or we wouldn't only need a single byte).
+ // Cast the length to a single byte, since we know that it
+ // is 0x7F or less (or we wouldn't only need a single byte).
- *pbData = (unsigned char) nLength;
+ *pbData = (unsigned char) nLength;
}
return nNumBytesRequired;
int
ASNDerWriteToken(unsigned char *pbData, unsigned char ucType,
- unsigned char *pbTokenValue, long nLength)
+ unsigned char *pbTokenValue, long nLength)
{
int nTotalBytesWrittenOut = 0L;
int nNumLengthBytesWritten = 0L;
// nLength value indicates how many bytes are in pbTokenValue.
if (NULL != pbTokenValue) {
- memcpy(pbData, pbTokenValue, nLength);
- nTotalBytesWrittenOut += nLength;
+ memcpy(pbData, pbTokenValue, nLength);
+ nTotalBytesWrittenOut += nLength;
}
return nTotalBytesWrittenOut;
{
memcpy(pbData, g_stcMechOIDList[eMechOID].ucOid,
- g_stcMechOIDList[eMechOID].iLen);
+ g_stcMechOIDList[eMechOID].iLen);
return g_stcMechOIDList[eMechOID].iLen;
}
long nTempLength = 0L;
nTempLength = ASNDerWriteToken(pbData, SPNEGO_NEGINIT_ELEMENT_MECHTYPES,
- NULL, nInternalLength);
+ NULL, nInternalLength);
// Adjust the data pointer
pbData += nTempLength;
// structure.
nTempLength = ASNDerWriteToken(pbData, SPNEGO_CONSTRUCTED_SEQUENCE,
- g_stcMechOIDList[mechoid].ucOid, g_stcMechOIDList[mechoid].iLen);
+ g_stcMechOIDList[mechoid].ucOid, g_stcMechOIDList[mechoid].iLen);
return nMechListLength;
}
int
ASNDerWriteElement(unsigned char *pbData, unsigned char ucElementSequence,
- unsigned char ucType, unsigned char *pbTokenValue, long nLength)
+ unsigned char ucType, unsigned char *pbTokenValue, long nLength)
{
// First get the length
long nInternalLength = 0L;
// Write out the sequence byte and the length of the type and data
nTempLength =
- ASNDerWriteToken(pbData, ucElementSequence, NULL, nInternalLength);
+ ASNDerWriteToken(pbData, ucElementSequence, NULL, nInternalLength);
// Adjust the data pointer
pbData += nTempLength;
// C++ Specific
#if defined(__cplusplus)
-extern "C"
-{
+extern "C" {
#endif
-/* Identifier Types */
+ /* Identifier Types */
#define IDENTIFIER_MASK 0xC0 // Bits 7 and 8
#define IDENTIFIER_UNIVERSAL 0x00 // 00 = universal
#define IDENTIFIER_APPLICATION 0x40 // 01 = application
#define IDENTIFIER_CONTEXT_SPECIFIC 0x80 // 10 = context specific
#define IDENTIFIER_PRIVATE 0xC0 // 11 = Private
-/* Encoding type */
+ /* Encoding type */
#define FORM_MASK 0x20 /* Bit 6 */
#define PRIMITIVE 0x00 /* 0 = primitive */
#define CONSTRUCTED 0x20 /* 1 = constructed */
-/* Universal tags */
+ /* Universal tags */
#define TAG_MASK 0x1F /* Bits 5 - 1 */
#define BOOLEAN 0x01 /* 1: TRUE or FALSE */
#define UNIVERSALSTR 0x1C /* 28: Universal String */
#define BMPSTR 0x1E /* 30: Basic Multilingual Plane String */
-/* Length encoding */
+ /* Length encoding */
#define LEN_XTND 0x80 /* Indefinite or long form */
#define LEN_MASK 0x7f /* Bits 7 - 1 */
// of these which we'll use for validation/searches/parsing.
//
- typedef struct _mechOID
- {
- unsigned char *ucOid; // Byte representation of OID
- int iLen; // Length of the OID, length and identifier
- int iActualDataLen; // Length of the actual OID
- SPNEGO_MECH_OID eMechanismOID; // Which OID is this?
+ typedef struct _mechOID {
+ unsigned char *ucOid; // Byte representation of OID
+ int iLen; // Length of the OID, length and identifier
+ int iActualDataLen; // Length of the actual OID
+ SPNEGO_MECH_OID eMechanismOID; // Which OID is this?
} MECH_OID;
//
int ASNDerGetLength(unsigned char *pbLengthData, long nBoundaryLength,
- long *pnLength, long *pnNumLengthBytes);
+ long *pnLength, long *pnNumLengthBytes);
int ASNDerCheckToken(unsigned char *pbTokenData, unsigned char nToken,
- long nCheckLength, long nBoundaryLength, long *pnLength,
- long *pnTokenLength);
+ long nCheckLength, long nBoundaryLength, long *pnLength,
+ long *pnTokenLength);
int ASNDerCheckOID(unsigned char *pbTokenData, SPNEGO_MECH_OID nMechOID,
- long nBoundaryLength, long *pnTokenLength);
+ long nBoundaryLength, long *pnTokenLength);
int ASNDerCalcNumLengthBytes(long nLength);
long ASNDerCalcTokenLength(long nLength, long nDataLength);
long ASNDerCalcElementLength(long nDataLength, long *pnInternalLength);
long ASNDerCalcMechListLength(SPNEGO_MECH_OID mechoid,
- long *pnInternalLength);
+ long *pnInternalLength);
int ASNDerWriteLength(unsigned char *pbData, long nLength);
int ASNDerWriteToken(unsigned char *pbData, unsigned char ucType,
- unsigned char *pbTokenValue, long nLength);
+ unsigned char *pbTokenValue, long nLength);
int ASNDerWriteOID(unsigned char *pbData, SPNEGO_MECH_OID eMechOID);
long ASNDerWriteMechList(unsigned char *pbData, SPNEGO_MECH_OID mechoid);
int ASNDerWriteElement(unsigned char *pbData,
- unsigned char ucElementSequence, unsigned char ucType,
- unsigned char *pbTokenValue, long nLength);
+ unsigned char ucElementSequence, unsigned char ucType,
+ unsigned char *pbTokenValue, long nLength);
// C++ Specific
int
spnegoInitFromBinary(unsigned char *pbTokenData, unsigned long ulLength,
- SPNEGO_TOKEN_HANDLE * phSpnegoToken)
+ SPNEGO_TOKEN_HANDLE * phSpnegoToken)
{
int nReturn = SPNEGO_E_INVALID_PARAMETER;
SPNEGO_TOKEN **ppSpnegoToken = (SPNEGO_TOKEN **) phSpnegoToken;
// is handled. In this case, we want the token data copied and we want the associated buffer
// freed.
nReturn = InitTokenFromBinary(SPNEGO_TOKEN_INTERNAL_COPYDATA,
- SPNEGO_TOKEN_INTERNAL_FLAGS_FREEDATA, pbTokenData,
- ulLength, ppSpnegoToken);
+ SPNEGO_TOKEN_INTERNAL_FLAGS_FREEDATA, pbTokenData,
+ ulLength, ppSpnegoToken);
LOG(("spnegoInitFromBinary returned %d\n", nReturn));
return nReturn;
int
spnegoCreateNegTokenInit(SPNEGO_MECH_OID MechType,
- unsigned char ucContextFlags, unsigned char *pbMechToken,
- unsigned long ulMechTokenLen, unsigned char *pbMechListMIC,
- unsigned long ulMechListMICLen, SPNEGO_TOKEN_HANDLE * phSpnegoToken)
+ unsigned char ucContextFlags, unsigned char *pbMechToken,
+ unsigned long ulMechTokenLen, unsigned char *pbMechListMIC,
+ unsigned long ulMechListMICLen, SPNEGO_TOKEN_HANDLE * phSpnegoToken)
{
int nReturn = SPNEGO_E_INVALID_PARAMETER;
long nTokenLength = 0L;
SPNEGO_TOKEN **ppSpnegoToken = (SPNEGO_TOKEN **) phSpnegoToken;
if (NULL != ppSpnegoToken &&
- IsValidMechOid(MechType) && IsValidContextFlags(ucContextFlags)) {
- // Get the actual token size
-
- if ((nReturn =
- CalculateMinSpnegoInitTokenSize(ulMechTokenLen,
- ulMechListMICLen, MechType, (ucContextFlags != 0L),
- &nTokenLength, &nInternalTokenLength))
- == SPNEGO_E_SUCCESS) {
- // Allocate a buffer to hold the data.
- pbTokenData = calloc(1, nTokenLength);
-
- if (NULL != pbTokenData) {
-
- // Now write the token
- if ((nReturn = CreateSpnegoInitToken(MechType,
- ucContextFlags, pbMechToken,
- ulMechTokenLen, pbMechListMIC,
- ulMechListMICLen, pbTokenData,
- nTokenLength, nInternalTokenLength))
- == SPNEGO_E_SUCCESS) {
-
- // This will copy our allocated pointer, and ensure that the sructure cleans
- // up the data later
- nReturn = InitTokenFromBinary(SPNEGO_TOKEN_INTERNAL_COPYPTR,
- SPNEGO_TOKEN_INTERNAL_FLAGS_FREEDATA,
- pbTokenData, nTokenLength, ppSpnegoToken);
-
- }
- // Cleanup on failure
- if (SPNEGO_E_SUCCESS != nReturn) {
- free(pbTokenData);
- }
-
- } // IF alloc succeeded
- else {
- nReturn = SPNEGO_E_OUT_OF_MEMORY;
- }
-
- } // If calculated token size
+ IsValidMechOid(MechType) && IsValidContextFlags(ucContextFlags)) {
+ // Get the actual token size
+
+ if ((nReturn =
+ CalculateMinSpnegoInitTokenSize(ulMechTokenLen,
+ ulMechListMICLen, MechType, (ucContextFlags != 0L),
+ &nTokenLength, &nInternalTokenLength))
+ == SPNEGO_E_SUCCESS) {
+ // Allocate a buffer to hold the data.
+ pbTokenData = calloc(1, nTokenLength);
+
+ if (NULL != pbTokenData) {
+
+ // Now write the token
+ if ((nReturn = CreateSpnegoInitToken(MechType,
+ ucContextFlags, pbMechToken,
+ ulMechTokenLen, pbMechListMIC,
+ ulMechListMICLen, pbTokenData,
+ nTokenLength, nInternalTokenLength))
+ == SPNEGO_E_SUCCESS) {
+
+ // This will copy our allocated pointer, and ensure that the sructure cleans
+ // up the data later
+ nReturn = InitTokenFromBinary(SPNEGO_TOKEN_INTERNAL_COPYPTR,
+ SPNEGO_TOKEN_INTERNAL_FLAGS_FREEDATA,
+ pbTokenData, nTokenLength, ppSpnegoToken);
+
+ }
+ // Cleanup on failure
+ if (SPNEGO_E_SUCCESS != nReturn) {
+ free(pbTokenData);
+ }
+
+ } // IF alloc succeeded
+ else {
+ nReturn = SPNEGO_E_OUT_OF_MEMORY;
+ }
+
+ } // If calculated token size
} // IF Valid Parameters
int
spnegoCreateNegTokenTarg(SPNEGO_MECH_OID MechType,
- SPNEGO_NEGRESULT spnegoNegResult, unsigned char *pbMechToken,
- unsigned long ulMechTokenLen, unsigned char *pbMechListMIC,
- unsigned long ulMechListMICLen, SPNEGO_TOKEN_HANDLE * phSpnegoToken)
+ SPNEGO_NEGRESULT spnegoNegResult, unsigned char *pbMechToken,
+ unsigned long ulMechTokenLen, unsigned char *pbMechListMIC,
+ unsigned long ulMechListMICLen, SPNEGO_TOKEN_HANDLE * phSpnegoToken)
{
int nReturn = SPNEGO_E_INVALID_PARAMETER;
long nTokenLength = 0L;
//
if (NULL != ppSpnegoToken &&
- (IsValidMechOid(MechType) ||
- spnego_mech_oid_NotUsed == MechType) &&
- (IsValidNegResult(spnegoNegResult) ||
- spnego_negresult_NotUsed == spnegoNegResult) &&
- !(!IsValidMechOid(MechType) &&
- (spnego_negresult_success == spnegoNegResult ||
- spnego_negresult_incomplete == spnegoNegResult))) {
-
- // Get the actual token size
-
- if ((nReturn =
- CalculateMinSpnegoTargTokenSize(MechType, spnegoNegResult,
- ulMechTokenLen, ulMechListMICLen, &nTokenLength,
- &nInternalTokenLength))
- == SPNEGO_E_SUCCESS) {
- // Allocate a buffer to hold the data.
- pbTokenData = calloc(1, nTokenLength);
-
- if (NULL != pbTokenData) {
-
- // Now write the token
- if ((nReturn = CreateSpnegoTargToken(MechType,
- spnegoNegResult, pbMechToken,
- ulMechTokenLen, pbMechListMIC,
- ulMechListMICLen, pbTokenData,
- nTokenLength, nInternalTokenLength))
- == SPNEGO_E_SUCCESS) {
-
- // This will copy our allocated pointer, and ensure that the sructure cleans
- // up the data later
- nReturn = InitTokenFromBinary(SPNEGO_TOKEN_INTERNAL_COPYPTR,
- SPNEGO_TOKEN_INTERNAL_FLAGS_FREEDATA,
- pbTokenData, nTokenLength, ppSpnegoToken);
-
- }
- // Cleanup on failure
- if (SPNEGO_E_SUCCESS != nReturn) {
- free(pbTokenData);
- }
-
- } // IF alloc succeeded
- else {
- nReturn = SPNEGO_E_OUT_OF_MEMORY;
- }
-
- } // If calculated token size
+ (IsValidMechOid(MechType) ||
+ spnego_mech_oid_NotUsed == MechType) &&
+ (IsValidNegResult(spnegoNegResult) ||
+ spnego_negresult_NotUsed == spnegoNegResult) &&
+ !(!IsValidMechOid(MechType) &&
+ (spnego_negresult_success == spnegoNegResult ||
+ spnego_negresult_incomplete == spnegoNegResult))) {
+
+ // Get the actual token size
+
+ if ((nReturn =
+ CalculateMinSpnegoTargTokenSize(MechType, spnegoNegResult,
+ ulMechTokenLen, ulMechListMICLen, &nTokenLength,
+ &nInternalTokenLength))
+ == SPNEGO_E_SUCCESS) {
+ // Allocate a buffer to hold the data.
+ pbTokenData = calloc(1, nTokenLength);
+
+ if (NULL != pbTokenData) {
+
+ // Now write the token
+ if ((nReturn = CreateSpnegoTargToken(MechType,
+ spnegoNegResult, pbMechToken,
+ ulMechTokenLen, pbMechListMIC,
+ ulMechListMICLen, pbTokenData,
+ nTokenLength, nInternalTokenLength))
+ == SPNEGO_E_SUCCESS) {
+
+ // This will copy our allocated pointer, and ensure that the sructure cleans
+ // up the data later
+ nReturn = InitTokenFromBinary(SPNEGO_TOKEN_INTERNAL_COPYPTR,
+ SPNEGO_TOKEN_INTERNAL_FLAGS_FREEDATA,
+ pbTokenData, nTokenLength, ppSpnegoToken);
+
+ }
+ // Cleanup on failure
+ if (SPNEGO_E_SUCCESS != nReturn) {
+ free(pbTokenData);
+ }
+
+ } // IF alloc succeeded
+ else {
+ nReturn = SPNEGO_E_OUT_OF_MEMORY;
+ }
+
+ } // If calculated token size
} // IF Valid Parameters
int
spnegoTokenGetBinary(SPNEGO_TOKEN_HANDLE hSpnegoToken,
- unsigned char *pbTokenData, unsigned long *pulDataLen)
+ unsigned char *pbTokenData, unsigned long *pulDataLen)
{
int nReturn = SPNEGO_E_INVALID_PARAMETER;
SPNEGO_TOKEN *pSpnegoToken = (SPNEGO_TOKEN *) hSpnegoToken;
// Check parameters - pbTokenData is optional
if (IsValidSpnegoToken(pSpnegoToken) && NULL != pulDataLen) {
- // Check for Buffer too small conditions
- if (NULL == pbTokenData || pSpnegoToken->ulBinaryDataLen > *pulDataLen) {
- *pulDataLen = pSpnegoToken->ulBinaryDataLen;
- nReturn = SPNEGO_E_BUFFER_TOO_SMALL;
- } else {
- memcpy(pbTokenData, pSpnegoToken->pbBinaryData,
- pSpnegoToken->ulBinaryDataLen);
- *pulDataLen = pSpnegoToken->ulBinaryDataLen;
- nReturn = SPNEGO_E_SUCCESS;
- }
+ // Check for Buffer too small conditions
+ if (NULL == pbTokenData || pSpnegoToken->ulBinaryDataLen > *pulDataLen) {
+ *pulDataLen = pSpnegoToken->ulBinaryDataLen;
+ nReturn = SPNEGO_E_BUFFER_TOO_SMALL;
+ } else {
+ memcpy(pbTokenData, pSpnegoToken->pbBinaryData,
+ pSpnegoToken->ulBinaryDataLen);
+ *pulDataLen = pSpnegoToken->ulBinaryDataLen;
+ nReturn = SPNEGO_E_SUCCESS;
+ }
} // IF parameters OK
// Check parameters
if (IsValidSpnegoToken(pSpnegoToken) && NULL != piTokenType && pSpnegoToken) {
- // Check that the type in the structure makes sense
- if (SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType ||
- SPNEGO_TOKEN_TARG == pSpnegoToken->ucTokenType) {
- *piTokenType = pSpnegoToken->ucTokenType;
- nReturn = SPNEGO_E_SUCCESS;
- }
+ // Check that the type in the structure makes sense
+ if (SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType ||
+ SPNEGO_TOKEN_TARG == pSpnegoToken->ucTokenType) {
+ *piTokenType = pSpnegoToken->ucTokenType;
+ nReturn = SPNEGO_E_SUCCESS;
+ }
} // IF parameters OK
// Returns the Initial Mech Type in the MechList element in the NegInitToken.
int
spnegoIsMechTypeAvailable(SPNEGO_TOKEN_HANDLE hSpnegoToken,
- SPNEGO_MECH_OID MechOID, int *piMechTypeIndex)
+ SPNEGO_MECH_OID MechOID, int *piMechTypeIndex)
{
int nReturn = SPNEGO_E_INVALID_PARAMETER;
SPNEGO_TOKEN *pSpnegoToken = (SPNEGO_TOKEN *) hSpnegoToken;
// Check parameters
if (IsValidSpnegoToken(pSpnegoToken) &&
- NULL != piMechTypeIndex &&
- IsValidMechOid(MechOID) &&
- SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType) {
-
- // Check if MechList is available
- if (pSpnegoToken->aElementArray[SPNEGO_INIT_MECHTYPES_ELEMENT].
- iElementPresent == SPNEGO_TOKEN_ELEMENT_AVAILABLE) {
- // Locate the MechOID in the list element
- nReturn =
- FindMechOIDInMechList(&pSpnegoToken->
- aElementArray[SPNEGO_INIT_MECHTYPES_ELEMENT], MechOID,
- piMechTypeIndex);
- } else {
- nReturn = SPNEGO_E_ELEMENT_UNAVAILABLE;
- }
+ NULL != piMechTypeIndex &&
+ IsValidMechOid(MechOID) &&
+ SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType) {
+
+ // Check if MechList is available
+ if (pSpnegoToken->aElementArray[SPNEGO_INIT_MECHTYPES_ELEMENT].
+ iElementPresent == SPNEGO_TOKEN_ELEMENT_AVAILABLE) {
+ // Locate the MechOID in the list element
+ nReturn =
+ FindMechOIDInMechList(&pSpnegoToken->
+ aElementArray[SPNEGO_INIT_MECHTYPES_ELEMENT], MechOID,
+ piMechTypeIndex);
+ } else {
+ nReturn = SPNEGO_E_ELEMENT_UNAVAILABLE;
+ }
} // IF parameters OK
int
spnegoGetContextFlags(SPNEGO_TOKEN_HANDLE hSpnegoToken,
- unsigned char *pucContextFlags)
+ unsigned char *pucContextFlags)
{
int nReturn = SPNEGO_E_INVALID_PARAMETER;
SPNEGO_TOKEN *pSpnegoToken = (SPNEGO_TOKEN *) hSpnegoToken;
// Check parameters
if (IsValidSpnegoToken(pSpnegoToken) &&
- NULL != pucContextFlags &&
- SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType) {
-
- // Check if ContextFlags is available
- if (pSpnegoToken->aElementArray[SPNEGO_INIT_REQFLAGS_ELEMENT].
- iElementPresent == SPNEGO_TOKEN_ELEMENT_AVAILABLE) {
- // The length should be two, the value should show a 1 bit difference in the difference byte, and
- // the value must be valid
- if (pSpnegoToken->aElementArray[SPNEGO_INIT_REQFLAGS_ELEMENT].
- nDatalength == SPNEGO_NEGINIT_MAXLEN_REQFLAGS
- && pSpnegoToken->aElementArray[SPNEGO_INIT_REQFLAGS_ELEMENT].
- pbData[0] == SPNEGO_NEGINIT_REQFLAGS_BITDIFF
- && IsValidContextFlags(pSpnegoToken->
- aElementArray[SPNEGO_INIT_REQFLAGS_ELEMENT].pbData[1])) {
- *pucContextFlags =
- pSpnegoToken->aElementArray[SPNEGO_INIT_REQFLAGS_ELEMENT].
- pbData[1];
- nReturn = SPNEGO_E_SUCCESS;
- } else {
- nReturn = SPNEGO_E_INVALID_ELEMENT;
- }
-
- } else {
- nReturn = SPNEGO_E_ELEMENT_UNAVAILABLE;
- }
+ NULL != pucContextFlags &&
+ SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType) {
+
+ // Check if ContextFlags is available
+ if (pSpnegoToken->aElementArray[SPNEGO_INIT_REQFLAGS_ELEMENT].
+ iElementPresent == SPNEGO_TOKEN_ELEMENT_AVAILABLE) {
+ // The length should be two, the value should show a 1 bit difference in the difference byte, and
+ // the value must be valid
+ if (pSpnegoToken->aElementArray[SPNEGO_INIT_REQFLAGS_ELEMENT].
+ nDatalength == SPNEGO_NEGINIT_MAXLEN_REQFLAGS
+ && pSpnegoToken->aElementArray[SPNEGO_INIT_REQFLAGS_ELEMENT].
+ pbData[0] == SPNEGO_NEGINIT_REQFLAGS_BITDIFF
+ && IsValidContextFlags(pSpnegoToken->
+ aElementArray[SPNEGO_INIT_REQFLAGS_ELEMENT].pbData[1])) {
+ *pucContextFlags =
+ pSpnegoToken->aElementArray[SPNEGO_INIT_REQFLAGS_ELEMENT].
+ pbData[1];
+ nReturn = SPNEGO_E_SUCCESS;
+ } else {
+ nReturn = SPNEGO_E_INVALID_ELEMENT;
+ }
+
+ } else {
+ nReturn = SPNEGO_E_ELEMENT_UNAVAILABLE;
+ }
} // IF parameters OK
int
spnegoGetNegotiationResult(SPNEGO_TOKEN_HANDLE hSpnegoToken,
- SPNEGO_NEGRESULT * pnegResult)
+ SPNEGO_NEGRESULT * pnegResult)
{
int nReturn = SPNEGO_E_INVALID_PARAMETER;
SPNEGO_TOKEN *pSpnegoToken = (SPNEGO_TOKEN *) hSpnegoToken;
// Check parameters
if (IsValidSpnegoToken(pSpnegoToken) &&
- NULL != pnegResult && SPNEGO_TOKEN_TARG == pSpnegoToken->ucTokenType) {
-
- // Check if NegResult is available
- if (pSpnegoToken->aElementArray[SPNEGO_TARG_NEGRESULT_ELEMENT].
- iElementPresent == SPNEGO_TOKEN_ELEMENT_AVAILABLE) {
- // Must be 1 byte long and a valid value
- if (pSpnegoToken->aElementArray[SPNEGO_TARG_NEGRESULT_ELEMENT].
- nDatalength == SPNEGO_NEGTARG_MAXLEN_NEGRESULT
- && IsValidNegResult(*pSpnegoToken->
- aElementArray[SPNEGO_TARG_NEGRESULT_ELEMENT].pbData)) {
- *pnegResult =
- *pSpnegoToken->aElementArray[SPNEGO_TARG_NEGRESULT_ELEMENT].
- pbData;
- nReturn = SPNEGO_E_SUCCESS;
- } else {
- nReturn = SPNEGO_E_INVALID_ELEMENT;
- }
- } else {
- nReturn = SPNEGO_E_ELEMENT_UNAVAILABLE;
- }
+ NULL != pnegResult && SPNEGO_TOKEN_TARG == pSpnegoToken->ucTokenType) {
+
+ // Check if NegResult is available
+ if (pSpnegoToken->aElementArray[SPNEGO_TARG_NEGRESULT_ELEMENT].
+ iElementPresent == SPNEGO_TOKEN_ELEMENT_AVAILABLE) {
+ // Must be 1 byte long and a valid value
+ if (pSpnegoToken->aElementArray[SPNEGO_TARG_NEGRESULT_ELEMENT].
+ nDatalength == SPNEGO_NEGTARG_MAXLEN_NEGRESULT
+ && IsValidNegResult(*pSpnegoToken->
+ aElementArray[SPNEGO_TARG_NEGRESULT_ELEMENT].pbData)) {
+ *pnegResult =
+ *pSpnegoToken->aElementArray[SPNEGO_TARG_NEGRESULT_ELEMENT].
+ pbData;
+ nReturn = SPNEGO_E_SUCCESS;
+ } else {
+ nReturn = SPNEGO_E_INVALID_ELEMENT;
+ }
+ } else {
+ nReturn = SPNEGO_E_ELEMENT_UNAVAILABLE;
+ }
} // IF parameters OK
int
spnegoGetSupportedMechType(SPNEGO_TOKEN_HANDLE hSpnegoToken,
- SPNEGO_MECH_OID * pMechOID)
+ SPNEGO_MECH_OID * pMechOID)
{
int nReturn = SPNEGO_E_INVALID_PARAMETER;
int nCtr = 0L;
// Check parameters
if (IsValidSpnegoToken(pSpnegoToken) &&
- NULL != pMechOID && SPNEGO_TOKEN_TARG == pSpnegoToken->ucTokenType) {
+ NULL != pMechOID && SPNEGO_TOKEN_TARG == pSpnegoToken->ucTokenType) {
- // Check if MechList is available
- if (pSpnegoToken->aElementArray[SPNEGO_TARG_SUPPMECH_ELEMENT].
- iElementPresent == SPNEGO_TOKEN_ELEMENT_AVAILABLE) {
+ // Check if MechList is available
+ if (pSpnegoToken->aElementArray[SPNEGO_TARG_SUPPMECH_ELEMENT].
+ iElementPresent == SPNEGO_TOKEN_ELEMENT_AVAILABLE) {
- for (nCtr = 0;
- nReturn != SPNEGO_E_SUCCESS &&
- g_stcMechOIDList[nCtr].eMechanismOID != spnego_mech_oid_NotUsed;
- nCtr++) {
+ for (nCtr = 0;
+ nReturn != SPNEGO_E_SUCCESS &&
+ g_stcMechOIDList[nCtr].eMechanismOID != spnego_mech_oid_NotUsed;
+ nCtr++) {
- if ((nReturn =
- ASNDerCheckOID(pSpnegoToken->
- aElementArray[SPNEGO_TARG_SUPPMECH_ELEMENT].pbData,
- nCtr,
- pSpnegoToken->
- aElementArray[SPNEGO_TARG_SUPPMECH_ELEMENT].
- nDatalength, &nLength)) == SPNEGO_E_SUCCESS) {
- *pMechOID = nCtr;
- }
+ if ((nReturn =
+ ASNDerCheckOID(pSpnegoToken->
+ aElementArray[SPNEGO_TARG_SUPPMECH_ELEMENT].pbData,
+ nCtr,
+ pSpnegoToken->
+ aElementArray[SPNEGO_TARG_SUPPMECH_ELEMENT].
+ nDatalength, &nLength)) == SPNEGO_E_SUCCESS) {
+ *pMechOID = nCtr;
+ }
- } // For enum MechOIDs
+ } // For enum MechOIDs
- } else {
- nReturn = SPNEGO_E_ELEMENT_UNAVAILABLE;
- }
+ } else {
+ nReturn = SPNEGO_E_ELEMENT_UNAVAILABLE;
+ }
} // IF parameters OK
int
spnegoGetMechToken(SPNEGO_TOKEN_HANDLE hSpnegoToken, unsigned char *pbTokenData,
- unsigned long *pulDataLen)
+ unsigned long *pulDataLen)
{
int nReturn = SPNEGO_E_INVALID_PARAMETER;
SPNEGO_TOKEN *pSpnegoToken = (SPNEGO_TOKEN *) hSpnegoToken;
// Check parameters
if (IsValidSpnegoToken(pSpnegoToken) && NULL != pulDataLen) {
- // Point at the proper Element
- if (SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType) {
- pSpnegoElement =
- &pSpnegoToken->aElementArray[SPNEGO_INIT_MECHTOKEN_ELEMENT];
- } else {
- pSpnegoElement =
- &pSpnegoToken->aElementArray[SPNEGO_TARG_RESPTOKEN_ELEMENT];
- }
-
- // Check if MechType is available
- if (SPNEGO_TOKEN_ELEMENT_AVAILABLE == pSpnegoElement->iElementPresent) {
- // Check for Buffer too small conditions
- if (NULL == pbTokenData ||
- pSpnegoElement->nDatalength > *pulDataLen) {
- *pulDataLen = pSpnegoElement->nDatalength;
- nReturn = SPNEGO_E_BUFFER_TOO_SMALL;
- } else {
- // Copy Memory
- memcpy(pbTokenData, pSpnegoElement->pbData,
- pSpnegoElement->nDatalength);
- *pulDataLen = pSpnegoElement->nDatalength;
- nReturn = SPNEGO_E_SUCCESS;
- }
- } else {
- nReturn = SPNEGO_E_ELEMENT_UNAVAILABLE;
- }
+ // Point at the proper Element
+ if (SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType) {
+ pSpnegoElement =
+ &pSpnegoToken->aElementArray[SPNEGO_INIT_MECHTOKEN_ELEMENT];
+ } else {
+ pSpnegoElement =
+ &pSpnegoToken->aElementArray[SPNEGO_TARG_RESPTOKEN_ELEMENT];
+ }
+
+ // Check if MechType is available
+ if (SPNEGO_TOKEN_ELEMENT_AVAILABLE == pSpnegoElement->iElementPresent) {
+ // Check for Buffer too small conditions
+ if (NULL == pbTokenData ||
+ pSpnegoElement->nDatalength > *pulDataLen) {
+ *pulDataLen = pSpnegoElement->nDatalength;
+ nReturn = SPNEGO_E_BUFFER_TOO_SMALL;
+ } else {
+ // Copy Memory
+ memcpy(pbTokenData, pSpnegoElement->pbData,
+ pSpnegoElement->nDatalength);
+ *pulDataLen = pSpnegoElement->nDatalength;
+ nReturn = SPNEGO_E_SUCCESS;
+ }
+ } else {
+ nReturn = SPNEGO_E_ELEMENT_UNAVAILABLE;
+ }
} // IF parameters OK
int
spnegoGetMechListMIC(SPNEGO_TOKEN_HANDLE hSpnegoToken, unsigned char *pbMICData,
- unsigned long *pulDataLen)
+ unsigned long *pulDataLen)
{
int nReturn = SPNEGO_E_INVALID_PARAMETER;
SPNEGO_TOKEN *pSpnegoToken = (SPNEGO_TOKEN *) hSpnegoToken;
// Check parameters
if (IsValidSpnegoToken(pSpnegoToken) && NULL != pulDataLen) {
- // Point at the proper Element
- if (SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType) {
- pSpnegoElement =
- &pSpnegoToken->aElementArray[SPNEGO_INIT_MECHLISTMIC_ELEMENT];
- } else {
- pSpnegoElement =
- &pSpnegoToken->aElementArray[SPNEGO_TARG_MECHLISTMIC_ELEMENT];
- }
-
- // Check if MechType is available
- if (SPNEGO_TOKEN_ELEMENT_AVAILABLE == pSpnegoElement->iElementPresent) {
- // Check for Buffer too small conditions
- if (NULL == pbMICData || pSpnegoElement->nDatalength > *pulDataLen) {
- *pulDataLen = pSpnegoElement->nDatalength;
- nReturn = SPNEGO_E_BUFFER_TOO_SMALL;
- } else {
- // Copy Memory
- memcpy(pbMICData, pSpnegoElement->pbData,
- pSpnegoElement->nDatalength);
- *pulDataLen = pSpnegoElement->nDatalength;
- nReturn = SPNEGO_E_SUCCESS;
- }
- } else {
- nReturn = SPNEGO_E_ELEMENT_UNAVAILABLE;
- }
+ // Point at the proper Element
+ if (SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType) {
+ pSpnegoElement =
+ &pSpnegoToken->aElementArray[SPNEGO_INIT_MECHLISTMIC_ELEMENT];
+ } else {
+ pSpnegoElement =
+ &pSpnegoToken->aElementArray[SPNEGO_TARG_MECHLISTMIC_ELEMENT];
+ }
+
+ // Check if MechType is available
+ if (SPNEGO_TOKEN_ELEMENT_AVAILABLE == pSpnegoElement->iElementPresent) {
+ // Check for Buffer too small conditions
+ if (NULL == pbMICData || pSpnegoElement->nDatalength > *pulDataLen) {
+ *pulDataLen = pSpnegoElement->nDatalength;
+ nReturn = SPNEGO_E_BUFFER_TOO_SMALL;
+ } else {
+ // Copy Memory
+ memcpy(pbMICData, pSpnegoElement->pbData,
+ pSpnegoElement->nDatalength);
+ *pulDataLen = pSpnegoElement->nDatalength;
+ nReturn = SPNEGO_E_SUCCESS;
+ }
+ } else {
+ nReturn = SPNEGO_E_ELEMENT_UNAVAILABLE;
+ }
} // IF parameters OK
// C++ Specific
#if defined(__cplusplus)
-extern "C"
-{
+extern "C" {
#endif
// Type Definitions
typedef enum spnego_element_type
{
- spnego_element_min, // Lower bound
+ spnego_element_min, // Lower bound
- // Init token elements
- spnego_init_mechtypes,
- spnego_init_reqFlags,
- spnego_init_mechToken,
- spnego_init_mechListMIC,
+ // Init token elements
+ spnego_init_mechtypes,
+ spnego_init_reqFlags,
+ spnego_init_mechToken,
+ spnego_init_mechListMIC,
- // Targ token elements
- spnego_targ_negResult,
- spnego_targ_supportedMech,
- spnego_targ_responseToken,
- spnego_targ_mechListMIC,
+ // Targ token elements
+ spnego_targ_negResult,
+ spnego_targ_supportedMech,
+ spnego_targ_responseToken,
+ spnego_targ_mechListMIC,
- spnego_element_max // Upper bound
+ spnego_element_max // Upper bound
} SPNEGO_ELEMENT_TYPE;
//
typedef enum spnego_mech_oid
{
- // Init token elements
- spnego_mech_oid_Kerberos_V5_Legacy, // Really V5, but OID off by 1 bit
- spnego_mech_oid_Kerberos_V5,
- spnego_mech_oid_Spnego,
- spnego_mech_oid_NotUsed = -1
+ // Init token elements
+ spnego_mech_oid_Kerberos_V5_Legacy, // Really V5, but OID off by 1 bit
+ spnego_mech_oid_Kerberos_V5,
+ spnego_mech_oid_Spnego,
+ spnego_mech_oid_NotUsed = -1
} SPNEGO_MECH_OID;
//
typedef enum spnego_negResult
{
- spnego_negresult_success,
- spnego_negresult_incomplete,
- spnego_negresult_rejected,
- spnego_negresult_NotUsed = -1
+ spnego_negresult_success,
+ spnego_negresult_incomplete,
+ spnego_negresult_rejected,
+ spnego_negresult_NotUsed = -1
} SPNEGO_NEGRESULT;
//
// A Token Element was invalid (e.g. improper length or value)
#define SPNEGO_E_INVALID_ELEMENT -13
-/* Miscelaneous API Functions */
+ /* Miscelaneous API Functions */
// Frees opaque data
void spnegoFreeData(SPNEGO_TOKEN_HANDLE hSpnegoToken);
// Initializes SPNEGO_TOKEN structure from DER encoded binary data
int spnegoInitFromBinary(unsigned char *pbTokenData, unsigned long ulLength,
- SPNEGO_TOKEN_HANDLE * phSpnegoToken);
+ SPNEGO_TOKEN_HANDLE * phSpnegoToken);
// Initializes SPNEGO_TOKEN structure for a NegTokenInit type using the
// supplied parameters
int spnegoCreateNegTokenInit(SPNEGO_MECH_OID MechType,
- unsigned char ucContextFlags, unsigned char *pbMechToken,
- unsigned long ulMechTokenLen, unsigned char *pbMechTokenMIC,
- unsigned long ulMechTokenMIC, SPNEGO_TOKEN_HANDLE * phSpnegoToken);
+ unsigned char ucContextFlags, unsigned char *pbMechToken,
+ unsigned long ulMechTokenLen, unsigned char *pbMechTokenMIC,
+ unsigned long ulMechTokenMIC, SPNEGO_TOKEN_HANDLE * phSpnegoToken);
// Initializes SPNEGO_TOKEN structure for a NegTokenTarg type using the
// supplied parameters
int spnegoCreateNegTokenTarg(SPNEGO_MECH_OID MechType,
- SPNEGO_NEGRESULT spnegoNegResult, unsigned char *pbMechToken,
- unsigned long ulMechTokenLen, unsigned char *pbMechListMIC,
- unsigned long ulMechListMICLen, SPNEGO_TOKEN_HANDLE * phSpnegoToken);
+ SPNEGO_NEGRESULT spnegoNegResult, unsigned char *pbMechToken,
+ unsigned long ulMechTokenLen, unsigned char *pbMechListMIC,
+ unsigned long ulMechListMICLen, SPNEGO_TOKEN_HANDLE * phSpnegoToken);
// Copies binary representation of SPNEGO Data into user supplied buffer
int spnegoTokenGetBinary(SPNEGO_TOKEN_HANDLE hSpnegoToken,
- unsigned char *pbTokenData, unsigned long *pulDataLen);
+ unsigned char *pbTokenData, unsigned long *pulDataLen);
// Returns SPNEGO Token Type
int spnegoGetTokenType(SPNEGO_TOKEN_HANDLE hSpnegoToken, int *piTokenType);
-/* Reading an Init Token */
+ /* Reading an Init Token */
// Returns the Initial Mech Type in the MechList element in the NegInitToken.
int spnegoIsMechTypeAvailable(SPNEGO_TOKEN_HANDLE hSpnegoToken,
- SPNEGO_MECH_OID MechOID, int *piMechTypeIndex);
+ SPNEGO_MECH_OID MechOID, int *piMechTypeIndex);
// Returns the value from the context flags element in the NegInitToken as an unsigned long
int spnegoGetContextFlags(SPNEGO_TOKEN_HANDLE hSpnegoToken,
- unsigned char *pucContextFlags);
+ unsigned char *pucContextFlags);
-/* Reading a Response Token */
+ /* Reading a Response Token */
// Returns the value from the negResult element (Status code of GSS call - 0,1,2)
int spnegoGetNegotiationResult(SPNEGO_TOKEN_HANDLE hSpnegoToken,
- SPNEGO_NEGRESULT * pnegResult);
+ SPNEGO_NEGRESULT * pnegResult);
// Returns the Supported Mech Type from the NegTokenTarg.
int spnegoGetSupportedMechType(SPNEGO_TOKEN_HANDLE hSpnegoToken,
- SPNEGO_MECH_OID * pMechOID);
+ SPNEGO_MECH_OID * pMechOID);
-/* Reading either Token Type */
+ /* Reading either Token Type */
// Returns the actual Mechanism data from the token (this is what is passed into GSS-API functions
int spnegoGetMechToken(SPNEGO_TOKEN_HANDLE hSpnegoToken,
- unsigned char *pbTokenData, unsigned long *pulDataLen);
+ unsigned char *pbTokenData, unsigned long *pulDataLen);
// Returns the Message Integrity BLOB in the token
int spnegoGetMechListMIC(SPNEGO_TOKEN_HANDLE hSpnegoToken,
- unsigned char *pbMICData, unsigned long *pulDataLen);
+ unsigned char *pbMICData, unsigned long *pulDataLen);
// C++ Specific
#if defined(__cplusplus)
int
makeNegTokenTarg(const unsigned char *kerberosToken,
- size_t kerberosTokenLength,
- const unsigned char **negTokenTarg, size_t * negTokenTargLength)
+ size_t kerberosTokenLength,
+ const unsigned char **negTokenTarg, size_t * negTokenTargLength)
{
SPNEGO_TOKEN_HANDLE hSpnegoToken = NULL;
int rc1 = 1;
/* Check arguments. */
if (!kerberosToken || !negTokenTarg || !negTokenTargLength)
- return 10;
+ return 10;
/* Does IIS reply with 1.2.840.48018.1.2.2 or 1.2.840.113554.1.2.2? */
/* IIS does not include a MIC. */
rc2 = spnegoCreateNegTokenTarg(spnego_mech_oid_Kerberos_V5_Legacy,
- spnego_negresult_success,
- (unsigned char *) kerberosToken,
- kerberosTokenLength, NULL, 0, &hSpnegoToken);
+ spnego_negresult_success,
+ (unsigned char *) kerberosToken,
+ kerberosTokenLength, NULL, 0, &hSpnegoToken);
if (rc2 != SPNEGO_E_SUCCESS) {
- rc1 = abs(rc2) + 100;
- goto cleanup;
+ rc1 = abs(rc2) + 100;
+ goto cleanup;
}
/* Get NegTokenTarg length. */
rc2 = spnegoTokenGetBinary(hSpnegoToken,
- NULL, (unsigned long *) negTokenTargLength);
+ NULL, (unsigned long *) negTokenTargLength);
if (rc2 != SPNEGO_E_BUFFER_TOO_SMALL) {
- rc1 = abs(rc2) + 200;
- goto cleanup;
+ rc1 = abs(rc2) + 200;
+ goto cleanup;
}
*negTokenTarg = malloc(*negTokenTargLength);
if (!*negTokenTarg) {
- rc1 = abs(rc2) + 300;
- goto cleanup;
+ rc1 = abs(rc2) + 300;
+ goto cleanup;
}
/* Get NegTokenTarg data. */
rc2 = spnegoTokenGetBinary(hSpnegoToken,
- (unsigned char *) *negTokenTarg, (unsigned long *) negTokenTargLength);
+ (unsigned char *) *negTokenTarg, (unsigned long *) negTokenTargLength);
if (rc2 != SPNEGO_E_SUCCESS) {
- rc1 = abs(rc2) + 400;
- goto error;
+ rc1 = abs(rc2) + 400;
+ goto error;
}
rc1 = 0;
goto cleanup;
- error:
+error:
if (*negTokenTarg) {
- free((unsigned char *) *negTokenTarg);
- *negTokenTarg = NULL;
- *negTokenTargLength = 0;
+ free((unsigned char *) *negTokenTarg);
+ *negTokenTarg = NULL;
+ *negTokenTargLength = 0;
}
- cleanup:
+cleanup:
if (hSpnegoToken)
- spnegoFreeData(hSpnegoToken);
+ spnegoFreeData(hSpnegoToken);
LOG(("makeNegTokenTarg returned %d\n", rc1));
return rc1;
int
parseNegTokenInit(const unsigned char *negTokenInit,
- size_t negTokenInitLength,
- const unsigned char **kerberosToken, size_t * kerberosTokenLength)
+ size_t negTokenInitLength,
+ const unsigned char **kerberosToken, size_t * kerberosTokenLength)
{
SPNEGO_TOKEN_HANDLE hSpnegoToken = NULL;
int pindex = -1;
/* Check arguments. */
if (!negTokenInit || !kerberosToken || !kerberosTokenLength)
- return 10;
+ return 10;
/* Decode SPNEGO token. */
rc2 = spnegoInitFromBinary((unsigned char *) negTokenInit,
- negTokenInitLength, &hSpnegoToken);
+ negTokenInitLength, &hSpnegoToken);
if (rc2 != SPNEGO_E_SUCCESS) {
- rc1 = abs(rc2) + 100;
- goto cleanup;
+ rc1 = abs(rc2) + 100;
+ goto cleanup;
}
/* Check for negTokenInit choice. */
rc2 = spnegoGetTokenType(hSpnegoToken, &tokenType);
if (rc2 != SPNEGO_E_SUCCESS) {
- rc1 = abs(rc2) + 200;
- goto cleanup;
+ rc1 = abs(rc2) + 200;
+ goto cleanup;
}
if (tokenType != SPNEGO_TOKEN_INIT) {
- rc1 = abs(rc2) + 300;
- goto cleanup;
+ rc1 = abs(rc2) + 300;
+ goto cleanup;
}
/*
*/
rc2 = spnegoIsMechTypeAvailable(hSpnegoToken,
- spnego_mech_oid_Kerberos_V5_Legacy, &pindex);
+ spnego_mech_oid_Kerberos_V5_Legacy, &pindex);
if (rc2 != SPNEGO_E_SUCCESS || pindex != 0) {
- rc2 = spnegoIsMechTypeAvailable(hSpnegoToken,
- spnego_mech_oid_Kerberos_V5, &pindex);
+ rc2 = spnegoIsMechTypeAvailable(hSpnegoToken,
+ spnego_mech_oid_Kerberos_V5, &pindex);
- if (rc2 != SPNEGO_E_SUCCESS || pindex != 0) {
- rc1 = abs(rc2) + 400;
- goto cleanup;
- }
+ if (rc2 != SPNEGO_E_SUCCESS || pindex != 0) {
+ rc1 = abs(rc2) + 400;
+ goto cleanup;
+ }
}
/* Check for no reqFlags. */
rc2 = spnegoGetContextFlags(hSpnegoToken, &reqFlags);
if (rc2 == SPNEGO_E_SUCCESS) {
- rc1 = abs(rc2) + 500;
- goto cleanup;
+ rc1 = abs(rc2) + 500;
+ goto cleanup;
}
/* Get mechanism token length. */
rc2 = spnegoGetMechToken(hSpnegoToken,
- NULL, (unsigned long *) kerberosTokenLength);
+ NULL, (unsigned long *) kerberosTokenLength);
if (rc2 != SPNEGO_E_BUFFER_TOO_SMALL) {
- rc1 = abs(rc2) + 600;
- goto cleanup;
+ rc1 = abs(rc2) + 600;
+ goto cleanup;
}
*kerberosToken = malloc(*kerberosTokenLength);
if (!*kerberosToken) {
- rc1 = abs(rc2) + 700;
- goto cleanup;
+ rc1 = abs(rc2) + 700;
+ goto cleanup;
}
/* Get mechanism token data. */
rc2 = spnegoGetMechToken(hSpnegoToken,
- (unsigned char *) *kerberosToken,
- (unsigned long *) kerberosTokenLength);
+ (unsigned char *) *kerberosToken,
+ (unsigned long *) kerberosTokenLength);
if (rc2 != SPNEGO_E_SUCCESS) {
- rc1 = abs(rc2) + 800;
- goto error;
+ rc1 = abs(rc2) + 800;
+ goto error;
}
/* According to Microsoft, IE does not send a MIC. */
goto cleanup;
- error:
+error:
if (*kerberosToken) {
- free((unsigned char *) *kerberosToken);
- *kerberosToken = NULL;
- *kerberosTokenLength = 0;
+ free((unsigned char *) *kerberosToken);
+ *kerberosToken = NULL;
+ *kerberosTokenLength = 0;
}
- cleanup:
+cleanup:
if (hSpnegoToken)
- spnegoFreeData(hSpnegoToken);
+ spnegoFreeData(hSpnegoToken);
LOG(("parseNegTokenInit returned %d\n", rc1));
return rc1;
#define SPNEGOHELP_H
#ifdef __cplusplus
-extern "C"
-{
+extern "C" {
#endif
#include <stddef.h>
-/* -----------------------------------------------------------------------------
- * makeNegTokenTarg makes an RFC 2478 SPNEGO NegTokenTarg (token) from an
- * RFC 1964 Kerberos GSS-API token.
- *
- * If makeNegTokenTarg is successful, call free (*negTokenTarg) to free the
- * memory allocated by parseNegTokenInit.
- *
- * Returns 0 if successful, 1 otherwise.
- * -----------------------------------------------------------------------------
- */
+ /* -----------------------------------------------------------------------------
+ * makeNegTokenTarg makes an RFC 2478 SPNEGO NegTokenTarg (token) from an
+ * RFC 1964 Kerberos GSS-API token.
+ *
+ * If makeNegTokenTarg is successful, call free (*negTokenTarg) to free the
+ * memory allocated by parseNegTokenInit.
+ *
+ * Returns 0 if successful, 1 otherwise.
+ * -----------------------------------------------------------------------------
+ */
int makeNegTokenTarg(const unsigned char *kerberosToken,
- size_t kerberosTokenLength,
- const unsigned char **negTokenTarg, size_t * negTokenTargLength);
-
-/* -----------------------------------------------------------------------------
- * parseNegTokenInit parses an RFC 2478 SPNEGO NegTokenInit (token) to extract
- * an RFC 1964 Kerberos GSS-API token.
- *
- * If the NegTokenInit does cotain a Kerberos GSS-API token, parseNegTokenInit
- * returns an error.
- *
- * If parseNegTokenInit is successful, call free (*kerberosToken) to
- * free the memory allocated by parseNegTokenInit.
- *
- * Returns 0 if successful, 1 otherwise.
- * -----------------------------------------------------------------------------
- */
+ size_t kerberosTokenLength,
+ const unsigned char **negTokenTarg, size_t * negTokenTargLength);
+
+ /* -----------------------------------------------------------------------------
+ * parseNegTokenInit parses an RFC 2478 SPNEGO NegTokenInit (token) to extract
+ * an RFC 1964 Kerberos GSS-API token.
+ *
+ * If the NegTokenInit does cotain a Kerberos GSS-API token, parseNegTokenInit
+ * returns an error.
+ *
+ * If parseNegTokenInit is successful, call free (*kerberosToken) to
+ * free the memory allocated by parseNegTokenInit.
+ *
+ * Returns 0 if successful, 1 otherwise.
+ * -----------------------------------------------------------------------------
+ */
int parseNegTokenInit(const unsigned char *negTokenInit,
- size_t negTokenInitLength,
- const unsigned char **kerberosToken, size_t * kerberosTokenLength);
+ size_t negTokenInitLength,
+ const unsigned char **kerberosToken, size_t * kerberosTokenLength);
#ifdef __cplusplus
}
int
CalculateMinSpnegoInitTokenSize(long nMechTokenLength,
- long nMechListMICLength, SPNEGO_MECH_OID mechOid,
- int nReqFlagsAvailable, long *pnTokenSize, long *pnInternalTokenLength)
+ long nMechListMICLength, SPNEGO_MECH_OID mechOid,
+ int nReqFlagsAvailable, long *pnTokenSize, long *pnInternalTokenLength)
{
int nReturn = SPNEGO_E_INVALID_LENGTH;
// Start with MIC Element
if (nMechListMICLength > 0L) {
- nTempLength = ASNDerCalcElementLength(nMechListMICLength, NULL);
+ nTempLength = ASNDerCalcElementLength(nMechListMICLength, NULL);
- // Check for rollover error
- if (nTempLength < nMechListMICLength) {
- goto xEndTokenInitLength;
- }
+ // Check for rollover error
+ if (nTempLength < nMechListMICLength) {
+ goto xEndTokenInitLength;
+ }
- nTotalLength += nTempLength;
+ nTotalLength += nTempLength;
}
// Next is the MechToken
if (nMechTokenLength > 0L) {
- nTempLength += ASNDerCalcElementLength(nMechTokenLength, NULL);
+ nTempLength += ASNDerCalcElementLength(nMechTokenLength, NULL);
- // Check for rollover error
- if (nTempLength < nTotalLength) {
- goto xEndTokenInitLength;
- }
+ // Check for rollover error
+ if (nTempLength < nTotalLength) {
+ goto xEndTokenInitLength;
+ }
- nTotalLength = nTempLength;
+ nTotalLength = nTempLength;
}
// Next is the ReqFlags
if (nReqFlagsAvailable) {
- nTempLength +=
- ASNDerCalcElementLength(SPNEGO_NEGINIT_MAXLEN_REQFLAGS, NULL);
+ nTempLength +=
+ ASNDerCalcElementLength(SPNEGO_NEGINIT_MAXLEN_REQFLAGS, NULL);
- // Check for rollover error
- if (nTempLength < nTotalLength) {
- goto xEndTokenInitLength;
- }
+ // Check for rollover error
+ if (nTempLength < nTotalLength) {
+ goto xEndTokenInitLength;
+ }
- nTotalLength = nTempLength;
+ nTotalLength = nTempLength;
}
// Next is the MechList - This is REQUIRED
nTempLength += ASNDerCalcMechListLength(mechOid, NULL);
// Check for rollover error
if (nTempLength < nTotalLength) {
- goto xEndTokenInitLength;
+ goto xEndTokenInitLength;
}
nTotalLength = nTempLength;
// Check for rollover error
if (nTempLength < nTotalLength) {
- goto xEndTokenInitLength;
+ goto xEndTokenInitLength;
}
nTotalLength = nTempLength;
// Check for rollover error
if (nTempLength < nTotalLength) {
- goto xEndTokenInitLength;
+ goto xEndTokenInitLength;
}
nTotalLength = nTempLength;
// Check for rollover error
if (nTempLength < nTotalLength) {
- goto xEndTokenInitLength;
+ goto xEndTokenInitLength;
}
nTotalLength = nTempLength;
// Check for rollover error
if (nTempLength < nTotalLength) {
- goto xEndTokenInitLength;
+ goto xEndTokenInitLength;
}
// The internal length doesn't include the number of bytes
// for the initial token
*pnTokenSize = nTotalLength;
nReturn = SPNEGO_E_SUCCESS;
- xEndTokenInitLength:
+xEndTokenInitLength:
LOG(("CalculateMinSpnegoInitTokenSize returned %d\n", nReturn));
return nReturn;
int
CreateSpnegoInitToken(SPNEGO_MECH_OID MechType,
- unsigned char ucContextFlags, unsigned char *pbMechToken,
- unsigned long ulMechTokenLen, unsigned char *pbMechListMIC,
- unsigned long ulMechListMICLen, unsigned char *pbTokenData,
- long nTokenLength, long nInternalTokenLength)
+ unsigned char ucContextFlags, unsigned char *pbMechToken,
+ unsigned long ulMechTokenLen, unsigned char *pbMechListMIC,
+ unsigned long ulMechListMICLen, unsigned char *pbTokenData,
+ long nTokenLength, long nInternalTokenLength)
{
int nReturn = SPNEGO_E_INVALID_LENGTH;
// Start with MIC Element
if (ulMechListMICLen > 0L) {
- nTempLength =
- ASNDerCalcElementLength(ulMechListMICLen, &nInternalLength);
+ nTempLength =
+ ASNDerCalcElementLength(ulMechListMICLen, &nInternalLength);
- // Decrease the pbWriteTokenData, now we know the length and
- // write it out.
+ // Decrease the pbWriteTokenData, now we know the length and
+ // write it out.
- pbWriteTokenData -= nTempLength;
- nTempLength =
- ASNDerWriteElement(pbWriteTokenData,
- SPNEGO_NEGINIT_ELEMENT_MECHLISTMIC, OCTETSTRING, pbMechListMIC,
- ulMechListMICLen);
+ pbWriteTokenData -= nTempLength;
+ nTempLength =
+ ASNDerWriteElement(pbWriteTokenData,
+ SPNEGO_NEGINIT_ELEMENT_MECHLISTMIC, OCTETSTRING, pbMechListMIC,
+ ulMechListMICLen);
- // Adjust Values and sanity check
- nTotalBytesWritten += nTempLength;
- nInternalTokenLength -= nTempLength;
+ // Adjust Values and sanity check
+ nTotalBytesWritten += nTempLength;
+ nInternalTokenLength -= nTempLength;
- if (nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0) {
- goto xEndWriteNegTokenInit;
- }
+ if (nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0) {
+ goto xEndWriteNegTokenInit;
+ }
} // IF MechListMIC is present
// Next is the MechToken
if (ulMechTokenLen > 0L) {
- nTempLength = ASNDerCalcElementLength(ulMechTokenLen, &nInternalLength);
-
- // Decrease the pbWriteTokenData, now we know the length and
- // write it out.
- pbWriteTokenData -= nTempLength;
- nTempLength =
- ASNDerWriteElement(pbWriteTokenData,
- SPNEGO_NEGINIT_ELEMENT_MECHTOKEN, OCTETSTRING, pbMechToken,
- ulMechTokenLen);
- // Adjust Values and sanity check
- nTotalBytesWritten += nTempLength;
- nInternalTokenLength -= nTempLength;
-
- if (nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0) {
- goto xEndWriteNegTokenInit;
- }
+ nTempLength = ASNDerCalcElementLength(ulMechTokenLen, &nInternalLength);
+
+ // Decrease the pbWriteTokenData, now we know the length and
+ // write it out.
+ pbWriteTokenData -= nTempLength;
+ nTempLength =
+ ASNDerWriteElement(pbWriteTokenData,
+ SPNEGO_NEGINIT_ELEMENT_MECHTOKEN, OCTETSTRING, pbMechToken,
+ ulMechTokenLen);
+ // Adjust Values and sanity check
+ nTotalBytesWritten += nTempLength;
+ nInternalTokenLength -= nTempLength;
+
+ if (nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0) {
+ goto xEndWriteNegTokenInit;
+ }
} // IF MechToken Length is present
// Next is the ReqFlags
if (ucContextFlags > 0L) {
- nTempLength =
- ASNDerCalcElementLength(SPNEGO_NEGINIT_MAXLEN_REQFLAGS,
- &nInternalLength);
+ nTempLength =
+ ASNDerCalcElementLength(SPNEGO_NEGINIT_MAXLEN_REQFLAGS,
+ &nInternalLength);
- // We need a byte that indicates how many bits difference between the number
- // of bits used in final octet (we only have one) and the max (8)
+ // We need a byte that indicates how many bits difference between the number
+ // of bits used in final octet (we only have one) and the max (8)
- abTempReqFlags[0] = SPNEGO_NEGINIT_REQFLAGS_BITDIFF;
- abTempReqFlags[1] = ucContextFlags;
+ abTempReqFlags[0] = SPNEGO_NEGINIT_REQFLAGS_BITDIFF;
+ abTempReqFlags[1] = ucContextFlags;
- // Decrease the pbWriteTokenData, now we know the length and
- // write it out.
- pbWriteTokenData -= nTempLength;
- nTempLength =
- ASNDerWriteElement(pbWriteTokenData,
- SPNEGO_NEGINIT_ELEMENT_REQFLAGS, BITSTRING, abTempReqFlags,
- SPNEGO_NEGINIT_MAXLEN_REQFLAGS);
+ // Decrease the pbWriteTokenData, now we know the length and
+ // write it out.
+ pbWriteTokenData -= nTempLength;
+ nTempLength =
+ ASNDerWriteElement(pbWriteTokenData,
+ SPNEGO_NEGINIT_ELEMENT_REQFLAGS, BITSTRING, abTempReqFlags,
+ SPNEGO_NEGINIT_MAXLEN_REQFLAGS);
- // Adjust Values and sanity check
- nTotalBytesWritten += nTempLength;
- nInternalTokenLength -= nTempLength;
+ // Adjust Values and sanity check
+ nTotalBytesWritten += nTempLength;
+ nInternalTokenLength -= nTempLength;
- if (nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0) {
- goto xEndWriteNegTokenInit;
- }
+ if (nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0) {
+ goto xEndWriteNegTokenInit;
+ }
} // IF ContextFlags
nInternalTokenLength -= nTempLength;
if (nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0) {
- goto xEndWriteNegTokenInit;
+ goto xEndWriteNegTokenInit;
}
// The next tokens we're writing out reflect the total number of bytes
// we have actually written out.
// write it out.
pbWriteTokenData -= nTempLength;
nTempLength =
- ASNDerWriteToken(pbWriteTokenData, SPNEGO_CONSTRUCTED_SEQUENCE, NULL,
- nTotalBytesWritten);
+ ASNDerWriteToken(pbWriteTokenData, SPNEGO_CONSTRUCTED_SEQUENCE, NULL,
+ nTotalBytesWritten);
// Adjust Values and sanity check
nTotalBytesWritten += nTempLength;
nInternalTokenLength -= nTempLength;
if (nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0) {
- goto xEndWriteNegTokenInit;
+ goto xEndWriteNegTokenInit;
}
// Neg Init Token Identifier Token
nTempLength = ASNDerCalcTokenLength(nTotalBytesWritten, 0L);
// write it out.
pbWriteTokenData -= nTempLength;
nTempLength =
- ASNDerWriteToken(pbWriteTokenData, SPNEGO_NEGINIT_TOKEN_IDENTIFIER,
- NULL, nTotalBytesWritten);
+ ASNDerWriteToken(pbWriteTokenData, SPNEGO_NEGINIT_TOKEN_IDENTIFIER,
+ NULL, nTotalBytesWritten);
// Adjust Values and sanity check
nTotalBytesWritten += nTempLength;
nInternalTokenLength -= nTempLength;
if (nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0) {
- goto xEndWriteNegTokenInit;
+ goto xEndWriteNegTokenInit;
}
// SPNEGO OID Token
nTempLength = g_stcMechOIDList[spnego_mech_oid_Spnego].iLen;
nInternalTokenLength -= nTempLength;
if (nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0) {
- goto xEndWriteNegTokenInit;
+ goto xEndWriteNegTokenInit;
}
// App Constructed Token
nTempLength = ASNDerCalcTokenLength(nTotalBytesWritten, 0L);
// write it out.
pbWriteTokenData -= nTempLength;
nTempLength =
- ASNDerWriteToken(pbWriteTokenData, SPNEGO_NEGINIT_APP_CONSTRUCT, NULL,
- nTotalBytesWritten);
+ ASNDerWriteToken(pbWriteTokenData, SPNEGO_NEGINIT_APP_CONSTRUCT, NULL,
+ nTotalBytesWritten);
// Adjust Values and sanity check
nTotalBytesWritten += nTempLength;
// number of bytes left to write).
if (nTotalBytesWritten == nTokenLength && nInternalTokenLength == 0 &&
- pbWriteTokenData == pbTokenData) {
- nReturn = SPNEGO_E_SUCCESS;
+ pbWriteTokenData == pbTokenData) {
+ nReturn = SPNEGO_E_SUCCESS;
}
- xEndWriteNegTokenInit:
+xEndWriteNegTokenInit:
LOG(("CreateSpnegoInitToken returned %d\n", nReturn));
return nReturn;
int
CalculateMinSpnegoTargTokenSize(SPNEGO_MECH_OID MechType,
- SPNEGO_NEGRESULT spnegoNegResult, long nMechTokenLen,
- long nMechListMICLen, long *pnTokenSize, long *pnInternalTokenLength)
+ SPNEGO_NEGRESULT spnegoNegResult, long nMechTokenLen,
+ long nMechListMICLen, long *pnTokenSize, long *pnInternalTokenLength)
{
int nReturn = SPNEGO_E_INVALID_LENGTH;
// Start with MIC Element
if (nMechListMICLen > 0L) {
- nTempLength = ASNDerCalcElementLength(nMechListMICLen, NULL);
+ nTempLength = ASNDerCalcElementLength(nMechListMICLen, NULL);
- // Check for rollover error
- if (nTempLength < nMechListMICLen) {
- goto xEndTokenTargLength;
- }
+ // Check for rollover error
+ if (nTempLength < nMechListMICLen) {
+ goto xEndTokenTargLength;
+ }
- nTotalLength += nTempLength;
+ nTotalLength += nTempLength;
}
// Next is the MechToken
if (nMechTokenLen > 0L) {
- nTempLength += ASNDerCalcElementLength(nMechTokenLen, NULL);
+ nTempLength += ASNDerCalcElementLength(nMechTokenLen, NULL);
- // Check for rollover error
- if (nTempLength < nTotalLength) {
- goto xEndTokenTargLength;
- }
+ // Check for rollover error
+ if (nTempLength < nTotalLength) {
+ goto xEndTokenTargLength;
+ }
- nTotalLength = nTempLength;
+ nTotalLength = nTempLength;
}
// Supported MechType
if (spnego_mech_oid_NotUsed != MechType) {
- // Supported MechOID element - we use the token function since
- // we already know the size of the OID token and value
- nTempLength +=
- ASNDerCalcElementLength(g_stcMechOIDList[MechType].iActualDataLen,
- NULL);
+ // Supported MechOID element - we use the token function since
+ // we already know the size of the OID token and value
+ nTempLength +=
+ ASNDerCalcElementLength(g_stcMechOIDList[MechType].iActualDataLen,
+ NULL);
- // Check for rollover error
- if (nTempLength < nTotalLength) {
- goto xEndTokenTargLength;
- }
+ // Check for rollover error
+ if (nTempLength < nTotalLength) {
+ goto xEndTokenTargLength;
+ }
- nTotalLength = nTempLength;
+ nTotalLength = nTempLength;
} // IF MechType is available
// NegResult Element
if (spnego_negresult_NotUsed != spnegoNegResult) {
- nTempLength +=
- ASNDerCalcElementLength(SPNEGO_NEGTARG_MAXLEN_NEGRESULT, NULL);
+ nTempLength +=
+ ASNDerCalcElementLength(SPNEGO_NEGTARG_MAXLEN_NEGRESULT, NULL);
- // Check for rollover error
- if (nTempLength < nTotalLength) {
- goto xEndTokenTargLength;
- }
+ // Check for rollover error
+ if (nTempLength < nTotalLength) {
+ goto xEndTokenTargLength;
+ }
- nTotalLength = nTempLength;
+ nTotalLength = nTempLength;
} // IF negResult is available
// Check for rollover error
if (nTempLength < nTotalLength) {
- goto xEndTokenTargLength;
+ goto xEndTokenTargLength;
}
nTotalLength = nTempLength;
// Check for rollover error
if (nTempLength < nTotalLength) {
- goto xEndTokenTargLength;
+ goto xEndTokenTargLength;
}
// The internal length doesn't include the number of bytes
// for the initial token
*pnTokenSize = nTotalLength;
nReturn = SPNEGO_E_SUCCESS;
- xEndTokenTargLength:
+xEndTokenTargLength:
LOG(("CalculateMinSpnegoTargTokenSize returned %d\n", nReturn));
return nReturn;
int
CreateSpnegoTargToken(SPNEGO_MECH_OID MechType,
- SPNEGO_NEGRESULT eNegResult, unsigned char *pbMechToken,
- unsigned long ulMechTokenLen, unsigned char *pbMechListMIC,
- unsigned long ulMechListMICLen, unsigned char *pbTokenData,
- long nTokenLength, long nInternalTokenLength)
+ SPNEGO_NEGRESULT eNegResult, unsigned char *pbMechToken,
+ unsigned long ulMechTokenLen, unsigned char *pbMechListMIC,
+ unsigned long ulMechListMICLen, unsigned char *pbTokenData,
+ long nTokenLength, long nInternalTokenLength)
{
int nReturn = SPNEGO_E_INVALID_LENGTH;
// Start with MIC Element
if (ulMechListMICLen > 0L) {
- nTempLength =
- ASNDerCalcElementLength(ulMechListMICLen, &nInternalLength);
+ nTempLength =
+ ASNDerCalcElementLength(ulMechListMICLen, &nInternalLength);
- // Decrease the pbWriteTokenData, now we know the length and
- // write it out.
+ // Decrease the pbWriteTokenData, now we know the length and
+ // write it out.
- pbWriteTokenData -= nTempLength;
- nTempLength =
- ASNDerWriteElement(pbWriteTokenData,
- SPNEGO_NEGTARG_ELEMENT_MECHLISTMIC, OCTETSTRING, pbMechListMIC,
- ulMechListMICLen);
+ pbWriteTokenData -= nTempLength;
+ nTempLength =
+ ASNDerWriteElement(pbWriteTokenData,
+ SPNEGO_NEGTARG_ELEMENT_MECHLISTMIC, OCTETSTRING, pbMechListMIC,
+ ulMechListMICLen);
- // Adjust Values and sanity check
- nTotalBytesWritten += nTempLength;
- nInternalTokenLength -= nTempLength;
+ // Adjust Values and sanity check
+ nTotalBytesWritten += nTempLength;
+ nInternalTokenLength -= nTempLength;
- if (nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0) {
- goto xEndWriteNegTokenTarg;
- }
+ if (nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0) {
+ goto xEndWriteNegTokenTarg;
+ }
} // IF MechListMIC is present
// Next is the MechToken
if (ulMechTokenLen > 0L) {
- nTempLength = ASNDerCalcElementLength(ulMechTokenLen, &nInternalLength);
-
- // Decrease the pbWriteTokenData, now we know the length and
- // write it out.
- pbWriteTokenData -= nTempLength;
- nTempLength =
- ASNDerWriteElement(pbWriteTokenData,
- SPNEGO_NEGTARG_ELEMENT_RESPONSETOKEN, OCTETSTRING, pbMechToken,
- ulMechTokenLen);
- // Adjust Values and sanity check
- nTotalBytesWritten += nTempLength;
- nInternalTokenLength -= nTempLength;
-
- if (nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0) {
- goto xEndWriteNegTokenTarg;
- }
+ nTempLength = ASNDerCalcElementLength(ulMechTokenLen, &nInternalLength);
+
+ // Decrease the pbWriteTokenData, now we know the length and
+ // write it out.
+ pbWriteTokenData -= nTempLength;
+ nTempLength =
+ ASNDerWriteElement(pbWriteTokenData,
+ SPNEGO_NEGTARG_ELEMENT_RESPONSETOKEN, OCTETSTRING, pbMechToken,
+ ulMechTokenLen);
+ // Adjust Values and sanity check
+ nTotalBytesWritten += nTempLength;
+ nInternalTokenLength -= nTempLength;
+
+ if (nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0) {
+ goto xEndWriteNegTokenTarg;
+ }
} // IF MechToken Length is present
// Supported Mech Type
if (spnego_mech_oid_NotUsed != MechType) {
- nTempLength =
- ASNDerCalcElementLength(g_stcMechOIDList[MechType].iActualDataLen,
- &nInternalLength);
+ nTempLength =
+ ASNDerCalcElementLength(g_stcMechOIDList[MechType].iActualDataLen,
+ &nInternalLength);
- // Decrease the pbWriteTokenData, now we know the length and
- // write it out.
- pbWriteTokenData -= nTempLength;
- nTempLength =
- ASNDerWriteToken(pbWriteTokenData,
- SPNEGO_NEGTARG_ELEMENT_SUPPORTEDMECH,
- g_stcMechOIDList[MechType].ucOid, g_stcMechOIDList[MechType].iLen);
+ // Decrease the pbWriteTokenData, now we know the length and
+ // write it out.
+ pbWriteTokenData -= nTempLength;
+ nTempLength =
+ ASNDerWriteToken(pbWriteTokenData,
+ SPNEGO_NEGTARG_ELEMENT_SUPPORTEDMECH,
+ g_stcMechOIDList[MechType].ucOid, g_stcMechOIDList[MechType].iLen);
- // Adjust Values and sanity check
- nTotalBytesWritten += nTempLength;
- nInternalTokenLength -= nTempLength;
+ // Adjust Values and sanity check
+ nTotalBytesWritten += nTempLength;
+ nInternalTokenLength -= nTempLength;
- if (nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0) {
- goto xEndWriteNegTokenTarg;
- }
+ if (nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0) {
+ goto xEndWriteNegTokenTarg;
+ }
} // IF MechType is present
// Neg Result
// NegResult Element
if (spnego_negresult_NotUsed != eNegResult) {
- ucTemp = (unsigned char) eNegResult;
+ ucTemp = (unsigned char) eNegResult;
- nTempLength =
- ASNDerCalcElementLength(SPNEGO_NEGTARG_MAXLEN_NEGRESULT,
- &nInternalLength);
+ nTempLength =
+ ASNDerCalcElementLength(SPNEGO_NEGTARG_MAXLEN_NEGRESULT,
+ &nInternalLength);
- // Decrease the pbWriteTokenData, now we know the length and
- // write it out.
- pbWriteTokenData -= nTempLength;
- nTempLength =
- ASNDerWriteElement(pbWriteTokenData,
- SPNEGO_NEGTARG_ELEMENT_NEGRESULT, ENUMERATED, &ucTemp,
- SPNEGO_NEGTARG_MAXLEN_NEGRESULT);
+ // Decrease the pbWriteTokenData, now we know the length and
+ // write it out.
+ pbWriteTokenData -= nTempLength;
+ nTempLength =
+ ASNDerWriteElement(pbWriteTokenData,
+ SPNEGO_NEGTARG_ELEMENT_NEGRESULT, ENUMERATED, &ucTemp,
+ SPNEGO_NEGTARG_MAXLEN_NEGRESULT);
- // Adjust Values and sanity check
- nTotalBytesWritten += nTempLength;
- nInternalTokenLength -= nTempLength;
+ // Adjust Values and sanity check
+ nTotalBytesWritten += nTempLength;
+ nInternalTokenLength -= nTempLength;
- if (nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0) {
- goto xEndWriteNegTokenTarg;
- }
+ if (nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0) {
+ goto xEndWriteNegTokenTarg;
+ }
} // If eNegResult is available
// write it out.
pbWriteTokenData -= nTempLength;
nTempLength =
- ASNDerWriteToken(pbWriteTokenData, SPNEGO_CONSTRUCTED_SEQUENCE, NULL,
- nTotalBytesWritten);
+ ASNDerWriteToken(pbWriteTokenData, SPNEGO_CONSTRUCTED_SEQUENCE, NULL,
+ nTotalBytesWritten);
// Adjust Values and sanity check
nTotalBytesWritten += nTempLength;
nInternalTokenLength -= nTempLength;
if (nTotalBytesWritten > nTokenLength || nInternalTokenLength < 0) {
- goto xEndWriteNegTokenTarg;
+ goto xEndWriteNegTokenTarg;
}
// Neg Targ Token Identifier Token
nTempLength = ASNDerCalcTokenLength(nTotalBytesWritten, 0L);
// write it out.
pbWriteTokenData -= nTempLength;
nTempLength =
- ASNDerWriteToken(pbWriteTokenData, SPNEGO_NEGTARG_TOKEN_IDENTIFIER,
- NULL, nTotalBytesWritten);
+ ASNDerWriteToken(pbWriteTokenData, SPNEGO_NEGTARG_TOKEN_IDENTIFIER,
+ NULL, nTotalBytesWritten);
// Adjust Values and sanity check
nTotalBytesWritten += nTempLength;
// number of bytes left to write).
if (nTotalBytesWritten == nTokenLength && nInternalTokenLength == 0 &&
- pbWriteTokenData == pbTokenData) {
- nReturn = SPNEGO_E_SUCCESS;
+ pbWriteTokenData == pbTokenData) {
+ nReturn = SPNEGO_E_SUCCESS;
}
- xEndWriteNegTokenTarg:
+xEndWriteNegTokenTarg:
LOG(("CreateSpnegoTargToken returned %d\n", nReturn));
return nReturn;
SPNEGO_TOKEN *
AllocEmptySpnegoToken(unsigned char ucCopyData, unsigned long ulFlags,
- unsigned char *pbTokenData, unsigned long ulTokenSize)
+ unsigned char *pbTokenData, unsigned long ulTokenSize)
{
SPNEGO_TOKEN *pSpnegoToken =
- (SPNEGO_TOKEN *) calloc(1, sizeof(SPNEGO_TOKEN));
+ (SPNEGO_TOKEN *) calloc(1, sizeof(SPNEGO_TOKEN));
if (NULL != pSpnegoToken) {
- // Set the token size
- pSpnegoToken->nStructSize = SPNEGO_TOKEN_SIZE;
-
- // Initialize the element array
- InitSpnegoTokenElementArray(pSpnegoToken);
-
- // Assign the flags value
- pSpnegoToken->ulFlags = ulFlags;
-
- //
- // IF ucCopyData is TRUE, we will allocate a buffer and copy data into it.
- // Otherwise, we will just copy the pointer and the length. This is so we
- // can cut out additional allocations for performance reasons
- //
-
- if (SPNEGO_TOKEN_INTERNAL_FLAGS_FREEDATA == ucCopyData) {
- // Alloc the internal buffer. Cleanup on failure.
- pSpnegoToken->pbBinaryData =
- (unsigned char *) calloc(ulTokenSize, sizeof(unsigned char));
-
- if (NULL != pSpnegoToken->pbBinaryData) {
- // We must ALWAYS free this buffer
- pSpnegoToken->ulFlags |= SPNEGO_TOKEN_INTERNAL_FLAGS_FREEDATA;
-
- // Copy the data locally
- memcpy(pSpnegoToken->pbBinaryData, pbTokenData, ulTokenSize);
- pSpnegoToken->ulBinaryDataLen = ulTokenSize;
- } else {
- free(pSpnegoToken);
- pSpnegoToken = NULL;
- }
-
- } // IF ucCopyData
- else {
- // Copy the pointer and the length directly - ulFlags will control whether or not
- // we are allowed to free the value
-
- pSpnegoToken->pbBinaryData = pbTokenData;
- pSpnegoToken->ulBinaryDataLen = ulTokenSize;
- }
+ // Set the token size
+ pSpnegoToken->nStructSize = SPNEGO_TOKEN_SIZE;
+
+ // Initialize the element array
+ InitSpnegoTokenElementArray(pSpnegoToken);
+
+ // Assign the flags value
+ pSpnegoToken->ulFlags = ulFlags;
+
+ //
+ // IF ucCopyData is TRUE, we will allocate a buffer and copy data into it.
+ // Otherwise, we will just copy the pointer and the length. This is so we
+ // can cut out additional allocations for performance reasons
+ //
+
+ if (SPNEGO_TOKEN_INTERNAL_FLAGS_FREEDATA == ucCopyData) {
+ // Alloc the internal buffer. Cleanup on failure.
+ pSpnegoToken->pbBinaryData =
+ (unsigned char *) calloc(ulTokenSize, sizeof(unsigned char));
+
+ if (NULL != pSpnegoToken->pbBinaryData) {
+ // We must ALWAYS free this buffer
+ pSpnegoToken->ulFlags |= SPNEGO_TOKEN_INTERNAL_FLAGS_FREEDATA;
+
+ // Copy the data locally
+ memcpy(pSpnegoToken->pbBinaryData, pbTokenData, ulTokenSize);
+ pSpnegoToken->ulBinaryDataLen = ulTokenSize;
+ } else {
+ free(pSpnegoToken);
+ pSpnegoToken = NULL;
+ }
+
+ } // IF ucCopyData
+ else {
+ // Copy the pointer and the length directly - ulFlags will control whether or not
+ // we are allowed to free the value
+
+ pSpnegoToken->pbBinaryData = pbTokenData;
+ pSpnegoToken->ulBinaryDataLen = ulTokenSize;
+ }
}
{
if (NULL != pSpnegoToken) {
- // Cleanup internal allocation per the flags
- if (pSpnegoToken->ulFlags & SPNEGO_TOKEN_INTERNAL_FLAGS_FREEDATA &&
- NULL != pSpnegoToken->pbBinaryData) {
- free(pSpnegoToken->pbBinaryData);
- pSpnegoToken->pbBinaryData = NULL;
- }
+ // Cleanup internal allocation per the flags
+ if (pSpnegoToken->ulFlags & SPNEGO_TOKEN_INTERNAL_FLAGS_FREEDATA &&
+ NULL != pSpnegoToken->pbBinaryData) {
+ free(pSpnegoToken->pbBinaryData);
+ pSpnegoToken->pbBinaryData = NULL;
+ }
- free(pSpnegoToken);
+ free(pSpnegoToken);
}
}
//
for (nCtr = 0; nCtr < MAX_NUM_TOKEN_ELEMENTS; nCtr++) {
- // Set the element size as well
- pSpnegoToken->aElementArray[nCtr].nStructSize = SPNEGO_ELEMENT_SIZE;
- pSpnegoToken->aElementArray[nCtr].iElementPresent =
- SPNEGO_TOKEN_ELEMENT_UNAVAILABLE;
+ // Set the element size as well
+ pSpnegoToken->aElementArray[nCtr].nStructSize = SPNEGO_ELEMENT_SIZE;
+ pSpnegoToken->aElementArray[nCtr].iElementPresent =
+ SPNEGO_TOKEN_ELEMENT_UNAVAILABLE;
}
}
int
InitSpnegoTokenType(SPNEGO_TOKEN * pSpnegoToken, long *pnTokenLength,
- long *pnRemainingTokenLength, unsigned char **ppbFirstElement)
+ long *pnRemainingTokenLength, unsigned char **ppbFirstElement)
{
int nReturn = SPNEGO_E_INVALID_TOKEN;
long nActualTokenLength = 0L;
//
if (SPNEGO_NEGINIT_APP_CONSTRUCT == *pbTokenData) {
- // Validate the above token - this will tell us the actual length of the token
- // per the encoding (minus the actual token bytes)
- if ((nReturn =
- ASNDerCheckToken(pbTokenData, SPNEGO_NEGINIT_APP_CONSTRUCT, 0L,
- nBoundaryLength, pnTokenLength, &nActualTokenLength))
- == SPNEGO_E_SUCCESS) {
- // Initialize the remaining token length value. This will be used
- // to tell the caller how much token there is left once we've parsed
- // the header (they could calculate it from the other values, but this
- // is a bit friendlier)
- *pnRemainingTokenLength = *pnTokenLength;
-
- // Make adjustments to next token
- pbTokenData += nActualTokenLength;
- nBoundaryLength -= nActualTokenLength;
-
- // The next token should be an OID
- if ((nReturn =
- ASNDerCheckOID(pbTokenData, spnego_mech_oid_Spnego,
- nBoundaryLength,
- &nActualTokenLength)) == SPNEGO_E_SUCCESS) {
- // Make adjustments to next token
- pbTokenData += nActualTokenLength;
- nBoundaryLength -= nActualTokenLength;
- *pnRemainingTokenLength -= nActualTokenLength;
-
- // The next token should specify the NegTokenInit
- if ((nReturn =
- ASNDerCheckToken(pbTokenData,
- SPNEGO_NEGINIT_TOKEN_IDENTIFIER,
- *pnRemainingTokenLength, nBoundaryLength,
- pnTokenLength, &nActualTokenLength))
- == SPNEGO_E_SUCCESS) {
- // Make adjustments to next token
- pbTokenData += nActualTokenLength;
- nBoundaryLength -= nActualTokenLength;
- *pnRemainingTokenLength -= nActualTokenLength;
-
- // The next token should specify the start of a sequence
- if ((nReturn =
- ASNDerCheckToken(pbTokenData,
- SPNEGO_CONSTRUCTED_SEQUENCE,
- *pnRemainingTokenLength, nBoundaryLength,
- pnTokenLength, &nActualTokenLength))
- == SPNEGO_E_SUCCESS) {
- // NegTokenInit header is now checked out!
-
- // Make adjustments to next token
- *pnRemainingTokenLength -= nActualTokenLength;
-
- // Store pointer to first element
- *ppbFirstElement = pbTokenData + nActualTokenLength;
- pSpnegoToken->ucTokenType = SPNEGO_TOKEN_INIT;
- } // IF Check Sequence Token
-
- } // IF Check NegTokenInit token
-
-
- } // IF Check for SPNEGO OID
-
-
- } // IF check app construct token
+ // Validate the above token - this will tell us the actual length of the token
+ // per the encoding (minus the actual token bytes)
+ if ((nReturn =
+ ASNDerCheckToken(pbTokenData, SPNEGO_NEGINIT_APP_CONSTRUCT, 0L,
+ nBoundaryLength, pnTokenLength, &nActualTokenLength))
+ == SPNEGO_E_SUCCESS) {
+ // Initialize the remaining token length value. This will be used
+ // to tell the caller how much token there is left once we've parsed
+ // the header (they could calculate it from the other values, but this
+ // is a bit friendlier)
+ *pnRemainingTokenLength = *pnTokenLength;
+
+ // Make adjustments to next token
+ pbTokenData += nActualTokenLength;
+ nBoundaryLength -= nActualTokenLength;
+
+ // The next token should be an OID
+ if ((nReturn =
+ ASNDerCheckOID(pbTokenData, spnego_mech_oid_Spnego,
+ nBoundaryLength,
+ &nActualTokenLength)) == SPNEGO_E_SUCCESS) {
+ // Make adjustments to next token
+ pbTokenData += nActualTokenLength;
+ nBoundaryLength -= nActualTokenLength;
+ *pnRemainingTokenLength -= nActualTokenLength;
+
+ // The next token should specify the NegTokenInit
+ if ((nReturn =
+ ASNDerCheckToken(pbTokenData,
+ SPNEGO_NEGINIT_TOKEN_IDENTIFIER,
+ *pnRemainingTokenLength, nBoundaryLength,
+ pnTokenLength, &nActualTokenLength))
+ == SPNEGO_E_SUCCESS) {
+ // Make adjustments to next token
+ pbTokenData += nActualTokenLength;
+ nBoundaryLength -= nActualTokenLength;
+ *pnRemainingTokenLength -= nActualTokenLength;
+
+ // The next token should specify the start of a sequence
+ if ((nReturn =
+ ASNDerCheckToken(pbTokenData,
+ SPNEGO_CONSTRUCTED_SEQUENCE,
+ *pnRemainingTokenLength, nBoundaryLength,
+ pnTokenLength, &nActualTokenLength))
+ == SPNEGO_E_SUCCESS) {
+ // NegTokenInit header is now checked out!
+
+ // Make adjustments to next token
+ *pnRemainingTokenLength -= nActualTokenLength;
+
+ // Store pointer to first element
+ *ppbFirstElement = pbTokenData + nActualTokenLength;
+ pSpnegoToken->ucTokenType = SPNEGO_TOKEN_INIT;
+ } // IF Check Sequence Token
+
+ } // IF Check NegTokenInit token
+
+
+ } // IF Check for SPNEGO OID
+
+
+ } // IF check app construct token
} else if (SPNEGO_NEGTARG_TOKEN_IDENTIFIER == *pbTokenData) {
- // The next token should specify the NegTokenInit
- if ((nReturn =
- ASNDerCheckToken(pbTokenData, SPNEGO_NEGTARG_TOKEN_IDENTIFIER,
- *pnRemainingTokenLength, nBoundaryLength, pnTokenLength,
- &nActualTokenLength))
- == SPNEGO_E_SUCCESS) {
- // Initialize the remaining token length value. This will be used
- // to tell the caller how much token there is left once we've parsed
- // the header (they could calculate it from the other values, but this
- // is a bit friendlier)
- *pnRemainingTokenLength = *pnTokenLength;
-
- // Make adjustments to next token
- pbTokenData += nActualTokenLength;
- nBoundaryLength -= nActualTokenLength;
-
- // The next token should specify the start of a sequence
- if ((nReturn =
- ASNDerCheckToken(pbTokenData, SPNEGO_CONSTRUCTED_SEQUENCE,
- *pnRemainingTokenLength, nBoundaryLength, pnTokenLength,
- &nActualTokenLength))
- == SPNEGO_E_SUCCESS) {
- // NegTokenInit header is now checked out!
-
- // Make adjustments to next token
- *pnRemainingTokenLength -= nActualTokenLength;
-
- // Store pointer to first element
- *ppbFirstElement = pbTokenData + nActualTokenLength;
- pSpnegoToken->ucTokenType = SPNEGO_TOKEN_TARG;
- } // IF Check Sequence Token
-
- } // IF Check NegTokenInit token
+ // The next token should specify the NegTokenInit
+ if ((nReturn =
+ ASNDerCheckToken(pbTokenData, SPNEGO_NEGTARG_TOKEN_IDENTIFIER,
+ *pnRemainingTokenLength, nBoundaryLength, pnTokenLength,
+ &nActualTokenLength))
+ == SPNEGO_E_SUCCESS) {
+ // Initialize the remaining token length value. This will be used
+ // to tell the caller how much token there is left once we've parsed
+ // the header (they could calculate it from the other values, but this
+ // is a bit friendlier)
+ *pnRemainingTokenLength = *pnTokenLength;
+
+ // Make adjustments to next token
+ pbTokenData += nActualTokenLength;
+ nBoundaryLength -= nActualTokenLength;
+
+ // The next token should specify the start of a sequence
+ if ((nReturn =
+ ASNDerCheckToken(pbTokenData, SPNEGO_CONSTRUCTED_SEQUENCE,
+ *pnRemainingTokenLength, nBoundaryLength, pnTokenLength,
+ &nActualTokenLength))
+ == SPNEGO_E_SUCCESS) {
+ // NegTokenInit header is now checked out!
+
+ // Make adjustments to next token
+ *pnRemainingTokenLength -= nActualTokenLength;
+
+ // Store pointer to first element
+ *ppbFirstElement = pbTokenData + nActualTokenLength;
+ pSpnegoToken->ucTokenType = SPNEGO_TOKEN_TARG;
+ } // IF Check Sequence Token
+
+ } // IF Check NegTokenInit token
} // ELSE IF it's a NegTokenTarg
int
GetSpnegoInitTokenMechList(unsigned char *pbTokenData, int nMechListLength,
- SPNEGO_ELEMENT * pSpnegoElement)
+ SPNEGO_ELEMENT * pSpnegoElement)
{
int nReturn = SPNEGO_E_INVALID_TOKEN;
long nLength = 0L;
// Actual MechList is prepended by a Constructed Sequence Token
if ((nReturn = ASNDerCheckToken(pbTokenData, SPNEGO_CONSTRUCTED_SEQUENCE,
- nMechListLength, nMechListLength,
- &nLength, &nActualTokenLength))
- == SPNEGO_E_SUCCESS) {
- // Adjust for this token
- nMechListLength -= nActualTokenLength;
- pbTokenData += nActualTokenLength;
-
- // Perform simple validation of the actual MechList (i.e. ensure that
- // the OIDs in the MechList are reasonable).
-
- if ((nReturn =
- ValidateMechList(pbTokenData, nLength)) == SPNEGO_E_SUCCESS) {
- // Initialize the element now
- pSpnegoElement->eElementType = spnego_init_mechtypes;
- pSpnegoElement->iElementPresent = SPNEGO_TOKEN_ELEMENT_AVAILABLE;
- pSpnegoElement->type = SPNEGO_MECHLIST_TYPE;
- pSpnegoElement->nDatalength = nLength;
- pSpnegoElement->pbData = pbTokenData;
- }
+ nMechListLength, nMechListLength,
+ &nLength, &nActualTokenLength))
+ == SPNEGO_E_SUCCESS) {
+ // Adjust for this token
+ nMechListLength -= nActualTokenLength;
+ pbTokenData += nActualTokenLength;
+
+ // Perform simple validation of the actual MechList (i.e. ensure that
+ // the OIDs in the MechList are reasonable).
+
+ if ((nReturn =
+ ValidateMechList(pbTokenData, nLength)) == SPNEGO_E_SUCCESS) {
+ // Initialize the element now
+ pSpnegoElement->eElementType = spnego_init_mechtypes;
+ pSpnegoElement->iElementPresent = SPNEGO_TOKEN_ELEMENT_AVAILABLE;
+ pSpnegoElement->type = SPNEGO_MECHLIST_TYPE;
+ pSpnegoElement->nDatalength = nLength;
+ pSpnegoElement->pbData = pbTokenData;
+ }
} // IF Check Token
//
// Comments :
// Checks that pbTokenData is pointing at the specified DER type. If so,
-// then we verify that lengths are proper and then fill out the
+// then we verify that lengths are proper and then fill out the
// SPNEGO_ELEMENT data structure.
//
////////////////////////////////////////////////////////////////////////////
int
InitSpnegoTokenElementFromBasicType(unsigned char *pbTokenData,
- int nElementLength, unsigned char ucExpectedType,
- SPNEGO_ELEMENT_TYPE spnegoElementType, SPNEGO_ELEMENT * pSpnegoElement)
+ int nElementLength, unsigned char ucExpectedType,
+ SPNEGO_ELEMENT_TYPE spnegoElementType, SPNEGO_ELEMENT * pSpnegoElement)
{
int nReturn = SPNEGO_E_UNEXPECTED_TYPE;
long nLength = 0L;
// The type BYTE must match our token data or something is badly wrong
if (*pbTokenData == ucExpectedType) {
- // Check that we are pointing at the specified type
- if ((nReturn = ASNDerCheckToken(pbTokenData, ucExpectedType,
- nElementLength, nElementLength,
- &nLength, &nActualTokenLength))
- == SPNEGO_E_SUCCESS) {
- // Adjust for this token
- nElementLength -= nActualTokenLength;
- pbTokenData += nActualTokenLength;
-
- // Initialize the element now
- pSpnegoElement->eElementType = spnegoElementType;
- pSpnegoElement->iElementPresent = SPNEGO_TOKEN_ELEMENT_AVAILABLE;
- pSpnegoElement->type = ucExpectedType;
- pSpnegoElement->nDatalength = nLength;
- pSpnegoElement->pbData = pbTokenData;
- }
+ // Check that we are pointing at the specified type
+ if ((nReturn = ASNDerCheckToken(pbTokenData, ucExpectedType,
+ nElementLength, nElementLength,
+ &nLength, &nActualTokenLength))
+ == SPNEGO_E_SUCCESS) {
+ // Adjust for this token
+ nElementLength -= nActualTokenLength;
+ pbTokenData += nActualTokenLength;
+
+ // Initialize the element now
+ pSpnegoElement->eElementType = spnegoElementType;
+ pSpnegoElement->iElementPresent = SPNEGO_TOKEN_ELEMENT_AVAILABLE;
+ pSpnegoElement->type = ucExpectedType;
+ pSpnegoElement->nDatalength = nLength;
+ pSpnegoElement->pbData = pbTokenData;
+ }
} // IF type makes sense
int
InitSpnegoTokenElementFromOID(unsigned char *pbTokenData, int nElementLength,
- SPNEGO_ELEMENT_TYPE spnegoElementType, SPNEGO_ELEMENT * pSpnegoElement)
+ SPNEGO_ELEMENT_TYPE spnegoElementType, SPNEGO_ELEMENT * pSpnegoElement)
{
int nReturn = SPNEGO_E_UNEXPECTED_TYPE;
long nLength = 0L;
// The type BYTE must match our token data or something is badly wrong
if (*pbTokenData == OID) {
- // Check that we are pointing at an OID type
- if ((nReturn = ASNDerCheckToken(pbTokenData, OID,
- nElementLength, nElementLength,
- &nLength, &nActualTokenLength))
- == SPNEGO_E_SUCCESS) {
- // Don't adjust any values for this function
-
- // Initialize the element now
- pSpnegoElement->eElementType = spnegoElementType;
- pSpnegoElement->iElementPresent = SPNEGO_TOKEN_ELEMENT_AVAILABLE;
- pSpnegoElement->type = OID;
- pSpnegoElement->nDatalength = nElementLength;
- pSpnegoElement->pbData = pbTokenData;
- }
+ // Check that we are pointing at an OID type
+ if ((nReturn = ASNDerCheckToken(pbTokenData, OID,
+ nElementLength, nElementLength,
+ &nLength, &nActualTokenLength))
+ == SPNEGO_E_SUCCESS) {
+ // Don't adjust any values for this function
+
+ // Initialize the element now
+ pSpnegoElement->eElementType = spnegoElementType;
+ pSpnegoElement->iElementPresent = SPNEGO_TOKEN_ELEMENT_AVAILABLE;
+ pSpnegoElement->type = OID;
+ pSpnegoElement->nDatalength = nElementLength;
+ pSpnegoElement->pbData = pbTokenData;
+ }
} // IF type makes sense
int
InitSpnegoTokenElements(SPNEGO_TOKEN * pSpnegoToken, unsigned char *pbTokenData,
- long nRemainingTokenLength)
+ long nRemainingTokenLength)
{
//
// The following arrays contain the token identifiers for the elements
// no defaults.
//
- static unsigned char abNegTokenInitElements[] =
- { SPNEGO_NEGINIT_ELEMENT_MECHTYPES, SPNEGO_NEGINIT_ELEMENT_REQFLAGS,
- SPNEGO_NEGINIT_ELEMENT_MECHTOKEN, SPNEGO_NEGINIT_ELEMENT_MECHLISTMIC
- };
+ static unsigned char abNegTokenInitElements[] = { SPNEGO_NEGINIT_ELEMENT_MECHTYPES, SPNEGO_NEGINIT_ELEMENT_REQFLAGS,
+ SPNEGO_NEGINIT_ELEMENT_MECHTOKEN, SPNEGO_NEGINIT_ELEMENT_MECHLISTMIC
+ };
- static unsigned char abNegTokenTargElements[] =
- { SPNEGO_NEGTARG_ELEMENT_NEGRESULT,
- SPNEGO_NEGTARG_ELEMENT_SUPPORTEDMECH,
- SPNEGO_NEGTARG_ELEMENT_RESPONSETOKEN, SPNEGO_NEGTARG_ELEMENT_MECHLISTMIC
- };
+ static unsigned char abNegTokenTargElements[] = { SPNEGO_NEGTARG_ELEMENT_NEGRESULT,
+ SPNEGO_NEGTARG_ELEMENT_SUPPORTEDMECH,
+ SPNEGO_NEGTARG_ELEMENT_RESPONSETOKEN, SPNEGO_NEGTARG_ELEMENT_MECHLISTMIC
+ };
int nReturn = SPNEGO_E_SUCCESS;
int nCtr = 0L;
// Point to the correct array
switch (pSpnegoToken->ucTokenType) {
- case SPNEGO_TOKEN_INIT:
- {
- pbElements = abNegTokenInitElements;
- }
- break;
-
- case SPNEGO_TOKEN_TARG:
- {
- pbElements = abNegTokenTargElements;
- }
- break;
+ case SPNEGO_TOKEN_INIT: {
+ pbElements = abNegTokenInitElements;
+ }
+ break;
+
+ case SPNEGO_TOKEN_TARG: {
+ pbElements = abNegTokenTargElements;
+ }
+ break;
} // SWITCH tokentype
//
for (nCtr = 0L;
- SPNEGO_E_SUCCESS == nReturn &&
- nCtr < MAX_NUM_TOKEN_ELEMENTS && nRemainingTokenLength > 0L; nCtr++) {
-
- // Check if the token exists
- if ((nReturn = ASNDerCheckToken(pbTokenData, pbElements[nCtr],
- 0L, nRemainingTokenLength,
- &nElementLength, &nActualTokenLength))
- == SPNEGO_E_SUCCESS) {
-
- // Token data should skip over the sequence token and then
- // call the appropriate function to initialize the element
- pbTokenData += nActualTokenLength;
-
- // Lengths in the elements should NOT go beyond the element
- // length
-
- // Different tokens mean different elements
- if (SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType) {
-
- // Handle each element as appropriate
- switch (pbElements[nCtr]) {
-
- case SPNEGO_NEGINIT_ELEMENT_MECHTYPES:
- {
- //
- // This is a Mech List that specifies which OIDs the
- // originator of the Init Token supports.
- //
-
- nReturn =
- GetSpnegoInitTokenMechList(pbTokenData,
- nElementLength, &pSpnegoToken->aElementArray[nCtr]);
-
- }
- break;
-
- case SPNEGO_NEGINIT_ELEMENT_REQFLAGS:
- {
- //
- // This is a BITSTRING which specifies the flags that the receiver
- // pass to the gss_accept_sec_context() function.
- //
-
- nReturn =
- InitSpnegoTokenElementFromBasicType(pbTokenData,
- nElementLength, BITSTRING, spnego_init_reqFlags,
- &pSpnegoToken->aElementArray[nCtr]);
- }
- break;
-
- case SPNEGO_NEGINIT_ELEMENT_MECHTOKEN:
- {
- //
- // This is an OCTETSTRING which contains a GSSAPI token corresponding
- // to the first OID in the MechList.
- //
-
- nReturn =
- InitSpnegoTokenElementFromBasicType(pbTokenData,
- nElementLength, OCTETSTRING, spnego_init_mechToken,
- &pSpnegoToken->aElementArray[nCtr]);
- }
- break;
-
- case SPNEGO_NEGINIT_ELEMENT_MECHLISTMIC:
- {
- //
- // This is an OCTETSTRING which contains a message integrity BLOB.
- //
-
- nReturn =
- InitSpnegoTokenElementFromBasicType(pbTokenData,
- nElementLength, OCTETSTRING,
- spnego_init_mechListMIC,
- &pSpnegoToken->aElementArray[nCtr]);
- }
- break;
-
- } // SWITCH Element
- } else {
-
- switch (pbElements[nCtr]) {
-
- case SPNEGO_NEGTARG_ELEMENT_NEGRESULT:
- {
- //
- // This is an ENUMERATION which specifies result of the last GSS
- // token negotiation call.
- //
-
- nReturn =
- InitSpnegoTokenElementFromBasicType(pbTokenData,
- nElementLength, ENUMERATED, spnego_targ_negResult,
- &pSpnegoToken->aElementArray[nCtr]);
- }
- break;
-
- case SPNEGO_NEGTARG_ELEMENT_SUPPORTEDMECH:
- {
- //
- // This is an OID which specifies a supported mechanism.
- //
-
- nReturn =
- InitSpnegoTokenElementFromOID(pbTokenData,
- nElementLength, spnego_targ_mechListMIC,
- &pSpnegoToken->aElementArray[nCtr]);
- }
- break;
-
- case SPNEGO_NEGTARG_ELEMENT_RESPONSETOKEN:
- {
- //
- // This is an OCTETSTRING which specifies results of the last GSS
- // token negotiation call.
- //
-
- nReturn =
- InitSpnegoTokenElementFromBasicType(pbTokenData,
- nElementLength, OCTETSTRING,
- spnego_targ_responseToken,
- &pSpnegoToken->aElementArray[nCtr]);
- }
- break;
-
- case SPNEGO_NEGTARG_ELEMENT_MECHLISTMIC:
- {
- //
- // This is an OCTETSTRING which specifies a message integrity BLOB.
- //
-
- nReturn =
- InitSpnegoTokenElementFromBasicType(pbTokenData,
- nElementLength, OCTETSTRING,
- spnego_targ_mechListMIC,
- &pSpnegoToken->aElementArray[nCtr]);
- }
- break;
-
- } // SWITCH Element
-
- } // ELSE !NegTokenInit
-
- // Account for the entire token and following data
- nRemainingTokenLength -= (nActualTokenLength + nElementLength);
-
- // Token data should skip past the element length now
- pbTokenData += nElementLength;
-
- } // IF Token found
- else if (SPNEGO_E_TOKEN_NOT_FOUND == nReturn) {
- // For now, this is a benign error (remember, all elements are optional, so
- // if we don't find one, it's okay).
-
- nReturn = SPNEGO_E_SUCCESS;
- }
+ SPNEGO_E_SUCCESS == nReturn &&
+ nCtr < MAX_NUM_TOKEN_ELEMENTS && nRemainingTokenLength > 0L; nCtr++) {
+
+ // Check if the token exists
+ if ((nReturn = ASNDerCheckToken(pbTokenData, pbElements[nCtr],
+ 0L, nRemainingTokenLength,
+ &nElementLength, &nActualTokenLength))
+ == SPNEGO_E_SUCCESS) {
+
+ // Token data should skip over the sequence token and then
+ // call the appropriate function to initialize the element
+ pbTokenData += nActualTokenLength;
+
+ // Lengths in the elements should NOT go beyond the element
+ // length
+
+ // Different tokens mean different elements
+ if (SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType) {
+
+ // Handle each element as appropriate
+ switch (pbElements[nCtr]) {
+
+ case SPNEGO_NEGINIT_ELEMENT_MECHTYPES: {
+ //
+ // This is a Mech List that specifies which OIDs the
+ // originator of the Init Token supports.
+ //
+
+ nReturn =
+ GetSpnegoInitTokenMechList(pbTokenData,
+ nElementLength, &pSpnegoToken->aElementArray[nCtr]);
+
+ }
+ break;
+
+ case SPNEGO_NEGINIT_ELEMENT_REQFLAGS: {
+ //
+ // This is a BITSTRING which specifies the flags that the receiver
+ // pass to the gss_accept_sec_context() function.
+ //
+
+ nReturn =
+ InitSpnegoTokenElementFromBasicType(pbTokenData,
+ nElementLength, BITSTRING, spnego_init_reqFlags,
+ &pSpnegoToken->aElementArray[nCtr]);
+ }
+ break;
+
+ case SPNEGO_NEGINIT_ELEMENT_MECHTOKEN: {
+ //
+ // This is an OCTETSTRING which contains a GSSAPI token corresponding
+ // to the first OID in the MechList.
+ //
+
+ nReturn =
+ InitSpnegoTokenElementFromBasicType(pbTokenData,
+ nElementLength, OCTETSTRING, spnego_init_mechToken,
+ &pSpnegoToken->aElementArray[nCtr]);
+ }
+ break;
+
+ case SPNEGO_NEGINIT_ELEMENT_MECHLISTMIC: {
+ //
+ // This is an OCTETSTRING which contains a message integrity BLOB.
+ //
+
+ nReturn =
+ InitSpnegoTokenElementFromBasicType(pbTokenData,
+ nElementLength, OCTETSTRING,
+ spnego_init_mechListMIC,
+ &pSpnegoToken->aElementArray[nCtr]);
+ }
+ break;
+
+ } // SWITCH Element
+ } else {
+
+ switch (pbElements[nCtr]) {
+
+ case SPNEGO_NEGTARG_ELEMENT_NEGRESULT: {
+ //
+ // This is an ENUMERATION which specifies result of the last GSS
+ // token negotiation call.
+ //
+
+ nReturn =
+ InitSpnegoTokenElementFromBasicType(pbTokenData,
+ nElementLength, ENUMERATED, spnego_targ_negResult,
+ &pSpnegoToken->aElementArray[nCtr]);
+ }
+ break;
+
+ case SPNEGO_NEGTARG_ELEMENT_SUPPORTEDMECH: {
+ //
+ // This is an OID which specifies a supported mechanism.
+ //
+
+ nReturn =
+ InitSpnegoTokenElementFromOID(pbTokenData,
+ nElementLength, spnego_targ_mechListMIC,
+ &pSpnegoToken->aElementArray[nCtr]);
+ }
+ break;
+
+ case SPNEGO_NEGTARG_ELEMENT_RESPONSETOKEN: {
+ //
+ // This is an OCTETSTRING which specifies results of the last GSS
+ // token negotiation call.
+ //
+
+ nReturn =
+ InitSpnegoTokenElementFromBasicType(pbTokenData,
+ nElementLength, OCTETSTRING,
+ spnego_targ_responseToken,
+ &pSpnegoToken->aElementArray[nCtr]);
+ }
+ break;
+
+ case SPNEGO_NEGTARG_ELEMENT_MECHLISTMIC: {
+ //
+ // This is an OCTETSTRING which specifies a message integrity BLOB.
+ //
+
+ nReturn =
+ InitSpnegoTokenElementFromBasicType(pbTokenData,
+ nElementLength, OCTETSTRING,
+ spnego_targ_mechListMIC,
+ &pSpnegoToken->aElementArray[nCtr]);
+ }
+ break;
+
+ } // SWITCH Element
+
+ } // ELSE !NegTokenInit
+
+ // Account for the entire token and following data
+ nRemainingTokenLength -= (nActualTokenLength + nElementLength);
+
+ // Token data should skip past the element length now
+ pbTokenData += nElementLength;
+
+ } // IF Token found
+ else if (SPNEGO_E_TOKEN_NOT_FOUND == nReturn) {
+ // For now, this is a benign error (remember, all elements are optional, so
+ // if we don't find one, it's okay).
+
+ nReturn = SPNEGO_E_SUCCESS;
+ }
} // FOR enum elements
//
if (SPNEGO_E_SUCCESS == nReturn && nRemainingTokenLength != 0L) {
- nReturn = SPNEGO_E_INVALID_TOKEN;
+ nReturn = SPNEGO_E_INVALID_TOKEN;
}
LOG(("InitSpnegoTokenElements returned %d\n", nReturn));
int
FindMechOIDInMechList(SPNEGO_ELEMENT * pSpnegoElement, SPNEGO_MECH_OID MechOID,
- int *piMechTypeIndex)
+ int *piMechTypeIndex)
{
int nReturn = SPNEGO_E_NOT_FOUND;
int nCtr = 0;
while (SPNEGO_E_SUCCESS != nReturn && nBoundaryLength > 0L) {
- // Use the helper function to check the OID
- if ((nReturn =
- ASNDerCheckOID(pbMechListData, MechOID, nBoundaryLength,
- &nLength))
- == SPNEGO_E_SUCCESS) {
- *piMechTypeIndex = nCtr;
- }
- // Adjust for the current OID
- pbMechListData += nLength;
- nBoundaryLength -= nLength;
- nCtr++;
+ // Use the helper function to check the OID
+ if ((nReturn =
+ ASNDerCheckOID(pbMechListData, MechOID, nBoundaryLength,
+ &nLength))
+ == SPNEGO_E_SUCCESS) {
+ *piMechTypeIndex = nCtr;
+ }
+ // Adjust for the current OID
+ pbMechListData += nLength;
+ nBoundaryLength -= nLength;
+ nCtr++;
} // WHILE enuming OIDs
long nTokenLength = 0L;
while (SPNEGO_E_SUCCESS == nReturn && nBoundaryLength > 0L) {
- // Verify that we have something that at least *looks* like an OID - in other
- // words it has an OID identifier and specifies a length that doesn't go beyond
- // the size of the list.
- nReturn = ASNDerCheckToken(pbMechListData, OID, 0L, nBoundaryLength,
- &nLength, &nTokenLength);
+ // Verify that we have something that at least *looks* like an OID - in other
+ // words it has an OID identifier and specifies a length that doesn't go beyond
+ // the size of the list.
+ nReturn = ASNDerCheckToken(pbMechListData, OID, 0L, nBoundaryLength,
+ &nLength, &nTokenLength);
- // Adjust for the current OID
- pbMechListData += (nLength + nTokenLength);
- nBoundaryLength -= (nLength + nTokenLength);
+ // Adjust for the current OID
+ pbMechListData += (nLength + nTokenLength);
+ nBoundaryLength -= (nLength + nTokenLength);
} // WHILE enuming OIDs
IsValidMechOid(SPNEGO_MECH_OID mechOid)
{
LOG(("IsValidMechOid returned %d\n",
- mechOid >= spnego_mech_oid_Kerberos_V5_Legacy
- && mechOid <= spnego_mech_oid_Spnego));
+ mechOid >= spnego_mech_oid_Kerberos_V5_Legacy
+ && mechOid <= spnego_mech_oid_Spnego));
return (mechOid >= spnego_mech_oid_Kerberos_V5_Legacy
- && mechOid <= spnego_mech_oid_Spnego);
+ && mechOid <= spnego_mech_oid_Spnego);
}
/////////////////////////////////////////////////////////////////////////////
// Mask out our valid bits. If there is anything leftover, this
// is not a valid value for Context Flags
LOG(("IsValidContextFlags returned %d\n",
- ((ucContextFlags & ~SPNEGO_NEGINIT_CONTEXT_MASK) == 0)));
+ ((ucContextFlags & ~SPNEGO_NEGINIT_CONTEXT_MASK) == 0)));
return ((ucContextFlags & ~SPNEGO_NEGINIT_CONTEXT_MASK) == 0);
}
IsValidNegResult(SPNEGO_NEGRESULT negResult)
{
LOG(("IsValidNegResult returned %d\n", negResult >= spnego_negresult_success
- && negResult <= spnego_negresult_rejected));
+ && negResult <= spnego_negresult_rejected));
return (negResult >= spnego_negresult_success
- && negResult <= spnego_negresult_rejected);
+ && negResult <= spnego_negresult_rejected);
}
/////////////////////////////////////////////////////////////////////////////
// Parameter should be non-NULL
if (NULL != pSpnegoToken) {
- // Length should be at least the size defined in the header
- if (pSpnegoToken->nStructSize >= SPNEGO_TOKEN_SIZE) {
- // Number of elements should be >= our maximum - if it's greater, that's
- // okay, since we'll only be accessing the elements up to MAX_NUM_TOKEN_ELEMENTS
- if (pSpnegoToken->nNumElements >= MAX_NUM_TOKEN_ELEMENTS) {
- // Check for proper token type
- if (SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType ||
- SPNEGO_TOKEN_TARG == pSpnegoToken->ucTokenType) {
- nReturn = 1;
- }
- }
-
- } // IF struct size makes sense
+ // Length should be at least the size defined in the header
+ if (pSpnegoToken->nStructSize >= SPNEGO_TOKEN_SIZE) {
+ // Number of elements should be >= our maximum - if it's greater, that's
+ // okay, since we'll only be accessing the elements up to MAX_NUM_TOKEN_ELEMENTS
+ if (pSpnegoToken->nNumElements >= MAX_NUM_TOKEN_ELEMENTS) {
+ // Check for proper token type
+ if (SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType ||
+ SPNEGO_TOKEN_TARG == pSpnegoToken->ucTokenType) {
+ nReturn = 1;
+ }
+ }
+
+ } // IF struct size makes sense
} // IF non-NULL spnego Token
int
IsValidSpnegoElement(SPNEGO_TOKEN * pSpnegoToken,
- SPNEGO_ELEMENT_TYPE spnegoElement)
+ SPNEGO_ELEMENT_TYPE spnegoElement)
{
int nReturn = 0;
// Check boundaries
if (spnegoElement > spnego_element_min &&
- spnegoElement < spnego_element_max) {
+ spnegoElement < spnego_element_max) {
- // Check for appropriateness to token type
- if (SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType) {
- nReturn = (spnegoElement >= spnego_init_mechtypes &&
- spnegoElement <= spnego_init_mechListMIC);
- } else {
- nReturn = (spnegoElement >= spnego_targ_negResult &&
- spnegoElement <= spnego_targ_mechListMIC);
- }
+ // Check for appropriateness to token type
+ if (SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType) {
+ nReturn = (spnegoElement >= spnego_init_mechtypes &&
+ spnegoElement <= spnego_init_mechListMIC);
+ } else {
+ nReturn = (spnegoElement >= spnego_targ_negResult &&
+ spnegoElement <= spnego_targ_mechListMIC);
+ }
} // IF boundary conditions are met
int
CalculateElementArrayIndex(SPNEGO_TOKEN * pSpnegoToken,
- SPNEGO_ELEMENT_TYPE spnegoElement)
+ SPNEGO_ELEMENT_TYPE spnegoElement)
{
int nReturn = 0;
// (these differ based on ucTokenType)
if (SPNEGO_TOKEN_INIT == pSpnegoToken->ucTokenType) {
- nReturn = spnegoElement - spnego_init_mechtypes;
+ nReturn = spnegoElement - spnego_init_mechtypes;
} else {
- nReturn = spnegoElement - spnego_targ_negResult;
+ nReturn = spnegoElement - spnego_targ_negResult;
}
LOG(("CalculateElementArrayIndex returned %d\n", nReturn));
// Initializes SPNEGO_TOKEN structure from DER encoded binary data
int
InitTokenFromBinary(unsigned char ucCopyData, unsigned long ulFlags,
- unsigned char *pbTokenData, unsigned long ulLength,
- SPNEGO_TOKEN ** ppSpnegoToken)
+ unsigned char *pbTokenData, unsigned long ulLength,
+ SPNEGO_TOKEN ** ppSpnegoToken)
{
int nReturn = SPNEGO_E_INVALID_PARAMETER;
SPNEGO_TOKEN *pSpnegoToken = NULL;
if (NULL != pbTokenData && NULL != ppSpnegoToken && 0L != ulLength) {
- //
- // Allocate the empty token, then initialize the data structure.
- //
+ //
+ // Allocate the empty token, then initialize the data structure.
+ //
- pSpnegoToken =
- AllocEmptySpnegoToken(ucCopyData, ulFlags, pbTokenData, ulLength);
+ pSpnegoToken =
+ AllocEmptySpnegoToken(ucCopyData, ulFlags, pbTokenData, ulLength);
- if (NULL != pSpnegoToken) {
+ if (NULL != pSpnegoToken) {
- // Copy the binary data locally
+ // Copy the binary data locally
- // Initialize the token type
- if ((nReturn = InitSpnegoTokenType(pSpnegoToken, &nTokenLength,
- &nRemainingTokenLength, &pbFirstElement))
- == SPNEGO_E_SUCCESS) {
+ // Initialize the token type
+ if ((nReturn = InitSpnegoTokenType(pSpnegoToken, &nTokenLength,
+ &nRemainingTokenLength, &pbFirstElement))
+ == SPNEGO_E_SUCCESS) {
- // Initialize the element array
- if ((nReturn =
- InitSpnegoTokenElements(pSpnegoToken, pbFirstElement,
- nRemainingTokenLength))
- == SPNEGO_E_SUCCESS) {
- *ppSpnegoToken = pSpnegoToken;
- }
+ // Initialize the element array
+ if ((nReturn =
+ InitSpnegoTokenElements(pSpnegoToken, pbFirstElement,
+ nRemainingTokenLength))
+ == SPNEGO_E_SUCCESS) {
+ *ppSpnegoToken = pSpnegoToken;
+ }
- } // IF Init Token Type
+ } // IF Init Token Type
- // Cleanup on error condition
- if (SPNEGO_E_SUCCESS != nReturn) {
- spnegoFreeData(pSpnegoToken);
- }
+ // Cleanup on error condition
+ if (SPNEGO_E_SUCCESS != nReturn) {
+ spnegoFreeData(pSpnegoToken);
+ }
- } else {
- nReturn = SPNEGO_E_OUT_OF_MEMORY;
- }
+ } else {
+ nReturn = SPNEGO_E_OUT_OF_MEMORY;
+ }
} // IF Valid parameters
// C++ Specific
#if defined(__cplusplus)
-extern "C"
-{
+extern "C" {
#endif
// Indicates if we copy data when creating a SPNEGO_TOKEN structure or not
// Defines an individual SPNEGO Token Element.
//
- typedef struct SpnegoElement
- {
- size_t nStructSize; // Size of the element structure
- int iElementPresent; // Is the field present? Must be either
- // SPNEGO_TOKEN_ELEMENT_UNAVAILABLE or
- // SPNEGO_TOKEN_ELEMENT_AVAILABLE
+ typedef struct SpnegoElement {
+ size_t nStructSize; // Size of the element structure
+ int iElementPresent; // Is the field present? Must be either
+ // SPNEGO_TOKEN_ELEMENT_UNAVAILABLE or
+ // SPNEGO_TOKEN_ELEMENT_AVAILABLE
- SPNEGO_ELEMENT_TYPE eElementType; // The Element Type
+ SPNEGO_ELEMENT_TYPE eElementType; // The Element Type
- unsigned char type; // Data Type
+ unsigned char type; // Data Type
- unsigned char *pbData; // Points to actual Data
+ unsigned char *pbData; // Points to actual Data
- unsigned long nDatalength; // Actual Data Length
+ unsigned long nDatalength; // Actual Data Length
} SPNEGO_ELEMENT;
// contain up to four distinct, optional elements.
//
- typedef struct SpnegoToken
- {
- size_t nStructSize; // Size of the Token structure
- unsigned long ulFlags; // Internal Structure Flags - Reserved!
- int ucTokenType; // Token Type - Must be
- // SPNEGO_TOKEN_INIT or
- // SPNEGO_TOKEN_TARG
+ typedef struct SpnegoToken {
+ size_t nStructSize; // Size of the Token structure
+ unsigned long ulFlags; // Internal Structure Flags - Reserved!
+ int ucTokenType; // Token Type - Must be
+ // SPNEGO_TOKEN_INIT or
+ // SPNEGO_TOKEN_TARG
- unsigned char *pbBinaryData; // Points to binary token data
+ unsigned char *pbBinaryData; // Points to binary token data
- unsigned long ulBinaryDataLen; // Length of the actual binary data
- int nNumElements; // Number of elements
- SPNEGO_ELEMENT aElementArray[MAX_NUM_TOKEN_ELEMENTS]; // Holds the elements for the token
+ unsigned long ulBinaryDataLen; // Length of the actual binary data
+ int nNumElements; // Number of elements
+ SPNEGO_ELEMENT aElementArray[MAX_NUM_TOKEN_ELEMENTS]; // Holds the elements for the token
} SPNEGO_TOKEN;
// Structure size in case we later choose to extend the structure
//
SPNEGO_TOKEN *AllocEmptySpnegoToken(unsigned char ucCopyData,
- unsigned long ulFlags, unsigned char *pbTokenData,
- unsigned long ulTokenSize);
+ unsigned long ulFlags, unsigned char *pbTokenData,
+ unsigned long ulTokenSize);
void FreeSpnegoToken(SPNEGO_TOKEN * pSpnegoToken);
void InitSpnegoTokenElementArray(SPNEGO_TOKEN * pSpnegoToken);
int InitSpnegoTokenType(SPNEGO_TOKEN * pSpnegoToken, long *pnTokenLength,
- long *pnRemainingTokenLength, unsigned char **ppbFirstElement);
+ long *pnRemainingTokenLength, unsigned char **ppbFirstElement);
int InitSpnegoTokenElements(SPNEGO_TOKEN * pSpnegoToken,
- unsigned char *pbTokenData, long nRemainingTokenLength);
+ unsigned char *pbTokenData, long nRemainingTokenLength);
int GetSpnegoInitTokenMechList(unsigned char *pbTokenData,
- int nMechListLength, SPNEGO_ELEMENT * pSpnegoElement);
+ int nMechListLength, SPNEGO_ELEMENT * pSpnegoElement);
int InitSpnegoTokenElementFromBasicType(unsigned char *pbTokenData,
- int nElementLength, unsigned char ucExpectedType,
- SPNEGO_ELEMENT_TYPE spnegoElementType, SPNEGO_ELEMENT * pSpnegoElement);
+ int nElementLength, unsigned char ucExpectedType,
+ SPNEGO_ELEMENT_TYPE spnegoElementType, SPNEGO_ELEMENT * pSpnegoElement);
int InitSpnegoTokenElementFromOID(unsigned char *pbTokenData,
- int nElementLength, SPNEGO_ELEMENT_TYPE spnegoElementType,
- SPNEGO_ELEMENT * pSpnegoElement);
+ int nElementLength, SPNEGO_ELEMENT_TYPE spnegoElementType,
+ SPNEGO_ELEMENT * pSpnegoElement);
int FindMechOIDInMechList(SPNEGO_ELEMENT * pSpnegoElement,
- SPNEGO_MECH_OID MechOID, int *piMechTypeIndex);
+ SPNEGO_MECH_OID MechOID, int *piMechTypeIndex);
int ValidateMechList(unsigned char *pbMechListData, long nBoundaryLength);
int CalculateMinSpnegoInitTokenSize(long nMechTokenLength,
- long nMechListMICLength, SPNEGO_MECH_OID mechOid,
- int nReqFlagsAvailable, long *plTokenSize, long *plInternalLength);
+ long nMechListMICLength, SPNEGO_MECH_OID mechOid,
+ int nReqFlagsAvailable, long *plTokenSize, long *plInternalLength);
int CalculateMinSpnegoTargTokenSize(SPNEGO_MECH_OID MechType,
- SPNEGO_NEGRESULT spnegoNegResult, long nMechTokenLen,
- long nMechTokenMIC, long *pnTokenSize, long *pnInternalTokenLength);
+ SPNEGO_NEGRESULT spnegoNegResult, long nMechTokenLen,
+ long nMechTokenMIC, long *pnTokenSize, long *pnInternalTokenLength);
int CreateSpnegoInitToken(SPNEGO_MECH_OID MechType,
- unsigned char ucContextFlags, unsigned char *pbMechToken,
- unsigned long ulMechTokenLen, unsigned char *pbMechListMIC,
- unsigned long ulMechListMICLen, unsigned char *pbTokenData,
- long nTokenLength, long nInternalTokenLength);
+ unsigned char ucContextFlags, unsigned char *pbMechToken,
+ unsigned long ulMechTokenLen, unsigned char *pbMechListMIC,
+ unsigned long ulMechListMICLen, unsigned char *pbTokenData,
+ long nTokenLength, long nInternalTokenLength);
int CreateSpnegoTargToken(SPNEGO_MECH_OID MechType,
- SPNEGO_NEGRESULT eNegResult, unsigned char *pbMechToken,
- unsigned long ulMechTokenLen, unsigned char *pbMechListMIC,
- unsigned long ulMechListMICLen, unsigned char *pbTokenData,
- long nTokenLength, long nInternalTokenLength);
+ SPNEGO_NEGRESULT eNegResult, unsigned char *pbMechToken,
+ unsigned long ulMechTokenLen, unsigned char *pbMechListMIC,
+ unsigned long ulMechListMICLen, unsigned char *pbTokenData,
+ long nTokenLength, long nInternalTokenLength);
int IsValidMechOid(SPNEGO_MECH_OID mechOid);
int IsValidContextFlags(unsigned char ucContextFlags);
int IsValidNegResult(SPNEGO_NEGRESULT negResult);
int IsValidSpnegoToken(SPNEGO_TOKEN * pSpnegoToken);
int IsValidSpnegoElement(SPNEGO_TOKEN * pSpnegoToken,
- SPNEGO_ELEMENT_TYPE spnegoElement);
+ SPNEGO_ELEMENT_TYPE spnegoElement);
int CalculateElementArrayIndex(SPNEGO_TOKEN * pSpnegoToken,
- SPNEGO_ELEMENT_TYPE spnegoElement);
+ SPNEGO_ELEMENT_TYPE spnegoElement);
int InitTokenFromBinary(unsigned char ucCopyData, unsigned long ulFlags,
- unsigned char *pbTokenData, unsigned long ulLength,
- SPNEGO_TOKEN ** ppSpnegoToken);
+ unsigned char *pbTokenData, unsigned long ulLength,
+ SPNEGO_TOKEN ** ppSpnegoToken);
// C++ Specific
#if defined(__cplusplus)