|
|
b52932 |
diff --git a/src/svc.c b/src/svc.c
|
|
|
b52932 |
index 08cd6c9..8afd15d 100644
|
|
|
b52932 |
--- a/src/svc.c
|
|
|
b52932 |
+++ b/src/svc.c
|
|
|
b52932 |
@@ -649,6 +649,7 @@ svc_getreq_common (fd)
|
|
|
b52932 |
{
|
|
|
b52932 |
if (SVC_RECV (xprt, &msg))
|
|
|
b52932 |
{
|
|
|
b52932 |
+ bool_t no_dispatch;
|
|
|
b52932 |
|
|
|
b52932 |
/* now find the exported program and call it */
|
|
|
b52932 |
struct svc_callout *s;
|
|
|
b52932 |
@@ -660,11 +661,14 @@ svc_getreq_common (fd)
|
|
|
b52932 |
r.rq_proc = msg.rm_call.cb_proc;
|
|
|
b52932 |
r.rq_cred = msg.rm_call.cb_cred;
|
|
|
b52932 |
/* first authenticate the message */
|
|
|
b52932 |
- if ((why = _authenticate (&r, &msg)) != AUTH_OK)
|
|
|
b52932 |
+ why = _gss_authenticate(&r, &msg, &no_dispatch);
|
|
|
b52932 |
+ if (why != AUTH_OK)
|
|
|
b52932 |
{
|
|
|
b52932 |
svcerr_auth (xprt, why);
|
|
|
b52932 |
goto call_done;
|
|
|
b52932 |
}
|
|
|
b52932 |
+ if (no_dispatch)
|
|
|
b52932 |
+ goto call_done;
|
|
|
b52932 |
/* now match message with a registered service */
|
|
|
b52932 |
prog_found = FALSE;
|
|
|
b52932 |
low_vers = (rpcvers_t) - 1L;
|
|
|
b52932 |
diff --git a/src/svc_auth.c b/src/svc_auth.c
|
|
|
b52932 |
index e80d5f9..31241c9 100644
|
|
|
b52932 |
--- a/src/svc_auth.c
|
|
|
b52932 |
+++ b/src/svc_auth.c
|
|
|
b52932 |
@@ -82,9 +82,10 @@ static struct authsvc *Auths = NULL;
|
|
|
b52932 |
* invalid.
|
|
|
b52932 |
*/
|
|
|
b52932 |
enum auth_stat
|
|
|
b52932 |
-_authenticate(rqst, msg)
|
|
|
b52932 |
+_gss_authenticate(rqst, msg, no_dispatch)
|
|
|
b52932 |
struct svc_req *rqst;
|
|
|
b52932 |
struct rpc_msg *msg;
|
|
|
b52932 |
+ bool_t *no_dispatch;
|
|
|
b52932 |
{
|
|
|
b52932 |
int cred_flavor;
|
|
|
b52932 |
struct authsvc *asp;
|
|
|
b52932 |
@@ -97,6 +98,7 @@ _authenticate(rqst, msg)
|
|
|
b52932 |
rqst->rq_xprt->xp_verf.oa_flavor = _null_auth.oa_flavor;
|
|
|
b52932 |
rqst->rq_xprt->xp_verf.oa_length = 0;
|
|
|
b52932 |
cred_flavor = rqst->rq_cred.oa_flavor;
|
|
|
b52932 |
+ *no_dispatch = FALSE;
|
|
|
b52932 |
switch (cred_flavor) {
|
|
|
b52932 |
case AUTH_NONE:
|
|
|
b52932 |
dummy = _svcauth_none(rqst, msg);
|
|
|
b52932 |
@@ -112,6 +114,11 @@ _authenticate(rqst, msg)
|
|
|
b52932 |
dummy = _svcauth_des(rqst, msg);
|
|
|
b52932 |
return (dummy);
|
|
|
b52932 |
#endif
|
|
|
b52932 |
+#ifdef HAVE_RPCSEC_GSS
|
|
|
b52932 |
+ case RPCSEC_GSS:
|
|
|
b52932 |
+ dummy = _svcauth_gss(rqst, msg, no_dispatch);
|
|
|
b52932 |
+ return (dummy);
|
|
|
b52932 |
+#endif
|
|
|
b52932 |
default:
|
|
|
b52932 |
break;
|
|
|
b52932 |
}
|
|
|
b52932 |
@@ -132,6 +139,13 @@ _authenticate(rqst, msg)
|
|
|
b52932 |
return (AUTH_REJECTEDCRED);
|
|
|
b52932 |
}
|
|
|
b52932 |
|
|
|
b52932 |
+enum auth_stat
|
|
|
b52932 |
+_authenticate(struct svc_req *rqst, struct rpc_msg *msg)
|
|
|
b52932 |
+{
|
|
|
b52932 |
+ bool_t no_dispatch;
|
|
|
b52932 |
+ return _gss_authenticate(rqst, msg, &no_dispatch);
|
|
|
b52932 |
+}
|
|
|
b52932 |
+
|
|
|
b52932 |
/*
|
|
|
b52932 |
* Allow the rpc service to register new authentication types that it is
|
|
|
b52932 |
* prepared to handle. When an authentication flavor is registered,
|
|
|
b52932 |
@@ -161,6 +175,9 @@ svc_auth_reg(cred_flavor, handler)
|
|
|
b52932 |
#ifdef DES_BUILTIN
|
|
|
b52932 |
case AUTH_DES:
|
|
|
b52932 |
#endif
|
|
|
b52932 |
+#ifdef HAVE_RPCSEC_GSS
|
|
|
b52932 |
+ case RPCSEC_GSS:
|
|
|
b52932 |
+#endif
|
|
|
b52932 |
/* already registered */
|
|
|
b52932 |
return (1);
|
|
|
b52932 |
|
|
|
b52932 |
diff --git a/src/svc_auth_gss.c b/src/svc_auth_gss.c
|
|
|
b52932 |
index 3a3c980..7376107 100644
|
|
|
b52932 |
--- a/src/svc_auth_gss.c
|
|
|
b52932 |
+++ b/src/svc_auth_gss.c
|
|
|
b52932 |
@@ -116,6 +116,7 @@ svcauth_gss_import_name(char *service)
|
|
|
b52932 |
gss_name_t name;
|
|
|
b52932 |
gss_buffer_desc namebuf;
|
|
|
b52932 |
OM_uint32 maj_stat, min_stat;
|
|
|
b52932 |
+ bool_t result;
|
|
|
b52932 |
|
|
|
b52932 |
gss_log_debug("in svcauth_gss_import_name()");
|
|
|
b52932 |
|
|
|
b52932 |
@@ -130,11 +131,9 @@ svcauth_gss_import_name(char *service)
|
|
|
b52932 |
maj_stat, min_stat);
|
|
|
b52932 |
return (FALSE);
|
|
|
b52932 |
}
|
|
|
b52932 |
- if (svcauth_gss_set_svc_name(name) != TRUE) {
|
|
|
b52932 |
- gss_release_name(&min_stat, &name);
|
|
|
b52932 |
- return (FALSE);
|
|
|
b52932 |
- }
|
|
|
b52932 |
- return (TRUE);
|
|
|
b52932 |
+ result = svcauth_gss_set_svc_name(name);
|
|
|
b52932 |
+ gss_release_name(&min_stat, &name);
|
|
|
b52932 |
+ return result;
|
|
|
b52932 |
}
|
|
|
b52932 |
|
|
|
b52932 |
static bool_t
|
|
|
b52932 |
@@ -211,6 +210,8 @@ svcauth_gss_accept_sec_context(struct svc_req *rqst,
|
|
|
b52932 |
NULL,
|
|
|
b52932 |
NULL);
|
|
|
b52932 |
|
|
|
b52932 |
+ xdr_free((xdrproc_t)xdr_rpc_gss_init_args, (caddr_t)&recv_tok);
|
|
|
b52932 |
+
|
|
|
b52932 |
if (gr->gr_major != GSS_S_COMPLETE &&
|
|
|
b52932 |
gr->gr_major != GSS_S_CONTINUE_NEEDED) {
|
|
|
b52932 |
gss_log_status("svcauth_gss_accept_sec_context: accept_sec_context",
|
|
|
b52932 |
@@ -279,8 +280,11 @@ svcauth_gss_accept_sec_context(struct svc_req *rqst,
|
|
|
b52932 |
return (FALSE);
|
|
|
b52932 |
|
|
|
b52932 |
rqst->rq_xprt->xp_verf.oa_flavor = RPCSEC_GSS;
|
|
|
b52932 |
- rqst->rq_xprt->xp_verf.oa_base = checksum.value;
|
|
|
b52932 |
+ memcpy(rqst->rq_xprt->xp_verf.oa_base, checksum.value,
|
|
|
b52932 |
+ checksum.length);
|
|
|
b52932 |
rqst->rq_xprt->xp_verf.oa_length = checksum.length;
|
|
|
b52932 |
+
|
|
|
b52932 |
+ gss_release_buffer(&min_stat, &checksum);
|
|
|
b52932 |
}
|
|
|
b52932 |
return (TRUE);
|
|
|
b52932 |
}
|
|
|
b52932 |
@@ -363,10 +367,13 @@ svcauth_gss_nextverf(struct svc_req *rqst, u_int num)
|
|
|
b52932 |
maj_stat, min_stat);
|
|
|
b52932 |
return (FALSE);
|
|
|
b52932 |
}
|
|
|
b52932 |
+
|
|
|
b52932 |
rqst->rq_xprt->xp_verf.oa_flavor = RPCSEC_GSS;
|
|
|
b52932 |
- rqst->rq_xprt->xp_verf.oa_base = (caddr_t)checksum.value;
|
|
|
b52932 |
+ memcpy(rqst->rq_xprt->xp_verf.oa_base, checksum.value, checksum.length);
|
|
|
b52932 |
rqst->rq_xprt->xp_verf.oa_length = (u_int)checksum.length;
|
|
|
b52932 |
|
|
|
b52932 |
+ gss_release_buffer(&min_stat, &checksum);
|
|
|
b52932 |
+
|
|
|
b52932 |
return (TRUE);
|
|
|
b52932 |
}
|
|
|
b52932 |
|
|
|
b52932 |
@@ -379,8 +386,10 @@ _svcauth_gss(struct svc_req *rqst, struct rpc_msg *msg, bool_t *no_dispatch)
|
|
|
b52932 |
struct rpc_gss_cred *gc;
|
|
|
b52932 |
struct rpc_gss_init_res gr;
|
|
|
b52932 |
int call_stat, offset;
|
|
|
b52932 |
+ enum auth_stat result = AUTH_OK;
|
|
|
b52932 |
+ OM_uint32 min_stat;
|
|
|
b52932 |
|
|
|
b52932 |
- gss_log_debug("in svcauth_gss()");
|
|
|
b52932 |
+ gss_log_debug("in _svcauth_gss()");
|
|
|
b52932 |
|
|
|
b52932 |
/* Initialize reply. */
|
|
|
b52932 |
rqst->rq_xprt->xp_verf = _null_auth;
|
|
|
b52932 |
@@ -419,19 +428,25 @@ _svcauth_gss(struct svc_req *rqst, struct rpc_msg *msg, bool_t *no_dispatch)
|
|
|
b52932 |
XDR_DESTROY(&xdrs);
|
|
|
b52932 |
|
|
|
b52932 |
/* Check version. */
|
|
|
b52932 |
- if (gc->gc_v != RPCSEC_GSS_VERSION)
|
|
|
b52932 |
- return (AUTH_BADCRED);
|
|
|
b52932 |
+ if (gc->gc_v != RPCSEC_GSS_VERSION) {
|
|
|
b52932 |
+ result = AUTH_BADCRED;
|
|
|
b52932 |
+ goto out;
|
|
|
b52932 |
+ }
|
|
|
b52932 |
|
|
|
b52932 |
/* Check RPCSEC_GSS service. */
|
|
|
b52932 |
if (gc->gc_svc != RPCSEC_GSS_SVC_NONE &&
|
|
|
b52932 |
gc->gc_svc != RPCSEC_GSS_SVC_INTEGRITY &&
|
|
|
b52932 |
- gc->gc_svc != RPCSEC_GSS_SVC_PRIVACY)
|
|
|
b52932 |
- return (AUTH_BADCRED);
|
|
|
b52932 |
+ gc->gc_svc != RPCSEC_GSS_SVC_PRIVACY) {
|
|
|
b52932 |
+ result = AUTH_BADCRED;
|
|
|
b52932 |
+ goto out;
|
|
|
b52932 |
+ }
|
|
|
b52932 |
|
|
|
b52932 |
/* Check sequence number. */
|
|
|
b52932 |
if (gd->established) {
|
|
|
b52932 |
- if (gc->gc_seq > MAXSEQ)
|
|
|
b52932 |
- return (RPCSEC_GSS_CTXPROBLEM);
|
|
|
b52932 |
+ if (gc->gc_seq > MAXSEQ) {
|
|
|
b52932 |
+ result = RPCSEC_GSS_CTXPROBLEM;
|
|
|
b52932 |
+ goto out;
|
|
|
b52932 |
+ }
|
|
|
b52932 |
|
|
|
b52932 |
if ((offset = gd->seqlast - gc->gc_seq) < 0) {
|
|
|
b52932 |
gd->seqlast = gc->gc_seq;
|
|
|
b52932 |
@@ -441,7 +456,8 @@ _svcauth_gss(struct svc_req *rqst, struct rpc_msg *msg, bool_t *no_dispatch)
|
|
|
b52932 |
}
|
|
|
b52932 |
else if (offset >= gd->win || (gd->seqmask & (1 << offset))) {
|
|
|
b52932 |
*no_dispatch = 1;
|
|
|
b52932 |
- return (RPCSEC_GSS_CTXPROBLEM);
|
|
|
b52932 |
+ result = RPCSEC_GSS_CTXPROBLEM;
|
|
|
b52932 |
+ goto out;
|
|
|
b52932 |
}
|
|
|
b52932 |
gd->seq = gc->gc_seq;
|
|
|
b52932 |
gd->seqmask |= (1 << offset);
|
|
|
b52932 |
@@ -452,35 +468,52 @@ _svcauth_gss(struct svc_req *rqst, struct rpc_msg *msg, bool_t *no_dispatch)
|
|
|
b52932 |
rqst->rq_svcname = (char *)gd->ctx;
|
|
|
b52932 |
}
|
|
|
b52932 |
|
|
|
b52932 |
+ rqst->rq_xprt->xp_verf.oa_base = msg->rm_call.cb_verf.oa_base;
|
|
|
b52932 |
+
|
|
|
b52932 |
/* Handle RPCSEC_GSS control procedure. */
|
|
|
b52932 |
switch (gc->gc_proc) {
|
|
|
b52932 |
|
|
|
b52932 |
case RPCSEC_GSS_INIT:
|
|
|
b52932 |
case RPCSEC_GSS_CONTINUE_INIT:
|
|
|
b52932 |
- if (rqst->rq_proc != NULLPROC)
|
|
|
b52932 |
- return (AUTH_FAILED); /* XXX ? */
|
|
|
b52932 |
+ if (rqst->rq_proc != NULLPROC) {
|
|
|
b52932 |
+ result = AUTH_FAILED;
|
|
|
b52932 |
+ break;
|
|
|
b52932 |
+ }
|
|
|
b52932 |
|
|
|
b52932 |
if (_svcauth_gss_name == NULL) {
|
|
|
b52932 |
- if (!svcauth_gss_import_name("nfs"))
|
|
|
b52932 |
- return (AUTH_FAILED);
|
|
|
b52932 |
+ if (!svcauth_gss_import_name("nfs")) {
|
|
|
b52932 |
+ result = AUTH_FAILED;
|
|
|
b52932 |
+ break;
|
|
|
b52932 |
+ }
|
|
|
b52932 |
}
|
|
|
b52932 |
|
|
|
b52932 |
- if (!svcauth_gss_acquire_cred())
|
|
|
b52932 |
- return (AUTH_FAILED);
|
|
|
b52932 |
+ if (!svcauth_gss_acquire_cred()) {
|
|
|
b52932 |
+ result = AUTH_FAILED;
|
|
|
b52932 |
+ break;
|
|
|
b52932 |
+ }
|
|
|
b52932 |
|
|
|
b52932 |
- if (!svcauth_gss_accept_sec_context(rqst, &gr))
|
|
|
b52932 |
- return (AUTH_REJECTEDCRED);
|
|
|
b52932 |
+ if (!svcauth_gss_accept_sec_context(rqst, &gr)) {
|
|
|
b52932 |
+ result = AUTH_REJECTEDCRED;
|
|
|
b52932 |
+ break;
|
|
|
b52932 |
+ }
|
|
|
b52932 |
|
|
|
b52932 |
- if (!svcauth_gss_nextverf(rqst, htonl(gr.gr_win)))
|
|
|
b52932 |
- return (AUTH_FAILED);
|
|
|
b52932 |
+ if (!svcauth_gss_nextverf(rqst, htonl(gr.gr_win))) {
|
|
|
b52932 |
+ result = AUTH_FAILED;
|
|
|
b52932 |
+ break;
|
|
|
b52932 |
+ }
|
|
|
b52932 |
|
|
|
b52932 |
*no_dispatch = TRUE;
|
|
|
b52932 |
|
|
|
b52932 |
call_stat = svc_sendreply(rqst->rq_xprt,
|
|
|
b52932 |
(xdrproc_t)xdr_rpc_gss_init_res, (caddr_t)&gr);
|
|
|
b52932 |
|
|
|
b52932 |
- if (!call_stat)
|
|
|
b52932 |
- return (AUTH_FAILED);
|
|
|
b52932 |
+ gss_release_buffer(&min_stat, &gr.gr_token);
|
|
|
b52932 |
+ free(gr.gr_ctx.value);
|
|
|
b52932 |
+
|
|
|
b52932 |
+ if (!call_stat) {
|
|
|
b52932 |
+ result = AUTH_FAILED;
|
|
|
b52932 |
+ break;
|
|
|
b52932 |
+ }
|
|
|
b52932 |
|
|
|
b52932 |
if (gr.gr_major == GSS_S_COMPLETE)
|
|
|
b52932 |
gd->established = TRUE;
|
|
|
b52932 |
@@ -488,25 +521,36 @@ _svcauth_gss(struct svc_req *rqst, struct rpc_msg *msg, bool_t *no_dispatch)
|
|
|
b52932 |
break;
|
|
|
b52932 |
|
|
|
b52932 |
case RPCSEC_GSS_DATA:
|
|
|
b52932 |
- if (!svcauth_gss_validate(gd, msg))
|
|
|
b52932 |
- return (RPCSEC_GSS_CREDPROBLEM);
|
|
|
b52932 |
+ if (!svcauth_gss_validate(gd, msg)) {
|
|
|
b52932 |
+ result = RPCSEC_GSS_CREDPROBLEM;
|
|
|
b52932 |
+ break;
|
|
|
b52932 |
+ }
|
|
|
b52932 |
|
|
|
b52932 |
- if (!svcauth_gss_nextverf(rqst, htonl(gc->gc_seq)))
|
|
|
b52932 |
- return (AUTH_FAILED);
|
|
|
b52932 |
+ if (!svcauth_gss_nextverf(rqst, htonl(gc->gc_seq))) {
|
|
|
b52932 |
+ result = AUTH_FAILED;
|
|
|
b52932 |
+ break;
|
|
|
b52932 |
+ }
|
|
|
b52932 |
break;
|
|
|
b52932 |
|
|
|
b52932 |
case RPCSEC_GSS_DESTROY:
|
|
|
b52932 |
- if (rqst->rq_proc != NULLPROC)
|
|
|
b52932 |
- return (AUTH_FAILED); /* XXX ? */
|
|
|
b52932 |
-
|
|
|
b52932 |
- if (!svcauth_gss_validate(gd, msg))
|
|
|
b52932 |
- return (RPCSEC_GSS_CREDPROBLEM);
|
|
|
b52932 |
+ if (rqst->rq_proc != NULLPROC) {
|
|
|
b52932 |
+ result = AUTH_FAILED; /* XXX ? */
|
|
|
b52932 |
+ break;
|
|
|
b52932 |
+ }
|
|
|
b52932 |
+ if (!svcauth_gss_validate(gd, msg)) {
|
|
|
b52932 |
+ result = RPCSEC_GSS_CREDPROBLEM;
|
|
|
b52932 |
+ break;
|
|
|
b52932 |
+ }
|
|
|
b52932 |
|
|
|
b52932 |
- if (!svcauth_gss_nextverf(rqst, htonl(gc->gc_seq)))
|
|
|
b52932 |
- return (AUTH_FAILED);
|
|
|
b52932 |
+ if (!svcauth_gss_nextverf(rqst, htonl(gc->gc_seq))) {
|
|
|
b52932 |
+ result = AUTH_FAILED;
|
|
|
b52932 |
+ break;
|
|
|
b52932 |
+ }
|
|
|
b52932 |
|
|
|
b52932 |
- if (!svcauth_gss_release_cred())
|
|
|
b52932 |
- return (AUTH_FAILED);
|
|
|
b52932 |
+ if (!svcauth_gss_release_cred()) {
|
|
|
b52932 |
+ result = AUTH_FAILED;
|
|
|
b52932 |
+ break;
|
|
|
b52932 |
+ }
|
|
|
b52932 |
|
|
|
b52932 |
SVCAUTH_DESTROY(rqst->rq_xprt->xp_auth);
|
|
|
b52932 |
rqst->rq_xprt->xp_auth = &svc_auth_none;
|
|
|
b52932 |
@@ -514,10 +558,15 @@ _svcauth_gss(struct svc_req *rqst, struct rpc_msg *msg, bool_t *no_dispatch)
|
|
|
b52932 |
break;
|
|
|
b52932 |
|
|
|
b52932 |
default:
|
|
|
b52932 |
- return (AUTH_REJECTEDCRED);
|
|
|
b52932 |
+ result = AUTH_REJECTEDCRED;
|
|
|
b52932 |
break;
|
|
|
b52932 |
}
|
|
|
b52932 |
- return (AUTH_OK);
|
|
|
b52932 |
+out:
|
|
|
b52932 |
+ xdr_free((xdrproc_t)xdr_rpc_gss_cred, (caddr_t)gc);
|
|
|
b52932 |
+ if (result != AUTH_OK)
|
|
|
b52932 |
+ gss_log_debug("_svcauth_gss() failed: %d", result);
|
|
|
b52932 |
+
|
|
|
b52932 |
+ return result;
|
|
|
b52932 |
}
|
|
|
b52932 |
|
|
|
b52932 |
bool_t
|
|
|
b52932 |
diff --git a/tirpc/rpc/auth.h b/tirpc/rpc/auth.h
|
|
|
b52932 |
index 4ce11f0..7c8f813 100644
|
|
|
b52932 |
--- a/tirpc/rpc/auth.h
|
|
|
b52932 |
+++ b/tirpc/rpc/auth.h
|
|
|
b52932 |
@@ -399,6 +399,7 @@ struct rpc_msg;
|
|
|
b52932 |
enum auth_stat _svcauth_none (struct svc_req *, struct rpc_msg *);
|
|
|
b52932 |
enum auth_stat _svcauth_short (struct svc_req *, struct rpc_msg *);
|
|
|
b52932 |
enum auth_stat _svcauth_unix (struct svc_req *, struct rpc_msg *);
|
|
|
b52932 |
+enum auth_stat _svcauth_gss (struct svc_req *, struct rpc_msg *, bool_t *);
|
|
|
b52932 |
__END_DECLS
|
|
|
b52932 |
|
|
|
b52932 |
#define AUTH_NONE 0 /* no authentication */
|
|
|
b52932 |
diff --git a/tirpc/rpc/svc_auth.h b/tirpc/rpc/svc_auth.h
|
|
|
b52932 |
index 14269d1..723c989 100644
|
|
|
b52932 |
--- a/tirpc/rpc/svc_auth.h
|
|
|
b52932 |
+++ b/tirpc/rpc/svc_auth.h
|
|
|
b52932 |
@@ -66,6 +66,8 @@ typedef struct SVCAUTH {
|
|
|
b52932 |
* Server side authenticator
|
|
|
b52932 |
*/
|
|
|
b52932 |
__BEGIN_DECLS
|
|
|
b52932 |
+extern enum auth_stat _gss_authenticate(struct svc_req *, struct rpc_msg *,
|
|
|
b52932 |
+ bool_t *);
|
|
|
b52932 |
extern enum auth_stat _authenticate(struct svc_req *, struct rpc_msg *);
|
|
|
b52932 |
extern int svc_auth_reg(int, enum auth_stat (*)(struct svc_req *,
|
|
|
b52932 |
struct rpc_msg *));
|