gss-token: restructure and refactor the code a bit.

This commit is contained in:
Roland C. Dowdeswell
2020-10-07 15:51:39 +01:00
parent ca59ee0ddd
commit 9693bdb272
2 changed files with 130 additions and 111 deletions

View File

@@ -164,8 +164,118 @@ gss_mk_err(OM_uint32 maj_stat, OM_uint32 min_stat, const char *preamble)
return str;
}
static char *
read_buffer(FILE *fp)
{
char buf[65536];
char *p;
char *ret = NULL;
size_t buflen;
size_t retlen = 0;
while (fgets(buf, sizeof(buf), fp) != NULL) {
if ((p = strchr(buf, '\n')) == NULL) {
fprintf(stderr, "Long line, exiting.\n");
exit(1);
}
*p = '\0';
buflen = strlen(buf);
if (buflen == 0)
break;
ret = realloc(ret, retlen + buflen + 1);
if (!ret) {
perror("realloc");
exit(1);
}
memcpy(ret + retlen, buf, buflen);
ret[retlen + buflen] = '\0';
retlen += buflen;
}
if (ferror(stdin)) {
perror("fgets");
exit(1);
}
return ret;
}
static int
write_one_token(gss_name_t service, int delegate, int negotiate)
write_token(gss_buffer_t out, int negotiate)
{
char *outstr = NULL;
char *p = out->value;
size_t len = out->length;
int ret;
if (nflag)
return 0;
ret = rk_base64_encode(p, len, &outstr);
if (ret < 0) {
fprintf(stderr, "Out of memory.\n");
return 1;
}
printf("%s%s\n", negotiate?"Negotiate ":"", outstr);
free(outstr);
return 0;
}
static int
read_token(gss_buffer_t in, int negotiate)
{
char *inbuf = NULL;
char *tmp;
size_t len;
int ret = 0;
inbuf = read_buffer(stdin);
if (!inbuf)
/* Just a couple of \n's in a row or EOF, no error. */
return 0;
tmp = inbuf;
if (negotiate) {
if (strncasecmp("Negotiate ", inbuf, 10)) {
fprintf(stderr, "Token doesn't begin with "
"\"Negotiate \"\n");
ret = -1;
goto bail;
}
tmp += 10;
}
len = strlen(tmp);
in->value = malloc(len + 1);
if (!in->value) {
fprintf(stderr, "Out of memory.\n");
ret = -1;
goto bail;
}
ret = rk_base64_decode(tmp, in->value);
if (ret < 0) {
free(in->value);
in->value = NULL;
if (errno == EOVERFLOW)
fprintf(stderr, "Token is too big\n");
else
fprintf(stderr, "Token encoding is not valid "
"base64\n");
goto bail;
} else {
in->length = ret;
}
ret = 0;
bail:
free(inbuf);
return ret;
}
static int
initiate_one(gss_name_t service, int delegate, int negotiate)
{
gss_ctx_id_t ctx = GSS_C_NO_CONTEXT;
gss_buffer_desc in;
@@ -174,7 +284,6 @@ write_one_token(gss_name_t service, int delegate, int negotiate)
OM_uint32 min;
OM_uint32 flags = 0;
int ret = 0;
char *base64_output = NULL;
in.length = 0;
in.value = 0;
@@ -190,14 +299,7 @@ write_one_token(gss_name_t service, int delegate, int negotiate)
GBAIL("gss_init_sec_context", maj, min);
if (rk_base64_encode(out.value, out.length, &base64_output) < 0) {
fprintf(stderr, "Out of memory.\n");
ret = 1;
goto bail;
}
if (!nflag)
printf("%s%s\n", negotiate?"Negotiate ":"", base64_output);
write_token(&out, negotiate);
bail:
if (out.value)
@@ -212,8 +314,6 @@ bail:
gss_delete_sec_context(&min, &ctx, NULL);
}
free(base64_output);
return ret;
}
@@ -250,8 +350,8 @@ copy_cache(krb5_context kctx, krb5_ccache from, krb5_ccache to)
}
static int
write_token(gss_name_t service, int delegate, int negotiate, int memcache,
size_t count)
initiate_many(gss_name_t service, int delegate, int negotiate, int memcache,
size_t count)
{
krb5_error_code kret;
krb5_context kctx = NULL;
@@ -269,7 +369,7 @@ write_token(gss_name_t service, int delegate, int negotiate, int memcache,
for (i=0; i < count; i++) {
if (memcache)
K5BAIL(copy_cache(kctx, def_cache, mem_cache));
kret = write_one_token(service, delegate, negotiate);
kret = initiate_one(service, delegate, negotiate);
if (!nflag && i < count - 1)
printf("\n");
@@ -285,44 +385,8 @@ write_token(gss_name_t service, int delegate, int negotiate, int memcache,
return kret;
}
static char *
read_buffer(FILE *fp)
{
char buf[65536];
char *p;
char *ret = NULL;
size_t buflen;
size_t retlen = 0;
while (fgets(buf, sizeof(buf), fp) != NULL) {
if ((p = strchr(buf, '\n')) == NULL) {
fprintf(stderr, "Long line, exiting.\n");
exit(1);
}
*p = '\0';
buflen = strlen(buf);
if (buflen == 0)
break;
ret = realloc(ret, retlen + buflen + 1);
memcpy(ret + retlen, buf, buflen);
ret[retlen + buflen] = '\0';
}
if (ferror(stdin)) {
perror("fgets");
exit(1);
}
return ret;
}
static int
read_one_token(gss_name_t service, const char *ccname, int negotiate)
accept_one(gss_name_t service, const char *ccname, int negotiate)
{
gss_cred_id_t cred = NULL;
gss_cred_id_t deleg_creds = NULL;
@@ -335,9 +399,6 @@ read_one_token(gss_name_t service, const char *ccname, int negotiate)
krb5_ccache ccache = NULL;
krb5_error_code kret;
OM_uint32 maj, min;
size_t len;
char *inbuf = NULL;
char *tmp;
int ret = 0;
if (service) {
@@ -346,39 +407,9 @@ read_one_token(gss_name_t service, const char *ccname, int negotiate)
GBAIL("gss_acquire_cred", maj, min);
}
inbuf = read_buffer(stdin);
if (!inbuf)
/* Just a couple of \n's in a row or EOF, not an error. */
return 0;
tmp = inbuf;
if (negotiate) {
if (strncasecmp("Negotiate ", inbuf, 10)) {
fprintf(stderr, "Token doesn't begin with "
"\"Negotiate \"\n");
return -1;
}
tmp += 10;
}
len = strlen(tmp);
in.value = malloc(len + 1);
if (!in.value) {
fprintf(stderr, "Out of memory.\n");
return -1;
}
ret = rk_base64_decode(tmp, in.value);
if (ret < 0) {
free(in.value);
if (errno == EOVERFLOW)
fprintf(stderr, "Token is too big\n");
else
fprintf(stderr, "Token encoding is not valid base64\n");
return -1;
}
in.length = ret;
ret = 0;
ret = read_token(&in, negotiate);
if (ret)
return ret;
out.length = 0;
out.value = 0;
@@ -438,20 +469,6 @@ bail:
gss_release_cred(&min, &deleg_creds);
free(in.value);
free(inbuf);
return ret;
}
static int
read_token(gss_name_t service, const char *ccname, int negotiate, size_t count)
{
size_t i;
int ret;
for (i=0; i < count; i++) {
ret = read_one_token(service, ccname, negotiate);
}
return ret;
}
@@ -545,7 +562,7 @@ main(int argc, char **argv)
"make sense without -r.\n");
usage(1);
}
ret = write_token(service, Dflag, Nflag, Mflag, count);
ret = initiate_many(service, Dflag, Nflag, Mflag, count);
goto done;
}
@@ -556,7 +573,7 @@ main(int argc, char **argv)
}
do {
ret = read_token(service, ccname, Nflag, count);
ret = accept_one(service, ccname, Nflag);
} while (lflag && !ret && !feof(stdin));
done: