From aab6538bbd55177221788df5bdb4b61698e00305 Mon Sep 17 00:00:00 2001 From: Ronnie Sahlberg Date: Mon, 26 Nov 2012 19:42:10 -0800 Subject: [PATCH] Implement 'rejected_reply' and switch to RFC5531 definitions Switch to using fields and names from RFC5531. that is the standard for RPC. --- include/libnfs-zdr.h | 136 +++++++++++++++++++++---------------------- lib/libnfs-zdr.c | 69 ++++++++++++++-------- lib/pdu.c | 26 ++++----- 3 files changed, 123 insertions(+), 108 deletions(-) diff --git a/include/libnfs-zdr.h b/include/libnfs-zdr.h index c5794b6..44f7378 100644 --- a/include/libnfs-zdr.h +++ b/include/libnfs-zdr.h @@ -21,6 +21,11 @@ * It aims to be compatible with normal rpcgen generated functions. */ +/************************************************************ + * Definitions copied from RFC 5531 + * and slightly modified. + ************************************************************/ + #include "config.h" #ifndef _LIBNFS_ZDR_H_ @@ -88,6 +93,7 @@ typedef int (*zdrproc_t) (ZDR *, void *,...); #define AUTH_NONE 0 #define AUTH_NULL 0 #define AUTH_UNIX 1 + struct opaque_auth { uint32_t oa_flavor; caddr_t oa_base; @@ -95,59 +101,36 @@ struct opaque_auth { }; extern struct opaque_auth _null_auth; - struct AUTH { struct opaque_auth ah_cred; struct opaque_auth ah_verf; caddr_t ah_private; }; -enum msg_type { - CALL=0, - REPLY=1 -}; - #define RPC_MSG_VERSION 2 -struct call_body { - uint32_t cb_rpcvers; - uint32_t cb_prog; - uint32_t cb_vers; - uint32_t cb_proc; - struct opaque_auth cb_cred; - struct opaque_auth cb_verf; +enum msg_type { + CALL = 0, + REPLY = 1 }; -enum accept_stat { - SUCCESS=0, - PROG_UNAVAIL=1, - PROG_MISMATCH=2, - PROC_UNAVAIL=3, - GARBAGE_ARGS=4, - SYSTEM_ERR=5 +enum reply_stat { + MSG_ACCEPTED=0, + MSG_DENIED=1 }; -struct accepted_reply { - struct opaque_auth ar_verf; - uint32_t ar_stat; - union { - struct { - uint32_t low; - uint32_t high; - } AR_versions; - struct { - caddr_t where; - zdrproc_t proc; - } AR_results; - /* and many other null cases */ - } ru; -#define ar_results ru.AR_results -#define ar_vers ru.AR_versions +enum accept_stat { + SUCCESS = 0, + PROG_UNAVAIL = 1, + PROG_MISMATCH = 2, + PROC_UNAVAIL = 3, + GARBAGE_ARGS = 4, + SYSTEM_ERR = 5 }; enum reject_stat { - RPC_MISMATCH=0, - AUTH_ERROR=1 + RPC_MISMATCH = 0, + AUTH_ERROR = 1 }; enum auth_stat { @@ -155,59 +138,70 @@ enum auth_stat { /* * failed at remote end */ - AUTH_BADCRED=1, /* bogus credentials (seal broken) */ - AUTH_REJECTEDCRED=2, /* client should begin new session */ - AUTH_BADVERF=3, /* bogus verifier (seal broken) */ - AUTH_REJECTEDVERF=4, /* verifier expired or was replayed */ - AUTH_TOOWEAK=5, /* rejected due to security reasons */ + AUTH_BADCRED = 1, /* bogus credentials (seal broken) */ + AUTH_REJECTEDCRED = 2, /* client should begin new session */ + AUTH_BADVERF = 3, /* bogus verifier (seal broken) */ + AUTH_REJECTEDVERF = 4, /* verifier expired or was replayed */ + AUTH_TOOWEAK = 5, /* rejected due to security reasons */ /* * failed locally */ - AUTH_INVALIDRESP=6, /* bogus response verifier */ - AUTH_FAILED=7 /* some unknown reason */ + AUTH_INVALIDRESP = 6, /* bogus response verifier */ + AUTH_FAILED = 7 /* some unknown reason */ +}; + +struct call_body { + uint32_t rpcvers; + uint32_t prog; + uint32_t vers; + uint32_t proc; + struct opaque_auth cred; + struct opaque_auth verf; +}; + +struct accepted_reply { + struct opaque_auth verf; + uint32_t stat; + union { + struct { + caddr_t where; + zdrproc_t proc; + } results; + struct { + uint32_t low; + uint32_t high; + } mismatch_info; + } reply_data; }; struct rejected_reply { - enum reject_stat rj_stat; + enum reject_stat stat; union { struct { u_long low; u_long high; - } RJ_versions; - enum auth_stat RJ_why; /* why authentication did not work */ - } ru; -#define rj_vers ru.RJ_versions -#define rj_why ru.RJ_why + } mismatch_info; + enum auth_stat stat; + } reject_data; }; -#define MSG_ACCEPTED 0 -#define MSG_DENIED 1 - struct reply_body { - uint32_t rp_stat; + uint32_t stat; union { - struct accepted_reply RP_ar; - struct rejected_reply RP_dr; - } ru; -#define rp_acpt ru.RP_ar -#define rp_rjct ru.RP_dr + struct accepted_reply areply; + struct rejected_reply rreply; + } reply; }; struct rpc_msg { - uint32_t rm_xid; + uint32_t xid; - uint32_t rm_direction; + uint32_t direction; union { - struct call_body RM_cmb; - struct reply_body RM_rmb; - } ru; -#define rm_call ru.RM_cmb -#define rm_reply ru.RM_rmb + struct call_body cbody; + struct reply_body rbody; + } body; }; -#define acpted_rply ru.RM_rmb.ru.RP_ar -#define rjcted_rply ru.RM_rmb.ru.RP_dr - - #define zdrmem_create libnfs_zdrmem_create void libnfs_zdrmem_create(ZDR *zdrs, const caddr_t addr, uint32_t size, enum zdr_op xop); diff --git a/lib/libnfs-zdr.c b/lib/libnfs-zdr.c index cdb35b9..a243d1d 100644 --- a/lib/libnfs-zdr.c +++ b/lib/libnfs-zdr.c @@ -307,27 +307,27 @@ static bool_t libnfs_opaque_auth(ZDR *zdrs, struct opaque_auth *auth) static bool_t libnfs_rpc_call_body(ZDR *zdrs, struct call_body *cmb) { - if (!libnfs_zdr_u_int(zdrs, &cmb->cb_rpcvers)) { + if (!libnfs_zdr_u_int(zdrs, &cmb->rpcvers)) { return FALSE; } - if (!libnfs_zdr_u_int(zdrs, &cmb->cb_prog)) { + if (!libnfs_zdr_u_int(zdrs, &cmb->prog)) { return FALSE; } - if (!libnfs_zdr_u_int(zdrs, &cmb->cb_vers)) { + if (!libnfs_zdr_u_int(zdrs, &cmb->vers)) { return FALSE; } - if (!libnfs_zdr_u_int(zdrs, &cmb->cb_proc)) { + if (!libnfs_zdr_u_int(zdrs, &cmb->proc)) { return FALSE; } - if (!libnfs_opaque_auth(zdrs, &cmb->cb_cred)) { + if (!libnfs_opaque_auth(zdrs, &cmb->cred)) { return FALSE; } - if (!libnfs_opaque_auth(zdrs, &cmb->cb_verf)) { + if (!libnfs_opaque_auth(zdrs, &cmb->verf)) { return FALSE; } @@ -336,25 +336,25 @@ static bool_t libnfs_rpc_call_body(ZDR *zdrs, struct call_body *cmb) static bool_t libnfs_accepted_reply(ZDR *zdrs, struct accepted_reply *ar) { - if (!libnfs_opaque_auth(zdrs, &ar->ar_verf)) { + if (!libnfs_opaque_auth(zdrs, &ar->verf)) { return FALSE; } - if (!libnfs_zdr_u_int(zdrs, &ar->ar_stat)) { + if (!libnfs_zdr_u_int(zdrs, &ar->stat)) { return FALSE; } - switch (ar->ar_stat) { + switch (ar->stat) { case SUCCESS: - if (!ar->ar_results.proc(zdrs, ar->ar_results.where)) { + if (!ar->reply_data.results.proc(zdrs, ar->reply_data.results.where)) { return FALSE; } return TRUE; case PROG_MISMATCH: - if (!libnfs_zdr_u_int(zdrs, &ar->ar_vers.low)) { + if (!libnfs_zdr_u_int(zdrs, &ar->reply_data.mismatch_info.low)) { return FALSE; } - if (!libnfs_zdr_u_int(zdrs, &ar->ar_vers.high)) { + if (!libnfs_zdr_u_int(zdrs, &ar->reply_data.mismatch_info.high)) { return FALSE; } return TRUE; @@ -365,26 +365,47 @@ static bool_t libnfs_accepted_reply(ZDR *zdrs, struct accepted_reply *ar) return FALSE; } -static bool_t libnfs_rejected_reply(ZDR *zdrs, struct rejected_reply *RP_dr) +static bool_t libnfs_rejected_reply(ZDR *zdrs, struct rejected_reply *rr) { -printf("rejected reply\n"); -exit(10); + if (!libnfs_zdr_u_int(zdrs, &rr->stat)) { + return FALSE; + } + + switch (rr->stat) { + case RPC_MISMATCH: + if (!libnfs_zdr_u_int(zdrs, &rr->reject_data.mismatch_info.low)) { + return FALSE; + } + if (!libnfs_zdr_u_int(zdrs, &rr->reject_data.mismatch_info.high)) { + return FALSE; + } + return TRUE; + case AUTH_ERROR: + if (!libnfs_zdr_u_int(zdrs, &rr->reject_data.stat)) { + return FALSE; + } + return TRUE; + default: + return TRUE; + } + + return FALSE; } static bool_t libnfs_rpc_reply_body(ZDR *zdrs, struct reply_body *rmb) { - if (!libnfs_zdr_u_int(zdrs, &rmb->rp_stat)) { + if (!libnfs_zdr_u_int(zdrs, &rmb->stat)) { return FALSE; } - switch (rmb->rp_stat) { + switch (rmb->stat) { case MSG_ACCEPTED: - if (!libnfs_accepted_reply(zdrs, &rmb->rp_acpt)) { + if (!libnfs_accepted_reply(zdrs, &rmb->reply.areply)) { return FALSE; } return TRUE; case MSG_DENIED: - if (!libnfs_rejected_reply(zdrs, &rmb->rp_rjct)) { + if (!libnfs_rejected_reply(zdrs, &rmb->reply.rreply)) { return FALSE; } return TRUE; @@ -395,20 +416,20 @@ static bool_t libnfs_rpc_reply_body(ZDR *zdrs, struct reply_body *rmb) static bool_t libnfs_rpc_msg(ZDR *zdrs, struct rpc_msg *msg) { - if (!libnfs_zdr_u_int(zdrs, &msg->rm_xid)) { + if (!libnfs_zdr_u_int(zdrs, &msg->xid)) { return FALSE; } - if (!libnfs_zdr_u_int(zdrs, &msg->rm_direction)) { + if (!libnfs_zdr_u_int(zdrs, &msg->direction)) { return FALSE; } - switch (msg->rm_direction) { + switch (msg->direction) { case CALL: - return libnfs_rpc_call_body(zdrs, &msg->ru.RM_cmb); + return libnfs_rpc_call_body(zdrs, &msg->body.cbody); break; case REPLY: - return libnfs_rpc_reply_body(zdrs, &msg->ru.RM_rmb); + return libnfs_rpc_reply_body(zdrs, &msg->body.rbody); break; default: return FALSE; diff --git a/lib/pdu.c b/lib/pdu.c index 7dc1ee3..6614260 100644 --- a/lib/pdu.c +++ b/lib/pdu.c @@ -61,14 +61,14 @@ struct rpc_pdu *rpc_allocate_pdu(struct rpc_context *rpc, int program, int versi } memset(&msg, 0, sizeof(struct rpc_msg)); - msg.rm_xid = pdu->xid; - msg.rm_direction = CALL; - msg.rm_call.cb_rpcvers = RPC_MSG_VERSION; - msg.rm_call.cb_prog = program; - msg.rm_call.cb_vers = version; - msg.rm_call.cb_proc = procedure; - msg.rm_call.cb_cred = rpc->auth->ah_cred; - msg.rm_call.cb_verf = rpc->auth->ah_verf; + msg.xid = pdu->xid; + msg.direction = CALL; + msg.body.cbody.rpcvers = RPC_MSG_VERSION; + msg.body.cbody.prog = program; + msg.body.cbody.vers = version; + msg.body.cbody.proc = procedure; + msg.body.cbody.cred = rpc->auth->ah_cred; + msg.body.cbody.verf = rpc->auth->ah_verf; if (zdr_callmsg(&pdu->zdr, &msg) == 0) { rpc_set_error(rpc, "zdr_callmsg failed"); @@ -156,7 +156,7 @@ static int rpc_process_reply(struct rpc_context *rpc, struct rpc_pdu *pdu, ZDR * assert(rpc->magic == RPC_CONTEXT_MAGIC); memset(&msg, 0, sizeof(struct rpc_msg)); - msg.acpted_rply.ar_verf = _null_auth; + msg.body.rbody.reply.areply.verf = _null_auth; if (pdu->zdr_decode_bufsize > 0) { if (pdu->zdr_decode_buf != NULL) { free(pdu->zdr_decode_buf); @@ -169,8 +169,8 @@ static int rpc_process_reply(struct rpc_context *rpc, struct rpc_pdu *pdu, ZDR * } memset(pdu->zdr_decode_buf, 0, pdu->zdr_decode_bufsize); } - msg.acpted_rply.ar_results.where = pdu->zdr_decode_buf; - msg.acpted_rply.ar_results.proc = pdu->zdr_decode_fn; + msg.body.rbody.reply.areply.reply_data.results.where = pdu->zdr_decode_buf; + msg.body.rbody.reply.areply.reply_data.results.proc = pdu->zdr_decode_fn; if (zdr_replymsg(zdr, &msg) == 0) { rpc_set_error(rpc, "zdr_replymsg failed in portmap_getport_reply"); @@ -181,11 +181,11 @@ static int rpc_process_reply(struct rpc_context *rpc, struct rpc_pdu *pdu, ZDR * } return 0; } - if (msg.rm_reply.rp_stat != MSG_ACCEPTED) { + if (msg.body.rbody.stat != MSG_ACCEPTED) { pdu->cb(rpc, RPC_STATUS_ERROR, "RPC Packet not accepted by the server", pdu->private_data); return 0; } - switch (msg.rm_reply.rp_acpt.ar_stat) { + switch (msg.body.rbody.reply.areply.stat) { case SUCCESS: pdu->cb(rpc, RPC_STATUS_SUCCESS, pdu->zdr_decode_buf, pdu->private_data); break; -- 2.34.1