summaryrefslogtreecommitdiffstats
path: root/src/lib
diff options
context:
space:
mode:
authorBarry Jaspan <bjaspan@mit.edu>1996-12-04 17:47:19 +0000
committerBarry Jaspan <bjaspan@mit.edu>1996-12-04 17:47:19 +0000
commit7b1defb77eb5450be7d4cf48221d1d6e05fd9065 (patch)
tree61cf8721f35404ffab35be4f0c5fa53794d46fac /src/lib
parent37f94362d977e2af27a5ecd0f2a921c53edab9ac (diff)
downloadkrb5-7b1defb77eb5450be7d4cf48221d1d6e05fd9065.tar.gz
krb5-7b1defb77eb5450be7d4cf48221d1d6e05fd9065.tar.xz
krb5-7b1defb77eb5450be7d4cf48221d1d6e05fd9065.zip
* 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
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/rpc/ChangeLog21
-rw-r--r--src/lib/rpc/auth_gssapi.c5
-rw-r--r--src/lib/rpc/clnt_udp.c19
-rw-r--r--src/lib/rpc/svc.h2
-rw-r--r--src/lib/rpc/svc_auth_gssapi.c35
-rw-r--r--src/lib/rpc/svc_tcp.c13
-rw-r--r--src/lib/rpc/svc_udp.c12
7 files changed, 82 insertions, 25 deletions
diff --git a/src/lib/rpc/ChangeLog b/src/lib/rpc/ChangeLog
index b4e0eb723a..1f815211b1 100644
--- a/src/lib/rpc/ChangeLog
+++ b/src/lib/rpc/ChangeLog
@@ -1,3 +1,24 @@
+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
diff --git a/src/lib/rpc/auth_gssapi.c b/src/lib/rpc/auth_gssapi.c
index 7d51d3dce6..455856cc25 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 6a5cf5f114..9e1d563af3 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 2114d6249e..8059573830 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 1e204e0e33..20bf95a741 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 e20a29b192..fe9b87fa6a 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 d44c7f5d88..142293facd 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));