From 7b1defb77eb5450be7d4cf48221d1d6e05fd9065 Mon Sep 17 00:00:00 2001 From: Barry Jaspan Date: Wed, 4 Dec 1996 17:47:19 +0000 Subject: * Various changes to allow channel bindings to work with both UDP and TCP cleanly [krb5-libs/180]: * auth_gssapi.c: remove the special-case exception to channel bindings failure added in the previous revision, since we now solve the problem by making channel bindings not fail * clnt_udp.c: use a connected socket so that the client can determine its own source address with getsockname * svc.h: add xp_laddr and xp_laddrlen fields to SVCXPRT structure * svc_tcp.c: set xp_laddr and xp_laddrlen when a connection is established * svc_udp.c (svcudp_recv): use recvmsg with MSG_PEEK followed by recvfrom in order to determine both source and dest address on unconnected UDP socket, set xp_laddr and xp_laddrlen git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@9600 dc483132-0cff-0310-8789-dd5450dbe970 --- src/lib/rpc/ChangeLog | 21 +++++++++++++++++++++ src/lib/rpc/auth_gssapi.c | 5 ----- src/lib/rpc/clnt_udp.c | 19 +++++++++++-------- src/lib/rpc/svc.h | 2 ++ src/lib/rpc/svc_auth_gssapi.c | 35 ++++++++++++++++++++++++++--------- src/lib/rpc/svc_tcp.c | 13 ++++++++++--- src/lib/rpc/svc_udp.c | 12 ++++++++++++ 7 files changed, 82 insertions(+), 25 deletions(-) (limited to 'src/lib/rpc') diff --git a/src/lib/rpc/ChangeLog b/src/lib/rpc/ChangeLog index b4e0eb7..1f81521 100644 --- a/src/lib/rpc/ChangeLog +++ b/src/lib/rpc/ChangeLog @@ -1,3 +1,24 @@ +Wed Dec 4 12:42:49 1996 Barry Jaspan + + * Various changes to allow channel bindings to work with both UDP + and TCP cleanly [krb5-libs/180]: + + * auth_gssapi.c: remove the special-case exception to channel + bindings failure added in the previous revision, since we now + solve the problem by making channel bindings not fail + + * clnt_udp.c: use a connected socket so that the client can + determine its own source address with getsockname + + * svc.h: add xp_laddr and xp_laddrlen fields to SVCXPRT structure + + * svc_tcp.c: set xp_laddr and xp_laddrlen when a connection is + established + + * svc_udp.c (svcudp_recv): use recvmsg with MSG_PEEK followed by + recvfrom in order to determine both source and dest address on + unconnected UDP socket, set xp_laddr and xp_laddrlen + Tue Nov 12 16:27:27 1996 Barry Jaspan * auth_gssapi.c (auth_gssapi_create): handle channel bindings diff --git a/src/lib/rpc/auth_gssapi.c b/src/lib/rpc/auth_gssapi.c index 7d51d3d..455856c 100644 --- a/src/lib/rpc/auth_gssapi.c +++ b/src/lib/rpc/auth_gssapi.c @@ -338,11 +338,6 @@ next_token: AUTH_GSSAPI_DISPLAY_STATUS(("in response from server", call_res.gss_major, call_res.gss_minor)); - if (GSS_ERROR(call_res.gss_major) == GSS_S_BAD_BINDINGS - && call_arg.version > 2) { - call_arg.version = 2; - goto try_new_version; - } goto cleanup; } diff --git a/src/lib/rpc/clnt_udp.c b/src/lib/rpc/clnt_udp.c index 6a5cf5f..9e1d563 100644 --- a/src/lib/rpc/clnt_udp.c +++ b/src/lib/rpc/clnt_udp.c @@ -77,6 +77,8 @@ struct cu_data { bool_t cu_closeit; struct sockaddr_in cu_raddr; int cu_rlen; + struct sockaddr_in cu_laddr; + int cu_llen; struct timeval cu_wait; struct timeval cu_total; struct rpc_err cu_error; @@ -183,6 +185,12 @@ clntudp_bufcreate(raddr, program, version, wait, sockp, sendsz, recvsz) } else { cu->cu_closeit = FALSE; } + if (connect(*sockp, raddr, sizeof(*raddr)) < 0) + goto fooy; + cu->cu_llen = sizeof(cu->cu_laddr); + if (getsockname(*sockp, &cu->cu_laddr, &cu->cu_llen) < 0) + goto fooy; + cu->cu_sock = *sockp; cl->cl_auth = authnone_create(); return (cl); @@ -261,9 +269,7 @@ call_again: outlen = (int)XDR_GETPOS(xdrs); send_again: - if (sendto(cu->cu_sock, cu->cu_outbuf, outlen, 0, - (struct sockaddr *)&(cu->cu_raddr), cu->cu_rlen) - != outlen) { + if (send(cu->cu_sock, cu->cu_outbuf, outlen, 0) != outlen) { cu->cu_error.re_errno = errno; return (cu->cu_error.re_status = RPC_CANTSEND); } @@ -434,11 +440,8 @@ clntudp_control(cl, request, info) *(struct sockaddr_in *)info = cu->cu_raddr; break; case CLGET_LOCAL_ADDR: - len = sizeof(struct sockaddr); - if (getsockname(cu->cu_sock, (struct sockaddr*)info, &len) < 0) - return FALSE; - else - return TRUE; + *(struct sockaddr_in *)info = cu->cu_laddr; + break; default: return (FALSE); } diff --git a/src/lib/rpc/svc.h b/src/lib/rpc/svc.h index 2114d62..8059573 100644 --- a/src/lib/rpc/svc.h +++ b/src/lib/rpc/svc.h @@ -85,6 +85,8 @@ typedef struct { SVCAUTH *xp_auth; /* auth flavor of current req */ caddr_t xp_p1; /* private */ caddr_t xp_p2; /* private */ + int xp_laddrlen; /* lenght of local address */ + struct sockaddr_in xp_laddr; /* local address */ } SVCXPRT; /* diff --git a/src/lib/rpc/svc_auth_gssapi.c b/src/lib/rpc/svc_auth_gssapi.c index 1e204e0..20bf95a 100644 --- a/src/lib/rpc/svc_auth_gssapi.c +++ b/src/lib/rpc/svc_auth_gssapi.c @@ -5,6 +5,26 @@ * $Source$ * * $Log$ + * Revision 1.42 1996/12/04 17:47:18 bjaspan + * * Various changes to allow channel bindings to work with both UDP + * and TCP cleanly [krb5-libs/180]: + * + * * auth_gssapi.c: remove the special-case exception to channel + * bindings failure added in the previous revision, since we now + * solve the problem by making channel bindings not fail + * + * * clnt_udp.c: use a connected socket so that the client can + * determine its own source address with getsockname + * + * * svc.h: add xp_laddr and xp_laddrlen fields to SVCXPRT structure + * + * * svc_tcp.c: set xp_laddr and xp_laddrlen when a connection is + * established + * + * * svc_udp.c (svcudp_recv): use recvmsg with MSG_PEEK followed by + * recvfrom in order to determine both source and dest address on + * unconnected UDP socket, set xp_laddr and xp_laddrlen + * * Revision 1.41 1996/10/16 20:16:10 bjaspan * * svc_auth_gssapi.c (_svcauth_gssapi): accept add call_arg version 4 * @@ -310,7 +330,6 @@ enum auth_stat _svcauth_gssapi(rqst, msg, no_dispatch) gss_buffer_desc output_token, in_buf, out_buf; gss_cred_id_t server_creds; struct gss_channel_bindings_struct bindings, *bindp; - struct sockaddr_in sockname; OM_uint32 gssstat, minor_stat, time_rec; struct opaque_auth *cred, *verf; svc_auth_gssapi_data *client_data; @@ -497,19 +516,17 @@ enum auth_stat _svcauth_gssapi(rqst, msg, no_dispatch) bindings.initiator_address.value = &svc_getcaller(rqst->rq_xprt)->sin_addr.s_addr; - len = sizeof(sockname); - if (getsockname(rqst->rq_xprt->xp_sock, - (struct sockaddr *) &sockname, &len) < 0) { + if (rqst->rq_xprt->xp_laddrlen > 0) { + bindings.acceptor_addrtype = GSS_C_AF_INET; + bindings.acceptor_address.length = 4; + bindings.acceptor_address.value = + &rqst->rq_xprt->xp_laddr.sin_addr.s_addr; + } else { LOG_MISCERR("cannot get local address"); - PRINTF(("svcauth_gssapi: errno %d while getting address", - errno)); ret = AUTH_FAILED; goto error; } - bindings.acceptor_addrtype = GSS_C_AF_INET; - bindings.acceptor_address.length = 4; - bindings.acceptor_address.value = &sockname.sin_addr.s_addr; bindp = &bindings; } else { diff --git a/src/lib/rpc/svc_tcp.c b/src/lib/rpc/svc_tcp.c index e20a29b..fe9b87f 100644 --- a/src/lib/rpc/svc_tcp.c +++ b/src/lib/rpc/svc_tcp.c @@ -174,6 +174,7 @@ svctcp_create(sock, sendsize, recvsize) xprt->xp_ops = &svctcp_rendezvous_op; xprt->xp_port = ntohs(addr.sin_port); xprt->xp_sock = sock; + xprt->xp_laddrlen = 0; xprt_register(xprt); return (xprt); } @@ -220,6 +221,7 @@ makefd_xprt(fd, sendsize, recvsize) xprt->xp_p1 = (caddr_t)cd; xprt->xp_verf.oa_base = cd->verf_body; xprt->xp_addrlen = 0; + xprt->xp_laddrlen = 0; xprt->xp_ops = &svctcp_op; /* truely deals with calls */ xprt->xp_port = 0; /* this is a connection, not a rendezvouser */ xprt->xp_sock = fd; @@ -234,24 +236,29 @@ rendezvous_request(xprt) { int sock; struct tcp_rendezvous *r; - struct sockaddr_in addr; - int len; + struct sockaddr_in addr, laddr; + int len, llen; r = (struct tcp_rendezvous *)xprt->xp_p1; again: - len = sizeof(struct sockaddr_in); + len = llen = sizeof(struct sockaddr_in); if ((sock = accept(xprt->xp_sock, (struct sockaddr *)&addr, &len)) < 0) { if (errno == EINTR) goto again; return (FALSE); } + if (getsockname(sock, &laddr, &llen) < 0) + return (FALSE); + /* * make a new transporter (re-uses xprt) */ xprt = makefd_xprt(sock, r->sendsize, r->recvsize); xprt->xp_raddr = addr; xprt->xp_addrlen = len; + xprt->xp_laddr = laddr; + xprt->xp_laddrlen = llen; return (FALSE); /* there is never an rpc msg to be processed */ } diff --git a/src/lib/rpc/svc_udp.c b/src/lib/rpc/svc_udp.c index d44c7f5..142293f 100644 --- a/src/lib/rpc/svc_udp.c +++ b/src/lib/rpc/svc_udp.c @@ -174,6 +174,7 @@ svcudp_recv(xprt, msg) register SVCXPRT *xprt; struct rpc_msg *msg; { + struct msghdr dummy; register struct svcudp_data *su = su_data(xprt); register XDR *xdrs = &(su->su_xdrs); register int rlen; @@ -181,6 +182,17 @@ svcudp_recv(xprt, msg) rpc_u_int32 replylen; again: + memset((char *) &dummy, 0, sizeof(dummy)); + dummy.msg_namelen = xprt->xp_laddrlen = sizeof(struct sockaddr_in); + dummy.msg_name = (char *) &xprt->xp_laddr; + rlen = recvmsg(xprt->xp_sock, &dummy, MSG_PEEK); + if (rlen == -1) { + if (errno == EINTR) + goto again; + else + return (FALSE); + } + xprt->xp_addrlen = sizeof(struct sockaddr_in); rlen = recvfrom(xprt->xp_sock, rpc_buffer(xprt), (int) su->su_iosz, 0, (struct sockaddr *)&(xprt->xp_raddr), &(xprt->xp_addrlen)); -- cgit v1.1