#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include "gsscred.h"
extern int
get_der_length(unsigned char **, unsigned int, unsigned int *);
extern unsigned int
der_length_size(unsigned int);
extern int
put_der_length(unsigned int, unsigned char **, unsigned int);
static const char *expNameTokId = "\x04\x01";
static const int expNameTokIdLen = 2;
static const int mechOidLenLen = 2;
static const int mechOidTagLen = 1;
int
gsscred_read_config_file(void)
{
return (GSSCRED_FLAT_FILE);
}
int gsscred_MakeName(const gss_OID mechOid, const char *name,
const char *nameOidStr, gss_buffer_t nameOut)
{
gss_OID nameOid;
gss_name_t intName;
OM_uint32 minor, major;
gss_buffer_desc aName = GSS_C_EMPTY_BUFFER, oidStr;
nameOut->length = 0;
nameOut->value = NULL;
if (nameOidStr == NULL)
nameOid = (gss_OID)GSS_C_NT_USER_NAME;
else {
oidStr.length = strlen(nameOidStr);
oidStr.value = (void *)nameOidStr;
if (gss_str_to_oid(&minor, &oidStr, &nameOid) !=
GSS_S_COMPLETE) {
(void) fprintf(stderr,
gettext("\nInvalid name oid supplied [%s].\n"),
nameOidStr);
return (0);
}
}
aName.length = strlen(name);
aName.value = (void*)name;
major = gss_import_name(&minor, &aName, nameOid, &intName);
if (nameOidStr != NULL) {
free(nameOid->elements);
free(nameOid);
}
if (major != GSS_S_COMPLETE) {
(void) fprintf(stderr,
gettext("\nInternal error importing name [%s].\n"),
name);
return (0);
}
if (gss_canonicalize_name(&minor, intName, mechOid, NULL)
!= GSS_S_COMPLETE) {
(void) fprintf(stderr,
gettext("\nInternal error canonicalizing name"
" [%s].\n"),
name);
(void) gss_release_name(&minor, &intName);
return (0);
}
if (gss_export_name(&minor, intName, nameOut) != GSS_S_COMPLETE) {
(void) fprintf(stderr,
gettext("\nInternal error exporting name [%s].\n"),
name);
(void) gss_release_name(&minor, &intName);
return (0);
}
(void) gss_release_name(&minor, &intName);
return (1);
}
int
gsscred_MakeNameHeader(const gss_OID mechOid, gss_buffer_t outNameHdr)
{
unsigned char *buf = NULL;
int mechOidDERLength, mechOidLength;
mechOidDERLength = der_length_size(mechOid->length);
outNameHdr->length = mechOidLenLen + mechOidTagLen +
mechOidDERLength + expNameTokIdLen + mechOid->length;
if ((outNameHdr->value = (void*)malloc(outNameHdr->length)) == NULL) {
outNameHdr->length = 0;
return (0);
}
buf = (unsigned char *) outNameHdr->value;
(void) memset(outNameHdr->value, '\0', outNameHdr->length);
(void) memcpy(buf, expNameTokId, expNameTokIdLen);
buf += expNameTokIdLen;
mechOidLength = mechOidTagLen + mechOidDERLength +
mechOid->length;
*buf++ = (mechOidLength & 0xFF00) >> 8;
*buf++ = (mechOidLength & 0x00FF);
*buf++ = 0x06;
if (put_der_length(mechOid->length, &buf,
mechOidDERLength) != 0) {
free(outNameHdr->value);
return (0);
}
(void) memcpy(buf, mechOid->elements, mechOid->length);
return (1);
}
int
gsscred_AsHex(gss_buffer_t dataIn, gss_buffer_t dataOut)
{
int i;
char *out, *in;
unsigned int tmp;
if (dataOut->length < ((dataIn->length *2) + 1))
return (0);
out = (char *)dataOut->value;
in = (char *)dataIn->value;
dataOut->length = 0;
for (i = 0; i < dataIn->length; i++) {
tmp = (unsigned int)(*in++)&0xff;
(void) sprintf(out, "%02X", tmp);
out++;
out++;
}
dataOut->length = out - (char *)dataOut->value;
*out = '\0';
return (1);
}
int
gss_getGssCredEntry(const gss_buffer_t expName, uid_t *uid)
{
int tableSource;
unsigned char *buf;
gss_buffer_desc mechOidDesc = GSS_C_EMPTY_BUFFER,
mechHexOidDesc = GSS_C_EMPTY_BUFFER,
expNameHexDesc = GSS_C_EMPTY_BUFFER;
char oidHexBuf[256], expNameHexBuf[1024];
unsigned int dummy;
int len;
tableSource = gsscred_read_config_file();
if (expName->length < (expNameTokIdLen + mechOidLenLen +
mechOidTagLen))
return (0);
buf = (unsigned char *)expName->value;
buf += expNameTokIdLen;
buf++;
buf++;
buf++;
len = get_der_length(&buf,
(expName->length - expNameTokIdLen
- mechOidLenLen - mechOidTagLen), &dummy);
if (len == -1)
return (0);
else
mechOidDesc.length = len;
if (expName->length <
(expNameTokIdLen + mechOidLenLen + mechOidDesc.length
+ dummy+ mechOidTagLen))
return (0);
mechOidDesc.value = (void *)buf;
mechHexOidDesc.value = (void*) oidHexBuf;
mechHexOidDesc.length = sizeof (oidHexBuf);
if (!gsscred_AsHex(&mechOidDesc, &mechHexOidDesc))
return (0);
expNameHexDesc.value = expNameHexBuf;
expNameHexDesc.length = sizeof (expNameHexBuf);
if (!gsscred_AsHex(expName, &expNameHexDesc))
return (0);
if (tableSource == GSSCRED_FLAT_FILE)
return (file_getGssCredUid(&expNameHexDesc, uid));
return (0);
}