From bjaspan@MIT.EDU Tue Nov 12 16:19:23 1996 Received: from MIT.EDU (SOUTH-STATION-ANNEX.MIT.EDU [18.72.1.2]) by rt-11.MIT.EDU (8.7.5/8.7.3) with SMTP id QAA28223 for ; Tue, 12 Nov 1996 16:19:23 -0500 Received: from BEEBLEBROX.MIT.EDU by MIT.EDU with SMTP id AA25663; Tue, 12 Nov 96 16:19:12 EST Received: by beeblebrox.MIT.EDU (940816.SGI.8.6.9/4.7) id VAA15465; Tue, 12 Nov 1996 21:18:20 GMT Message-Id: <199611122118.VAA15465@beeblebrox.MIT.EDU> Date: Tue, 12 Nov 1996 21:18:20 GMT From: bjaspan@MIT.EDU Reply-To: bjaspan@MIT.EDU To: krb5-bugs@MIT.EDU Subject: GSS-RPC, channel bindings, and UDP X-Send-Pr-Version: 3.99 >Number: 180 >Category: krb5-libs >Synopsis: GSS-RPC, channel bindings, and UDP >Confidential: no >Severity: serious >Priority: medium >Responsible: krb5-unassigned >State: closed >Class: sw-bug >Submitter-Id: unknown >Arrival-Date: Tue Nov 12 16:20:00 EST 1996 >Last-Modified: Wed Dec 04 12:48:01 EST 1996 >Originator: Barry Jaspan >Organization: mit >Release: 1.0-development >Environment: System: IRIX beeblebrox 5.3 11091812 IP22 mips >Description: The GSS-RPC uses channel bindings when its internal protocol is version 3 or higher. Channel bindings work by having the client and server specify the source and destination address of the context initiation tokens and then having the libraries verify a checksum of that data in each token. For TCP, GSS-RPC uses getsockname() and getpeername() to determine the correct addresses. For UDP, this doesn't work: the socket is unconnected on the server side, so getsockname() returns a zero address. The recvmsg() syscall returns the dest address of a packet, but unlike recvfrom does *not* return the source address. Thus, the only way for the server to get the destination address of the packet is to open a separate UDP socket bound to each of the machine's local addresses. This is not a change I want to make before the 1.0 release. My temporary workaround is to have the client fall back from versions greater than 2 to version 2 when the server returns a "bad channel bindings error." This works because the server-side RPC layer is still happy to accept the old (pre-bindings) version. I am also going to enhance the rpc unit tests to run both on TCP and UDP so we make sure this behavior continues to work. >How-To-Repeat: >Fix: >Audit-Trail: From: "Barry Jaspan" To: bjaspan@MIT.EDU Cc: krb5-bugs@MIT.EDU Subject: Re: krb5-libs/180: GSS-RPC, channel bindings, and UDP Date: Tue, 12 Nov 1996 21:31:57 GMT I have implemented the temporary workaround and unit tests for UDP. We'll get back to this after 1.0. Files: lib/rpc/ChangeLog lib/rpc/auth_gssapi.c lib/rpc/unit-test/ChangeLog From: "Barry Jaspan" To: Unassigned Problem Report Cc: krb5-bugs@MIT.EDU Subject: Re: krb5-libs/180: GSS-RPC, channel bindings, and UDP Date: Tue, 12 Nov 1996 21:32:08 GMT `Barry Jaspan' made changes to this PR. *** /tmp/gnatsa0038s Tue Nov 12 16:30:39 1996 --- /tmp/gnatsb0038s Tue Nov 12 16:32:05 1996 *************** *** 50,56 **** addresses. This is not a change I want to make before the 1.0 release. ! My temporary workaround is to have the client fall back from version >How-To-Repeat: >Fix: --- 50,63 ---- addresses. This is not a change I want to make before the 1.0 release. ! My temporary workaround is to have the client fall back from versions ! greater than 2 to version 2 when the server returns a "bad channel ! bindings error." This works because the server-side RPC layer is ! still happy to accept the old (pre-bindings) version. ! ! I am also going to enhance the rpc unit tests to run both on TCP and ! UDP so we make sure this behavior continues to work. ! >How-To-Repeat: >Fix: *************** *** 57,66 **** >Audit-Trail: >Unformatted: - >=3 to version 2 when the server returns a "bad channel bindings - error." This works because the server-side RPC layer is still happy - to accept the old (pre-bindings) version. - - I am also going to enhance the rpc unit tests to run both on TCP and - UDP so we make sure this behavior continues to work. --- 64,67 ---- From: "Barry Jaspan" To: bjaspan@MIT.EDU Cc: krb5-bugs@MIT.EDU Subject: Re: krb5-libs/180: GSS-RPC, channel bindings, and UDP Date: Tue, 3 Dec 1996 23:26:35 GMT I just made the next approximation to a correct solution. I made the server-side UDP transport use recvmsg() with MSG_PEEK to get the desination address and recvfrom() to get the source address. Then it also turned out that the client could not get its own address with an unconnected UDP socket, so I made the client connect the socket and use send() instead of sendto() for all messages. This could conceivably break an existing ONC-RPC client program that assumes the UDP layer does not connect the socket, but clients shouldn't make that assumption. The solution could be implemented more cleanly. First, the code now allows transport layers to specify the destination address of packets via the xprt structure (xp_laddr and xp_laddrlen) or, if xp_laddrlen is 0, the dispatch layer must use getsockname itself. Probably the TCP transport should be made to use xp_laddr so that the dispatch layer can always count on it. Second, since the client UDP side is using a connected socket, the server UDP side could too, and that would eliminate the need to use the recvmsg/recvfrom hack. But, not tonight. State-Changed-From-To: open-closed State-Changed-By: bjaspan State-Changed-When: Wed Dec 4 12:47:22 1996 State-Changed-Why: Fixed. Files: lib/rpc/ChangeLog lib/rpc/auth_gssapi.c lib/rpc/clnt_udp.c lib/rpc/svc.h lib/rpc/svc_tcp.c lib/rpc/svc_udp.c From: "Barry Jaspan" To: bjaspan@MIT.EDU Cc: krb5-bugs@MIT.EDU Subject: Re: krb5-libs/180: GSS-RPC, channel bindings, and UDP Date: Wed, 4 Dec 1996 17:42:22 GMT I fixed the TCP server-side layer to set xp_laddr and xp_laddrlen when appropriate (in the connection xprt, not the rendezvous xprt), so now the dispatch layer always gets the local address of the packet from those fields, and never calls getsockname itself. This is a cleaner solution. I was wrong yesterday when I said the server-side UDP layer could use a connected socket to avoid having to use recvmsg with MSG_PEEK and recvfrom. The server-side UDP layer needs to use an unconnected socket so that it can receive and respond to UDP packets from anywhere. This corresponds to the fact that the TCP rendezvous socket is not connected, so it can accept() a connection from wherewhere. In short, I belive the current code is as good as I can make it. >Unformatted: