]> granicus.if.org Git - libtirpc/commitdiff
SVCAUTH_WRAP/SVCAUTH_UNWRAP
authorMatthew N. Dodd <matthew.nygard.dodd@gmail.com>
Mon, 20 Jun 2011 17:34:56 +0000 (13:34 -0400)
committerSteve Dickson <steved@redhat.com>
Tue, 21 Jun 2011 18:31:44 +0000 (14:31 -0400)
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>
src/svc.c
src/svc_auth_unix.c
src/svc_dg.c
src/svc_vc.c
tirpc/rpc/svc_auth.h

index b4a63d019fe6d0ddc571ad5aad8fa15cab3b9404..08cd6c9887adc214ed5da51660e8dc45530b16c6 100644 (file)
--- 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;
        }
     }
index ce8385947cf7b76dd732140cce27ea6bb66c9693..9585069071bbee2934f1101598139dd6ffa16d73 100644 (file)
@@ -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);
 }
index 66a56eecdaa8af10b3907aec3724317d01cf1e3a..5ef9df267fedb79a1a84499fbee632d8ca97d2aa 100644 (file)
@@ -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));
index 87406f1c188df2cc617a91ad9b54ba1c0c2b6a2d..74632e2a98bb9365e39197119303a1da09561b33 100644 (file)
@@ -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);
 }
index 659e90cf6606ed95b2756284c05a04a868352ab4..14269d124c3d2cc50135dbf0e6699f763fc6d941 100644 (file)
 /*
  * 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