gss-token: turn initiator and acceptor into loops.
This commit is contained in:
@@ -78,6 +78,23 @@ takes one argument, a
|
||||
specifier.
|
||||
The argument is required when running as an initiator but is optional as
|
||||
an acceptor.
|
||||
.Pp
|
||||
.Nm
|
||||
will try to read a token whenever the GSS mechanism expects one
|
||||
and will output a token whenever the GSS mechanism provides one.
|
||||
Tokens are base64 encoded and terminated by either two successive
|
||||
newlines or one newline and EOF.
|
||||
The base64 encoding may be broken up by single newlines which will
|
||||
be ignored when read. No extra whitespace will be ignored.
|
||||
.Sh EXAMPLES
|
||||
To test a simple GSS mechanism which doesn't require a round trip,
|
||||
a single
|
||||
.Pa /bin/sh
|
||||
pipeline will suffice:
|
||||
.Bd -literal -offset indent
|
||||
$ export KRB5_KTNAME=/path/to/keytab
|
||||
$ gss-token HTTP@$(hostname) | gss-token -r
|
||||
.Ed
|
||||
.Sh SEE ALSO
|
||||
.Xr gssapi 3 ,
|
||||
.Xr kerberos 8 .
|
||||
|
@@ -203,17 +203,25 @@ read_buffer(FILE *fp)
|
||||
}
|
||||
|
||||
static int
|
||||
write_token(gss_buffer_t out, int negotiate)
|
||||
write_and_free_token(gss_buffer_t out, int negotiate)
|
||||
{
|
||||
OM_uint32 min;
|
||||
char *outstr = NULL;
|
||||
char *p = out->value;
|
||||
size_t len = out->length;
|
||||
size_t inc;
|
||||
int ret;
|
||||
int ret = 0;
|
||||
int first = 1;
|
||||
|
||||
if (nflag)
|
||||
return 0;
|
||||
goto bail;
|
||||
|
||||
/*
|
||||
* According to RFC 2744 page 25, we simply don't output
|
||||
* zero length output tokens.
|
||||
*/
|
||||
if (len == 0)
|
||||
goto bail;
|
||||
|
||||
inc = len;
|
||||
if (Sflag)
|
||||
@@ -229,7 +237,8 @@ write_token(gss_buffer_t out, int negotiate)
|
||||
ret = rk_base64_encode(p, inc, &outstr);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Out of memory.\n");
|
||||
return 1;
|
||||
ret = 1;
|
||||
goto bail;
|
||||
}
|
||||
printf("%s%s\n", negotiate?"Negotiate ":"", outstr);
|
||||
free(outstr);
|
||||
@@ -237,6 +246,8 @@ write_token(gss_buffer_t out, int negotiate)
|
||||
len -= inc;
|
||||
} while (len > 0);
|
||||
|
||||
bail:
|
||||
gss_release_buffer(&min, out);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -248,6 +259,9 @@ read_token(gss_buffer_t in, int negotiate)
|
||||
size_t len;
|
||||
int ret = 0;
|
||||
|
||||
/* We must flush before we block wanting input */
|
||||
fflush(stdout);
|
||||
|
||||
inbuf = read_buffer(stdin);
|
||||
if (!inbuf)
|
||||
/* Just a couple of \n's in a row or EOF, no error. */
|
||||
@@ -301,28 +315,42 @@ initiate_one(gss_name_t service, int delegate, int negotiate)
|
||||
OM_uint32 maj;
|
||||
OM_uint32 min;
|
||||
OM_uint32 flags = 0;
|
||||
int first = 1;
|
||||
int ret = 0;
|
||||
|
||||
in.length = 0;
|
||||
in.value = 0;
|
||||
out.length = 0;
|
||||
out.value = 0;
|
||||
|
||||
if (delegate)
|
||||
flags |= GSS_C_DELEG_FLAG;
|
||||
|
||||
maj = gss_init_sec_context(&min, GSS_C_NO_CREDENTIAL, &ctx, service,
|
||||
GSS_C_NO_OID, flags, 0, GSS_C_NO_CHANNEL_BINDINGS, &in, NULL, &out,
|
||||
do {
|
||||
out.length = 0;
|
||||
out.value = 0;
|
||||
|
||||
if (first) {
|
||||
in.length = 0;
|
||||
in.value = 0;
|
||||
first = 0;
|
||||
} else {
|
||||
printf("\n");
|
||||
ret = read_token(&in, negotiate);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (feof(stdin))
|
||||
return -1;
|
||||
}
|
||||
|
||||
maj = gss_init_sec_context(&min, GSS_C_NO_CREDENTIAL, &ctx,
|
||||
service, GSS_C_NO_OID, flags, 0,
|
||||
GSS_C_NO_CHANNEL_BINDINGS, &in, NULL, &out,
|
||||
NULL, NULL);
|
||||
|
||||
GBAIL("gss_init_sec_context", maj, min);
|
||||
ret = write_and_free_token(&out, negotiate);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
write_token(&out, negotiate);
|
||||
GBAIL("gss_init_sec_context", maj, min);
|
||||
} while (maj & GSS_S_CONTINUE_NEEDED);
|
||||
|
||||
bail:
|
||||
if (out.value)
|
||||
gss_release_buffer(&min, &out);
|
||||
|
||||
if (ctx != GSS_C_NO_CONTEXT) {
|
||||
/*
|
||||
* XXXrcd: here we ignore the fact that we might have an
|
||||
@@ -425,6 +453,9 @@ accept_one(gss_name_t service, const char *ccname, int negotiate)
|
||||
GBAIL("gss_acquire_cred", maj, min);
|
||||
}
|
||||
|
||||
do {
|
||||
if (feof(stdin))
|
||||
return -1;
|
||||
ret = read_token(&in, negotiate);
|
||||
if (ret)
|
||||
return ret;
|
||||
@@ -436,7 +467,11 @@ accept_one(gss_name_t service, const char *ccname, int negotiate)
|
||||
GSS_C_NO_CHANNEL_BINDINGS, &client, &mech_oid, &out,
|
||||
NULL, NULL, &deleg_creds);
|
||||
|
||||
ret = write_and_free_token(&out, negotiate);
|
||||
if (ret)
|
||||
return ret;
|
||||
GBAIL("gss_accept_sec_context", maj, min);
|
||||
} while (maj & GSS_S_CONTINUE_NEEDED);
|
||||
|
||||
/*
|
||||
* XXXrcd: not bothering to clean up because we're about to exit.
|
||||
|
Reference in New Issue
Block a user