summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew N. Dodd <matthew.nygard.dodd@gmail.com>2011-06-20 13:34:56 -0400
committerSteve Dickson <steved@redhat.com>2011-06-20 13:34:56 -0400
commit6383fae17388f5cd7b4674995d13beed1e7fa087 (patch)
tree95cb10c6f9d83cddb5ccded527b0ad0605789149
parentf2db0f29ce283385d5663c390a3ca7fb40e21dde (diff)
downloadti-rpc-6383fae17388f5cd7b4674995d13beed1e7fa087.tar.gz
SVCAUTH_WRAP/SVCAUTH_UNWRAP
Server code lacks support for authenticator wrapping/unwrapping, which is particularly useful when using GSS. Verified for both tcp & udp using a trivial RPC server against an MIT Krb5 client. Signed-off-by: Frank Filz <ffilzlnx@us.ibm.com> Signed-off-by: Steve Dickson <steved@redhat.com>
-rw-r--r--src/svc.c11
-rw-r--r--src/svc_auth_unix.c5
-rw-r--r--src/svc_dg.c31
-rw-r--r--src/svc_vc.c37
-rw-r--r--tirpc/rpc/svc_auth.h18
5 files changed, 83 insertions, 19 deletions
diff --git a/src/svc.c b/src/svc.c
index b4a63d0..08cd6c9 100644
--- a/src/svc.c
+++ b/src/svc.c
@@ -77,9 +77,6 @@ static struct svc_callout
extern rwlock_t svc_lock;
extern rwlock_t svc_fd_lock;
-#ifdef HAVE_LIBGSSAPI
-extern struct svc_auth_ops svc_auth_gss_ops;
-#endif
static struct svc_callout *svc_find (rpcprog_t, rpcvers_t,
struct svc_callout **, char *);
@@ -717,11 +714,9 @@ svc_getreq_common (fd)
SVC_DESTROY (xprt);
break;
}
- else if ((xprt->xp_auth != NULL)
-#ifdef HAVE_LIBGSSAPI
- && (xprt->xp_auth->svc_ah_ops != &svc_auth_gss_ops)
-#endif
- ) {
+ else if ((xprt->xp_auth != NULL) &&
+ (xprt->xp_auth->svc_ah_private == NULL))
+ {
xprt->xp_auth = NULL;
}
}
diff --git a/src/svc_auth_unix.c b/src/svc_auth_unix.c
index ce83859..9585069 100644
--- a/src/svc_auth_unix.c
+++ b/src/svc_auth_unix.c
@@ -43,6 +43,8 @@
#include <rpc/rpc.h>
+extern SVCAUTH svc_auth_none;
+
/*
* Unix longhand authenticator
*/
@@ -67,6 +69,8 @@ _svcauth_unix(rqst, msg)
assert(rqst != NULL);
assert(msg != NULL);
+ rqst->rq_xprt->xp_auth = &svc_auth_none;
+
area = (struct area *) rqst->rq_clntcred;
aup = &area->area_aup;
aup->aup_machname = area->area_machname;
@@ -142,5 +146,6 @@ _svcauth_short(rqst, msg)
struct svc_req *rqst;
struct rpc_msg *msg;
{
+ rqst->rq_xprt->xp_auth = &svc_auth_none;
return (AUTH_REJECTEDCRED);
}
diff --git a/src/svc_dg.c b/src/svc_dg.c
index 66a56ee..5ef9df2 100644
--- a/src/svc_dg.c
+++ b/src/svc_dg.c
@@ -134,6 +134,7 @@ svc_dg_create(fd, sendsize, recvsize)
su->su_cache = NULL;
xprt->xp_fd = fd;
xprt->xp_p2 = su;
+ xprt->xp_auth = NULL;
xprt->xp_verf.oa_base = su->su_verfbody;
svc_dg_ops(xprt);
xprt->xp_rtaddr.maxlen = sizeof (struct sockaddr_storage);
@@ -234,10 +235,27 @@ svc_dg_reply(xprt, msg)
bool_t stat = FALSE;
size_t slen;
+ xdrproc_t xdr_results;
+ caddr_t xdr_location;
+ bool_t has_args;
+
+ if (msg->rm_reply.rp_stat == MSG_ACCEPTED &&
+ msg->rm_reply.rp_acpt.ar_stat == SUCCESS) {
+ has_args = TRUE;
+ xdr_results = msg->acpted_rply.ar_results.proc;
+ xdr_location = msg->acpted_rply.ar_results.where;
+
+ msg->acpted_rply.ar_results.proc = (xdrproc_t)xdr_void;
+ msg->acpted_rply.ar_results.where = NULL;
+ } else
+ has_args = FALSE;
+
xdrs->x_op = XDR_ENCODE;
XDR_SETPOS(xdrs, 0);
msg->rm_xid = su->su_xid;
- if (xdr_replymsg(xdrs, msg)) {
+ if (xdr_replymsg(xdrs, msg) &&
+ (!has_args ||
+ (SVCAUTH_WRAP(xprt->xp_auth, xdrs, xdr_results, xdr_location)))) {
struct msghdr *msg = &su->su_msghdr;
struct iovec iov;
@@ -264,7 +282,12 @@ svc_dg_getargs(xprt, xdr_args, args_ptr)
xdrproc_t xdr_args;
void *args_ptr;
{
- return (*xdr_args)(&(su_data(xprt)->su_xdrs), args_ptr);
+ if (! SVCAUTH_UNWRAP(xprt->xp_auth, &(su_data(xprt)->su_xdrs),
+ xdr_args, args_ptr)) {
+ (void)svc_freeargs(xprt, xdr_args, args_ptr);
+ return FALSE;
+ }
+ return TRUE;
}
static bool_t
@@ -288,6 +311,10 @@ svc_dg_destroy(xprt)
xprt_unregister(xprt);
if (xprt->xp_fd != -1)
(void)close(xprt->xp_fd);
+ if (xprt->xp_auth != NULL) {
+ SVCAUTH_DESTROY(xprt->xp_auth);
+ xprt->xp_auth = NULL;
+ }
XDR_DESTROY(&(su->su_xdrs));
(void) mem_free(rpc_buffer(xprt), su->su_iosz);
(void) mem_free(su, sizeof (*su));
diff --git a/src/svc_vc.c b/src/svc_vc.c
index 87406f1..74632e2 100644
--- a/src/svc_vc.c
+++ b/src/svc_vc.c
@@ -172,6 +172,7 @@ svc_vc_create(fd, sendsize, recvsize)
xprt->xp_p1 = r;
xprt->xp_p2 = NULL;
xprt->xp_p3 = NULL;
+ xprt->xp_auth = NULL;
xprt->xp_verf = _null_auth;
svc_vc_rendezvous_ops(xprt);
xprt->xp_port = (u_short)-1; /* It is the rendezvouser */
@@ -283,6 +284,7 @@ makefd_xprt(fd, sendsize, recvsize)
xdrrec_create(&(cd->xdrs), sendsize, recvsize,
xprt, read_vc, write_vc);
xprt->xp_p1 = cd;
+ xprt->xp_auth = NULL;
xprt->xp_verf.oa_base = cd->verf_body;
svc_vc_ops(xprt); /* truely deals with calls */
xprt->xp_port = 0; /* this is a connection, not a rendezvouser */
@@ -412,6 +414,10 @@ __svc_vc_dodestroy(xprt)
XDR_DESTROY(&(cd->xdrs));
mem_free(cd, sizeof(struct cf_conn));
}
+ if (xprt->xp_auth != NULL) {
+ SVCAUTH_DESTROY(xprt->xp_auth);
+ xprt->xp_auth = NULL;
+ }
if (xprt->xp_rtaddr.buf)
mem_free(xprt->xp_rtaddr.buf, xprt->xp_rtaddr.maxlen);
if (xprt->xp_ltaddr.buf)
@@ -632,8 +638,13 @@ svc_vc_getargs(xprt, xdr_args, args_ptr)
assert(xprt != NULL);
/* args_ptr may be NULL */
- return ((*xdr_args)(&(((struct cf_conn *)(xprt->xp_p1))->xdrs),
- args_ptr));
+
+ if (! SVCAUTH_UNWRAP(xprt->xp_auth,
+ &(((struct cf_conn *)(xprt->xp_p1))->xdrs),
+ xdr_args, args_ptr)) {
+ return FALSE;
+ }
+ return TRUE;
}
static bool_t
@@ -662,15 +673,35 @@ svc_vc_reply(xprt, msg)
XDR *xdrs;
bool_t rstat;
+ xdrproc_t xdr_results;
+ caddr_t xdr_location;
+ bool_t has_args;
+
assert(xprt != NULL);
assert(msg != NULL);
cd = (struct cf_conn *)(xprt->xp_p1);
xdrs = &(cd->xdrs);
+ if (msg->rm_reply.rp_stat == MSG_ACCEPTED &&
+ msg->rm_reply.rp_acpt.ar_stat == SUCCESS) {
+ has_args = TRUE;
+ xdr_results = msg->acpted_rply.ar_results.proc;
+ xdr_location = msg->acpted_rply.ar_results.where;
+
+ msg->acpted_rply.ar_results.proc = (xdrproc_t)xdr_void;
+ msg->acpted_rply.ar_results.where = NULL;
+ } else
+ has_args = FALSE;
+
xdrs->x_op = XDR_ENCODE;
msg->rm_xid = cd->x_id;
- rstat = xdr_replymsg(xdrs, msg);
+ rstat = FALSE;
+ if (xdr_replymsg(xdrs, msg) &&
+ (!has_args ||
+ (SVCAUTH_WRAP(xprt->xp_auth, xdrs, xdr_results, xdr_location)))) {
+ rstat = TRUE;
+ }
(void)xdrrec_endofrecord(xdrs, TRUE);
return (rstat);
}
diff --git a/tirpc/rpc/svc_auth.h b/tirpc/rpc/svc_auth.h
index 659e90c..14269d1 100644
--- a/tirpc/rpc/svc_auth.h
+++ b/tirpc/rpc/svc_auth.h
@@ -44,17 +44,23 @@
/*
* Interface to server-side authentication flavors.
*/
-typedef struct {
+typedef struct SVCAUTH {
struct svc_auth_ops {
- int (*svc_ah_wrap)(void);
- int (*svc_ah_unwrap)(void);
- int (*svc_ah_destroy)(void);
+ int (*svc_ah_wrap)(struct SVCAUTH *, XDR *, xdrproc_t,
+ caddr_t);
+ int (*svc_ah_unwrap)(struct SVCAUTH *, XDR *, xdrproc_t,
+ caddr_t);
+ int (*svc_ah_destroy)(struct SVCAUTH *);
} *svc_ah_ops;
caddr_t svc_ah_private;
} SVCAUTH;
-#define SVCAUTH_DESTROY(cred) ((*(cred)->svc_ah_ops->svc_ah_destroy)())
-#define svcauth_destroy(cred) ((*(cred)->svc_ah_ops->svc_ah_destroy)())
+#define SVCAUTH_WRAP(auth, xdrs, xfunc, xwhere) \
+ ((*((auth)->svc_ah_ops->svc_ah_wrap))(auth, xdrs, xfunc, xwhere))
+#define SVCAUTH_UNWRAP(auth, xdrs, xfunc, xwhere) \
+ ((*((auth)->svc_ah_ops->svc_ah_unwrap))(auth, xdrs, xfunc, xwhere))
+#define SVCAUTH_DESTROY(auth) \
+ ((*((auth)->svc_ah_ops->svc_ah_destroy))(auth))
/*
* Server side authenticator