ab0c29af05
An internet draft titled "Towards Remote Procedure Call Encryption By Default" describes how TLS is to be used for Sun RPC, with NFS as an intended use case. This patch adds client and server support for this to the kernel RPC, using KERN_TLS and upcalls to daemons for the handshake, peer reset and other non-application data record cases. The upcalls to the daemons use three fields to uniquely identify the TCP connection. They are the time.tv_sec, time.tv_usec of the connection establshment, plus a 64bit sequence number. The time fields avoid problems with re-use of the sequence number after a daemon restart. For the server side, once a Null RPC with AUTH_TLS is received, kernel reception on the socket is blocked and an upcall to the rpctlssd(8) daemon is done to perform the TLS handshake. Upon completion, the completion status of the handshake is stored in xp_tls as flag bits and the reply to the Null RPC is sent. For the client, if CLSET_TLS has been set, a new TCP connection will send the Null RPC with AUTH_TLS to initiate the handshake. The client kernel RPC code will then block kernel I/O on the socket and do an upcall to the rpctlscd(8) daemon to perform the handshake. If the upcall is successful, ct_rcvstate will be maintained to indicate if/when an upcall is being done. If non-application data records are received, the code does an upcall to the appropriate daemon, which will do a SSL_read() of 0 length to handle the record(s). When the socket is being shut down, upcalls are done to the daemons, so that they can perform SSL_shutdown() calls to perform the "peer reset". The rpctlssd(8) and rpctlscd(8) daemons require a patched version of the openssl library and, as such, will not be committed to head at this time. Although the changes done by this patch are fairly numerous, there should be no semantics change to the kernel RPC at this time. A future commit to the NFS code will optionally enable use of TLS for NFS.
88 lines
3.2 KiB
C
88 lines
3.2 KiB
C
/*-
|
|
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
|
|
*
|
|
* Copyright (c) 2020 Rick Macklem
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
* SUCH DAMAGE.
|
|
*
|
|
* $FreeBSD$
|
|
*/
|
|
|
|
#ifndef _RPC_RPCSEC_TLS_H_
|
|
#define _RPC_RPCSEC_TLS_H_
|
|
|
|
/* Operation values for rpctls syscall. */
|
|
#define RPCTLS_SYSC_CLSETPATH 1
|
|
#define RPCTLS_SYSC_CLSOCKET 2
|
|
#define RPCTLS_SYSC_CLSHUTDOWN 3
|
|
#define RPCTLS_SYSC_SRVSETPATH 4
|
|
#define RPCTLS_SYSC_SRVSOCKET 5
|
|
#define RPCTLS_SYSC_SRVSHUTDOWN 6
|
|
|
|
/* System call used by the rpctlscd, rpctlssd daemons. */
|
|
int rpctls_syscall(int, const char *);
|
|
|
|
/* Flag bits to indicate certificate results. */
|
|
#define RPCTLS_FLAGS_HANDSHAKE 0x01
|
|
#define RPCTLS_FLAGS_GOTCERT 0x02
|
|
#define RPCTLS_FLAGS_SELFSIGNED 0x04
|
|
#define RPCTLS_FLAGS_VERIFIED 0x08
|
|
#define RPCTLS_FLAGS_DISABLED 0x10
|
|
#define RPCTLS_FLAGS_CERTUSER 0x20
|
|
#define RPCTLS_FLAGS_HANDSHFAIL 0x40
|
|
|
|
/* Error return values for upcall rpcs. */
|
|
#define RPCTLSERR_OK 0
|
|
#define RPCTLSERR_NOCLOSE 1
|
|
#define RPCTLSERR_NOSSL 2
|
|
#define RPCTLSERR_NOSOCKET 3
|
|
|
|
#ifdef _KERNEL
|
|
/* Functions that perform upcalls to the rpctlsd daemon. */
|
|
enum clnt_stat rpctls_connect(CLIENT *newclient, struct socket *so,
|
|
uint64_t *sslp, uint32_t *reterr);
|
|
enum clnt_stat rpctls_cl_handlerecord(uint64_t sec, uint64_t usec,
|
|
uint64_t ssl, uint32_t *reterr);
|
|
enum clnt_stat rpctls_srv_handlerecord(uint64_t sec, uint64_t usec,
|
|
uint64_t ssl, uint32_t *reterr);
|
|
enum clnt_stat rpctls_cl_disconnect(uint64_t sec, uint64_t usec,
|
|
uint64_t ssl, uint32_t *reterr);
|
|
enum clnt_stat rpctls_srv_disconnect(uint64_t sec, uint64_t usec,
|
|
uint64_t ssl, uint32_t *reterr);
|
|
|
|
/* Initialization function for rpcsec_tls. */
|
|
int rpctls_init(void);
|
|
|
|
/* Get TLS information function. */
|
|
bool rpctls_getinfo(u_int *maxlen, bool rpctlscd_run,
|
|
bool rpctlssd_run);
|
|
|
|
/* String for AUTH_TLS reply verifier. */
|
|
#define RPCTLS_START_STRING "STARTTLS"
|
|
|
|
/* ssl refno value to indicate TLS handshake being done. */
|
|
#define RPCTLS_REFNO_HANDSHAKE 0xFFFFFFFFFFFFFFFFULL
|
|
|
|
#endif /* _KERNEL */
|
|
|
|
#endif /* _RPC_RPCSEC_TLS_H_ */
|