gss-token: restructure and refactor the code a bit.
This commit is contained in:
@@ -20,7 +20,9 @@
|
|||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
.Nm
|
.Nm
|
||||||
generates and consumes base64 encoded GSS tokens.
|
generates and consumes base64 encoded GSS tokens.
|
||||||
It is mostly useful for testing.
|
By default, it runs as an initiator and with the
|
||||||
|
.Fl r
|
||||||
|
flag it becomes an acceptor.
|
||||||
.Pp
|
.Pp
|
||||||
.Nm
|
.Nm
|
||||||
supports the following options:
|
supports the following options:
|
||||||
@@ -54,22 +56,22 @@ to generated tokens and expect it on consumed tokens.
|
|||||||
repeat the operation
|
repeat the operation
|
||||||
.Ar count
|
.Ar count
|
||||||
times.
|
times.
|
||||||
|
This flag only changes the behaviour when operating in initiator mode.
|
||||||
This is good for very basic benchmarking.
|
This is good for very basic benchmarking.
|
||||||
.It Fl l
|
.It Fl l
|
||||||
loop infinitely in read mode.
|
loop indefinitely in acceptor mode.
|
||||||
This is to support a multiple round trip GSS mechanism.
|
|
||||||
.It Fl n
|
.It Fl n
|
||||||
do not output the generated token.
|
do not output the generated tokens.
|
||||||
.It Fl r
|
.It Fl r
|
||||||
read a token rather than generate a token.
|
run in acceptor mode.
|
||||||
.El
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
.Nm
|
.Nm
|
||||||
takes one argument, a
|
takes one argument, a
|
||||||
.Ar host@service
|
.Ar host@service
|
||||||
specifier.
|
specifier.
|
||||||
The argument is required when generating a token but is optional if
|
The argument is required when running as an initiator but is optional as
|
||||||
consuming (reading) a token.
|
an acceptor.
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr gssapi 3 ,
|
.Xr gssapi 3 ,
|
||||||
.Xr kerberos 8 .
|
.Xr kerberos 8 .
|
||||||
|
@@ -164,8 +164,118 @@ gss_mk_err(OM_uint32 maj_stat, OM_uint32 min_stat, const char *preamble)
|
|||||||
return str;
|
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
|
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_ctx_id_t ctx = GSS_C_NO_CONTEXT;
|
||||||
gss_buffer_desc in;
|
gss_buffer_desc in;
|
||||||
@@ -174,7 +284,6 @@ write_one_token(gss_name_t service, int delegate, int negotiate)
|
|||||||
OM_uint32 min;
|
OM_uint32 min;
|
||||||
OM_uint32 flags = 0;
|
OM_uint32 flags = 0;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
char *base64_output = NULL;
|
|
||||||
|
|
||||||
in.length = 0;
|
in.length = 0;
|
||||||
in.value = 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);
|
GBAIL("gss_init_sec_context", maj, min);
|
||||||
|
|
||||||
if (rk_base64_encode(out.value, out.length, &base64_output) < 0) {
|
write_token(&out, negotiate);
|
||||||
fprintf(stderr, "Out of memory.\n");
|
|
||||||
ret = 1;
|
|
||||||
goto bail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!nflag)
|
|
||||||
printf("%s%s\n", negotiate?"Negotiate ":"", base64_output);
|
|
||||||
|
|
||||||
bail:
|
bail:
|
||||||
if (out.value)
|
if (out.value)
|
||||||
@@ -212,8 +314,6 @@ bail:
|
|||||||
gss_delete_sec_context(&min, &ctx, NULL);
|
gss_delete_sec_context(&min, &ctx, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(base64_output);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,8 +350,8 @@ copy_cache(krb5_context kctx, krb5_ccache from, krb5_ccache to)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
write_token(gss_name_t service, int delegate, int negotiate, int memcache,
|
initiate_many(gss_name_t service, int delegate, int negotiate, int memcache,
|
||||||
size_t count)
|
size_t count)
|
||||||
{
|
{
|
||||||
krb5_error_code kret;
|
krb5_error_code kret;
|
||||||
krb5_context kctx = NULL;
|
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++) {
|
for (i=0; i < count; i++) {
|
||||||
if (memcache)
|
if (memcache)
|
||||||
K5BAIL(copy_cache(kctx, def_cache, mem_cache));
|
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)
|
if (!nflag && i < count - 1)
|
||||||
printf("\n");
|
printf("\n");
|
||||||
@@ -285,44 +385,8 @@ write_token(gss_name_t service, int delegate, int negotiate, int memcache,
|
|||||||
return kret;
|
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
|
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 cred = NULL;
|
||||||
gss_cred_id_t deleg_creds = 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_ccache ccache = NULL;
|
||||||
krb5_error_code kret;
|
krb5_error_code kret;
|
||||||
OM_uint32 maj, min;
|
OM_uint32 maj, min;
|
||||||
size_t len;
|
|
||||||
char *inbuf = NULL;
|
|
||||||
char *tmp;
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (service) {
|
if (service) {
|
||||||
@@ -346,39 +407,9 @@ read_one_token(gss_name_t service, const char *ccname, int negotiate)
|
|||||||
GBAIL("gss_acquire_cred", maj, min);
|
GBAIL("gss_acquire_cred", maj, min);
|
||||||
}
|
}
|
||||||
|
|
||||||
inbuf = read_buffer(stdin);
|
ret = read_token(&in, negotiate);
|
||||||
if (!inbuf)
|
if (ret)
|
||||||
/* Just a couple of \n's in a row or EOF, not an error. */
|
return ret;
|
||||||
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;
|
|
||||||
|
|
||||||
out.length = 0;
|
out.length = 0;
|
||||||
out.value = 0;
|
out.value = 0;
|
||||||
@@ -438,20 +469,6 @@ bail:
|
|||||||
gss_release_cred(&min, &deleg_creds);
|
gss_release_cred(&min, &deleg_creds);
|
||||||
|
|
||||||
free(in.value);
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -545,7 +562,7 @@ main(int argc, char **argv)
|
|||||||
"make sense without -r.\n");
|
"make sense without -r.\n");
|
||||||
usage(1);
|
usage(1);
|
||||||
}
|
}
|
||||||
ret = write_token(service, Dflag, Nflag, Mflag, count);
|
ret = initiate_many(service, Dflag, Nflag, Mflag, count);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -556,7 +573,7 @@ main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
ret = read_token(service, ccname, Nflag, count);
|
ret = accept_one(service, ccname, Nflag);
|
||||||
} while (lflag && !ret && !feof(stdin));
|
} while (lflag && !ret && !feof(stdin));
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
Reference in New Issue
Block a user