gss-token: turn initiator and acceptor into loops.
This commit is contained in:
@@ -78,6 +78,23 @@ takes one argument, a
|
|||||||
specifier.
|
specifier.
|
||||||
The argument is required when running as an initiator but is optional as
|
The argument is required when running as an initiator but is optional as
|
||||||
an acceptor.
|
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
|
.Sh SEE ALSO
|
||||||
.Xr gssapi 3 ,
|
.Xr gssapi 3 ,
|
||||||
.Xr kerberos 8 .
|
.Xr kerberos 8 .
|
||||||
|
@@ -203,17 +203,25 @@ read_buffer(FILE *fp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
write_token(gss_buffer_t out, int negotiate)
|
write_and_free_token(gss_buffer_t out, int negotiate)
|
||||||
{
|
{
|
||||||
char *outstr = NULL;
|
OM_uint32 min;
|
||||||
char *p = out->value;
|
char *outstr = NULL;
|
||||||
size_t len = out->length;
|
char *p = out->value;
|
||||||
size_t inc;
|
size_t len = out->length;
|
||||||
int ret;
|
size_t inc;
|
||||||
int first = 1;
|
int ret = 0;
|
||||||
|
int first = 1;
|
||||||
|
|
||||||
if (nflag)
|
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;
|
inc = len;
|
||||||
if (Sflag)
|
if (Sflag)
|
||||||
@@ -229,7 +237,8 @@ write_token(gss_buffer_t out, int negotiate)
|
|||||||
ret = rk_base64_encode(p, inc, &outstr);
|
ret = rk_base64_encode(p, inc, &outstr);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
fprintf(stderr, "Out of memory.\n");
|
fprintf(stderr, "Out of memory.\n");
|
||||||
return 1;
|
ret = 1;
|
||||||
|
goto bail;
|
||||||
}
|
}
|
||||||
printf("%s%s\n", negotiate?"Negotiate ":"", outstr);
|
printf("%s%s\n", negotiate?"Negotiate ":"", outstr);
|
||||||
free(outstr);
|
free(outstr);
|
||||||
@@ -237,6 +246,8 @@ write_token(gss_buffer_t out, int negotiate)
|
|||||||
len -= inc;
|
len -= inc;
|
||||||
} while (len > 0);
|
} while (len > 0);
|
||||||
|
|
||||||
|
bail:
|
||||||
|
gss_release_buffer(&min, out);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -248,6 +259,9 @@ read_token(gss_buffer_t in, int negotiate)
|
|||||||
size_t len;
|
size_t len;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
/* We must flush before we block wanting input */
|
||||||
|
fflush(stdout);
|
||||||
|
|
||||||
inbuf = read_buffer(stdin);
|
inbuf = read_buffer(stdin);
|
||||||
if (!inbuf)
|
if (!inbuf)
|
||||||
/* Just a couple of \n's in a row or EOF, no error. */
|
/* 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 maj;
|
||||||
OM_uint32 min;
|
OM_uint32 min;
|
||||||
OM_uint32 flags = 0;
|
OM_uint32 flags = 0;
|
||||||
|
int first = 1;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
in.length = 0;
|
|
||||||
in.value = 0;
|
|
||||||
out.length = 0;
|
|
||||||
out.value = 0;
|
|
||||||
|
|
||||||
if (delegate)
|
if (delegate)
|
||||||
flags |= GSS_C_DELEG_FLAG;
|
flags |= GSS_C_DELEG_FLAG;
|
||||||
|
|
||||||
maj = gss_init_sec_context(&min, GSS_C_NO_CREDENTIAL, &ctx, service,
|
do {
|
||||||
GSS_C_NO_OID, flags, 0, GSS_C_NO_CHANNEL_BINDINGS, &in, NULL, &out,
|
out.length = 0;
|
||||||
NULL, NULL);
|
out.value = 0;
|
||||||
|
|
||||||
GBAIL("gss_init_sec_context", maj, min);
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
write_token(&out, negotiate);
|
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);
|
||||||
|
|
||||||
|
ret = write_and_free_token(&out, negotiate);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
GBAIL("gss_init_sec_context", maj, min);
|
||||||
|
} while (maj & GSS_S_CONTINUE_NEEDED);
|
||||||
|
|
||||||
bail:
|
bail:
|
||||||
if (out.value)
|
|
||||||
gss_release_buffer(&min, &out);
|
|
||||||
|
|
||||||
if (ctx != GSS_C_NO_CONTEXT) {
|
if (ctx != GSS_C_NO_CONTEXT) {
|
||||||
/*
|
/*
|
||||||
* XXXrcd: here we ignore the fact that we might have an
|
* XXXrcd: here we ignore the fact that we might have an
|
||||||
@@ -425,18 +453,25 @@ accept_one(gss_name_t service, const char *ccname, int negotiate)
|
|||||||
GBAIL("gss_acquire_cred", maj, min);
|
GBAIL("gss_acquire_cred", maj, min);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = read_token(&in, negotiate);
|
do {
|
||||||
if (ret)
|
if (feof(stdin))
|
||||||
return ret;
|
return -1;
|
||||||
|
ret = read_token(&in, negotiate);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
out.length = 0;
|
out.length = 0;
|
||||||
out.value = 0;
|
out.value = 0;
|
||||||
|
|
||||||
maj = gss_accept_sec_context(&min, &ctx, cred, &in,
|
|
||||||
GSS_C_NO_CHANNEL_BINDINGS, &client, &mech_oid, &out,
|
|
||||||
NULL, NULL, &deleg_creds);
|
|
||||||
|
|
||||||
GBAIL("gss_accept_sec_context", maj, min);
|
maj = gss_accept_sec_context(&min, &ctx, cred, &in,
|
||||||
|
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.
|
* XXXrcd: not bothering to clean up because we're about to exit.
|
||||||
|
Reference in New Issue
Block a user