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
+Wed Dec 4 12:42:49 1996 Barry Jaspan <bjaspan@mit.edu>
+
+ * 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 <bjaspan@mit.edu>
* auth_gssapi.c (auth_gssapi_create): handle channel bindings
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;
}
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;
} 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);
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);
}
*(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);
}
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;
/*
* $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
*
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;
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 {
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);
}
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;
{
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 */
}
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;
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));