#include <stdio.h>
#include "krb.h"
#include <string.h>
static int k_isname_unparsed(const char *s);
static int k_isinst_unparsed(const char *s);
static int k_isrealm_unparsed(const char *s);
#define FULL_SZ (ANAME_SZ + INST_SZ + REALM_SZ)
#define NAME 0
#define INST 1
#define REALM 2
int KRB5_CALLCONV
kname_parse(np, ip, rp, fullname)
char *np;
char *ip;
char *rp;
char *fullname;
{
char buf[FULL_SZ];
char *rnext, *wnext;
register char c;
int backslash;
int field;
backslash = 0;
rnext = buf;
wnext = np;
field = NAME;
if (strlen(fullname) > FULL_SZ)
return KNAME_FMT;
(void) strcpy(buf, fullname);
while ((c = *rnext++)) {
if (backslash) {
*wnext++ = c;
backslash = 0;
continue;
}
switch (c) {
case '\\':
backslash++;
break;
case '.':
switch (field) {
case NAME:
if (wnext == np)
return KNAME_FMT;
*wnext = '\0';
field = INST;
wnext = ip;
break;
case INST:
case REALM:
*wnext++ = c;
break;
default:
DEB (("unknown field value\n"));
return KNAME_FMT;
}
break;
case '@':
switch (field) {
case NAME:
if (wnext == np)
return KNAME_FMT;
*ip = '\0';
case INST:
*wnext = '\0';
field = REALM;
wnext = rp;
break;
case REALM:
return KNAME_FMT;
default:
DEB (("unknown field value\n"));
return KNAME_FMT;
}
break;
default:
*wnext++ = c;
}
switch (field) {
case NAME:
if (wnext - np >= ANAME_SZ)
return KNAME_FMT;
break;
case INST:
if (wnext - ip >= INST_SZ)
return KNAME_FMT;
break;
case REALM:
if (wnext - rp >= REALM_SZ)
return KNAME_FMT;
break;
default:
DEB (("unknown field value\n"));
return KNAME_FMT;
}
}
*wnext = '\0';
return KSUCCESS;
}
int KRB5_CALLCONV
k_isname(s)
char *s;
{
register char c;
int backslash = 0;
if (!*s)
return 0;
if (strlen(s) > ANAME_SZ - 1)
return 0;
while((c = *s++)) {
if (backslash) {
backslash = 0;
continue;
}
switch(c) {
case '\\':
backslash = 1;
break;
case '.':
return 0;
case '@':
return 0;
}
}
return 1;
}
int KRB5_CALLCONV
k_isinst(s)
char *s;
{
register char c;
int backslash = 0;
if (strlen(s) > INST_SZ - 1)
return 0;
while((c = *s++)) {
if (backslash) {
backslash = 0;
continue;
}
switch(c) {
case '\\':
backslash = 1;
break;
case '@':
return 0;
}
}
return 1;
}
int KRB5_CALLCONV
k_isrealm(s)
char *s;
{
register char c;
int backslash = 0;
if (!*s)
return 0;
if (strlen(s) > REALM_SZ - 1)
return 0;
while((c = *s++)) {
if (backslash) {
backslash = 0;
continue;
}
switch(c) {
case '\\':
backslash = 1;
break;
case '@':
return 0;
}
}
return 1;
}
int KRB5_CALLCONV
kname_unparse(
char *outFullName,
const char *inName,
const char *inInstance,
const char *inRealm)
{
const char *read;
char *write = outFullName;
if (inName == NULL)
return KFAILURE;
if (outFullName == NULL)
return KFAILURE;
if (!k_isname_unparsed(inName) ||
((inInstance != NULL) && !k_isinst_unparsed(inInstance)) ||
((inRealm != NULL) && !k_isrealm_unparsed(inRealm))) {
return KFAILURE;
}
for (read = inName; *read != '\0'; read++, write++) {
if ((*read == '.') || (*read == '@')) {
*write = '\\';
write++;
}
*write = *read;
}
if ((inInstance != NULL) && (inInstance[0] != '\0')) {
*write = '.';
write++;
for (read = inInstance; *read != '\0'; read++, write++) {
if (*read == '@') {
*write = '\\';
write++;
}
*write = *read;
}
}
if ((inRealm != NULL) && (inRealm[0] != '\0')) {
*write = '@';
write++;
for (read = inRealm; *read != '\0'; read++, write++) {
if (*read == '@') {
*write = '\\';
write++;
}
*write = *read;
}
}
*write = '\0';
return KSUCCESS;
}
static int
k_isname_unparsed(const char *s)
{
int len = strlen(s);
const char* c;
if (!*s)
return 0;
for (c = s; *c != '\0'; c++) {
switch (*c) {
case '.':
case '@':
len++;
break;
}
}
if (len > ANAME_SZ - 1)
return 0;
return 1;
}
static int
k_isinst_unparsed(const char *s)
{
int len = strlen(s);
const char* c;
for (c = s; *c != '\0'; c++) {
switch (*c) {
case '.':
case '@':
len++;
break;
}
}
if (len > INST_SZ - 1)
return 0;
return 1;
}
static int
k_isrealm_unparsed(const char *s)
{
int len = strlen(s);
const char* c;
if (!*s)
return 0;
for (c = s; *c != '\0'; c++) {
switch (*c) {
case '@':
len++;
break;
}
}
if (len > REALM_SZ - 1)
return 0;
return 1;
}