forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
net/handshake: Create a NETLINK service for handling handshake requests
When a kernel consumer needs a transport layer security session, it first needs a handshake to negotiate and establish a session. This negotiation can be done in user space via one of the several existing library implementations, or it can be done in the kernel. No in-kernel handshake implementations yet exist. In their absence, we add a netlink service that can: a. Notify a user space daemon that a handshake is needed. b. Once notified, the daemon calls the kernel back via this netlink service to get the handshake parameters, including an open socket on which to establish the session. c. Once the handshake is complete, the daemon reports the session status and other information via a second netlink operation. This operation marks that it is safe for the kernel to use the open socket and the security session established there. The notification service uses a multicast group. Each handshake mechanism (eg, tlshd) adopts its own group number so that the handshake services are completely independent of one another. The kernel can then tell via netlink_has_listeners() whether a handshake service is active and prepared to handle a handshake request. A new netlink operation, ACCEPT, acts like accept(2) in that it instantiates a file descriptor in the user space daemon's fd table. If this operation is successful, the reply carries the fd number, which can be treated as an open and ready file descriptor. While user space is performing the handshake, the kernel keeps its muddy paws off the open socket. A second new netlink operation, DONE, indicates that the user space daemon is finished with the socket and it is safe for the kernel to use again. The operation also indicates whether a session was established successfully. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
- Loading branch information
1 parent
2bc42f4
commit 3b3009e
Showing
13 changed files
with
1,211 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
# SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) | ||
# | ||
# Author: Chuck Lever <chuck.lever@oracle.com> | ||
# | ||
# Copyright (c) 2023, Oracle and/or its affiliates. | ||
# | ||
|
||
name: handshake | ||
|
||
protocol: genetlink | ||
|
||
doc: Netlink protocol to request a transport layer security handshake. | ||
|
||
definitions: | ||
- | ||
type: enum | ||
name: handler-class | ||
value-start: 0 | ||
entries: [ none, max ] | ||
- | ||
type: enum | ||
name: msg-type | ||
value-start: 0 | ||
entries: [ unspec, clienthello, serverhello ] | ||
- | ||
type: enum | ||
name: auth | ||
value-start: 0 | ||
entries: [ unspec, unauth, psk, x509 ] | ||
|
||
attribute-sets: | ||
- | ||
name: x509 | ||
attributes: | ||
- | ||
name: cert | ||
type: u32 | ||
- | ||
name: privkey | ||
type: u32 | ||
- | ||
name: accept | ||
attributes: | ||
- | ||
name: sockfd | ||
type: u32 | ||
- | ||
name: handler-class | ||
type: u32 | ||
enum: handler-class | ||
- | ||
name: message-type | ||
type: u32 | ||
enum: msg-type | ||
- | ||
name: timeout | ||
type: u32 | ||
- | ||
name: auth-mode | ||
type: u32 | ||
enum: auth | ||
- | ||
name: peer-identity | ||
type: u32 | ||
multi-attr: true | ||
- | ||
name: certificate | ||
type: nest | ||
nested-attributes: x509 | ||
multi-attr: true | ||
- | ||
name: done | ||
attributes: | ||
- | ||
name: status | ||
type: u32 | ||
- | ||
name: sockfd | ||
type: u32 | ||
- | ||
name: remote-auth | ||
type: u32 | ||
multi-attr: true | ||
|
||
operations: | ||
list: | ||
- | ||
name: ready | ||
doc: Notify handlers that a new handshake request is waiting | ||
notify: accept | ||
- | ||
name: accept | ||
doc: Handler retrieves next queued handshake request | ||
attribute-set: accept | ||
flags: [ admin-perm ] | ||
do: | ||
request: | ||
attributes: | ||
- handler-class | ||
reply: | ||
attributes: | ||
- sockfd | ||
- message-type | ||
- timeout | ||
- auth-mode | ||
- peer-identity | ||
- certificate | ||
- | ||
name: done | ||
doc: Handler reports handshake completion | ||
attribute-set: done | ||
do: | ||
request: | ||
attributes: | ||
- status | ||
- sockfd | ||
- remote-auth | ||
|
||
mcast-groups: | ||
list: | ||
- | ||
name: none |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
/* SPDX-License-Identifier: GPL-2.0 */ | ||
#undef TRACE_SYSTEM | ||
#define TRACE_SYSTEM handshake | ||
|
||
#if !defined(_TRACE_HANDSHAKE_H) || defined(TRACE_HEADER_MULTI_READ) | ||
#define _TRACE_HANDSHAKE_H | ||
|
||
#include <linux/net.h> | ||
#include <linux/tracepoint.h> | ||
|
||
DECLARE_EVENT_CLASS(handshake_event_class, | ||
TP_PROTO( | ||
const struct net *net, | ||
const struct handshake_req *req, | ||
const struct sock *sk | ||
), | ||
TP_ARGS(net, req, sk), | ||
TP_STRUCT__entry( | ||
__field(const void *, req) | ||
__field(const void *, sk) | ||
__field(unsigned int, netns_ino) | ||
), | ||
TP_fast_assign( | ||
__entry->req = req; | ||
__entry->sk = sk; | ||
__entry->netns_ino = net->ns.inum; | ||
), | ||
TP_printk("req=%p sk=%p", | ||
__entry->req, __entry->sk | ||
) | ||
); | ||
#define DEFINE_HANDSHAKE_EVENT(name) \ | ||
DEFINE_EVENT(handshake_event_class, name, \ | ||
TP_PROTO( \ | ||
const struct net *net, \ | ||
const struct handshake_req *req, \ | ||
const struct sock *sk \ | ||
), \ | ||
TP_ARGS(net, req, sk)) | ||
|
||
DECLARE_EVENT_CLASS(handshake_fd_class, | ||
TP_PROTO( | ||
const struct net *net, | ||
const struct handshake_req *req, | ||
const struct sock *sk, | ||
int fd | ||
), | ||
TP_ARGS(net, req, sk, fd), | ||
TP_STRUCT__entry( | ||
__field(const void *, req) | ||
__field(const void *, sk) | ||
__field(int, fd) | ||
__field(unsigned int, netns_ino) | ||
), | ||
TP_fast_assign( | ||
__entry->req = req; | ||
__entry->sk = req->hr_sk; | ||
__entry->fd = fd; | ||
__entry->netns_ino = net->ns.inum; | ||
), | ||
TP_printk("req=%p sk=%p fd=%d", | ||
__entry->req, __entry->sk, __entry->fd | ||
) | ||
); | ||
#define DEFINE_HANDSHAKE_FD_EVENT(name) \ | ||
DEFINE_EVENT(handshake_fd_class, name, \ | ||
TP_PROTO( \ | ||
const struct net *net, \ | ||
const struct handshake_req *req, \ | ||
const struct sock *sk, \ | ||
int fd \ | ||
), \ | ||
TP_ARGS(net, req, sk, fd)) | ||
|
||
DECLARE_EVENT_CLASS(handshake_error_class, | ||
TP_PROTO( | ||
const struct net *net, | ||
const struct handshake_req *req, | ||
const struct sock *sk, | ||
int err | ||
), | ||
TP_ARGS(net, req, sk, err), | ||
TP_STRUCT__entry( | ||
__field(const void *, req) | ||
__field(const void *, sk) | ||
__field(int, err) | ||
__field(unsigned int, netns_ino) | ||
), | ||
TP_fast_assign( | ||
__entry->req = req; | ||
__entry->sk = sk; | ||
__entry->err = err; | ||
__entry->netns_ino = net->ns.inum; | ||
), | ||
TP_printk("req=%p sk=%p err=%d", | ||
__entry->req, __entry->sk, __entry->err | ||
) | ||
); | ||
#define DEFINE_HANDSHAKE_ERROR(name) \ | ||
DEFINE_EVENT(handshake_error_class, name, \ | ||
TP_PROTO( \ | ||
const struct net *net, \ | ||
const struct handshake_req *req, \ | ||
const struct sock *sk, \ | ||
int err \ | ||
), \ | ||
TP_ARGS(net, req, sk, err)) | ||
|
||
|
||
/* | ||
* Request lifetime events | ||
*/ | ||
|
||
DEFINE_HANDSHAKE_EVENT(handshake_submit); | ||
DEFINE_HANDSHAKE_ERROR(handshake_submit_err); | ||
DEFINE_HANDSHAKE_EVENT(handshake_cancel); | ||
DEFINE_HANDSHAKE_EVENT(handshake_cancel_none); | ||
DEFINE_HANDSHAKE_EVENT(handshake_cancel_busy); | ||
DEFINE_HANDSHAKE_EVENT(handshake_destruct); | ||
|
||
|
||
TRACE_EVENT(handshake_complete, | ||
TP_PROTO( | ||
const struct net *net, | ||
const struct handshake_req *req, | ||
const struct sock *sk, | ||
int status | ||
), | ||
TP_ARGS(net, req, sk, status), | ||
TP_STRUCT__entry( | ||
__field(const void *, req) | ||
__field(const void *, sk) | ||
__field(int, status) | ||
__field(unsigned int, netns_ino) | ||
), | ||
TP_fast_assign( | ||
__entry->req = req; | ||
__entry->sk = sk; | ||
__entry->status = status; | ||
__entry->netns_ino = net->ns.inum; | ||
), | ||
TP_printk("req=%p sk=%p status=%d", | ||
__entry->req, __entry->sk, __entry->status | ||
) | ||
); | ||
|
||
/* | ||
* Netlink events | ||
*/ | ||
|
||
DEFINE_HANDSHAKE_ERROR(handshake_notify_err); | ||
DEFINE_HANDSHAKE_FD_EVENT(handshake_cmd_accept); | ||
DEFINE_HANDSHAKE_ERROR(handshake_cmd_accept_err); | ||
DEFINE_HANDSHAKE_FD_EVENT(handshake_cmd_done); | ||
DEFINE_HANDSHAKE_ERROR(handshake_cmd_done_err); | ||
|
||
#endif /* _TRACE_HANDSHAKE_H */ | ||
|
||
#include <trace/define_trace.h> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */ | ||
/* Do not edit directly, auto-generated from: */ | ||
/* Documentation/netlink/specs/handshake.yaml */ | ||
/* YNL-GEN uapi header */ | ||
|
||
#ifndef _UAPI_LINUX_HANDSHAKE_H | ||
#define _UAPI_LINUX_HANDSHAKE_H | ||
|
||
#define HANDSHAKE_FAMILY_NAME "handshake" | ||
#define HANDSHAKE_FAMILY_VERSION 1 | ||
|
||
enum handshake_handler_class { | ||
HANDSHAKE_HANDLER_CLASS_NONE, | ||
HANDSHAKE_HANDLER_CLASS_MAX, | ||
}; | ||
|
||
enum handshake_msg_type { | ||
HANDSHAKE_MSG_TYPE_UNSPEC, | ||
HANDSHAKE_MSG_TYPE_CLIENTHELLO, | ||
HANDSHAKE_MSG_TYPE_SERVERHELLO, | ||
}; | ||
|
||
enum handshake_auth { | ||
HANDSHAKE_AUTH_UNSPEC, | ||
HANDSHAKE_AUTH_UNAUTH, | ||
HANDSHAKE_AUTH_PSK, | ||
HANDSHAKE_AUTH_X509, | ||
}; | ||
|
||
enum { | ||
HANDSHAKE_A_X509_CERT = 1, | ||
HANDSHAKE_A_X509_PRIVKEY, | ||
|
||
__HANDSHAKE_A_X509_MAX, | ||
HANDSHAKE_A_X509_MAX = (__HANDSHAKE_A_X509_MAX - 1) | ||
}; | ||
|
||
enum { | ||
HANDSHAKE_A_ACCEPT_SOCKFD = 1, | ||
HANDSHAKE_A_ACCEPT_HANDLER_CLASS, | ||
HANDSHAKE_A_ACCEPT_MESSAGE_TYPE, | ||
HANDSHAKE_A_ACCEPT_TIMEOUT, | ||
HANDSHAKE_A_ACCEPT_AUTH_MODE, | ||
HANDSHAKE_A_ACCEPT_PEER_IDENTITY, | ||
HANDSHAKE_A_ACCEPT_CERTIFICATE, | ||
|
||
__HANDSHAKE_A_ACCEPT_MAX, | ||
HANDSHAKE_A_ACCEPT_MAX = (__HANDSHAKE_A_ACCEPT_MAX - 1) | ||
}; | ||
|
||
enum { | ||
HANDSHAKE_A_DONE_STATUS = 1, | ||
HANDSHAKE_A_DONE_SOCKFD, | ||
HANDSHAKE_A_DONE_REMOTE_AUTH, | ||
|
||
__HANDSHAKE_A_DONE_MAX, | ||
HANDSHAKE_A_DONE_MAX = (__HANDSHAKE_A_DONE_MAX - 1) | ||
}; | ||
|
||
enum { | ||
HANDSHAKE_CMD_READY = 1, | ||
HANDSHAKE_CMD_ACCEPT, | ||
HANDSHAKE_CMD_DONE, | ||
|
||
__HANDSHAKE_CMD_MAX, | ||
HANDSHAKE_CMD_MAX = (__HANDSHAKE_CMD_MAX - 1) | ||
}; | ||
|
||
#define HANDSHAKE_MCGRP_NONE "none" | ||
|
||
#endif /* _UAPI_LINUX_HANDSHAKE_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# SPDX-License-Identifier: GPL-2.0-only | ||
# | ||
# Makefile for the Generic HANDSHAKE service | ||
# | ||
# Author: Chuck Lever <chuck.lever@oracle.com> | ||
# | ||
# Copyright (c) 2023, Oracle and/or its affiliates. | ||
# | ||
|
||
obj-y += handshake.o | ||
handshake-y := genl.o netlink.o request.o trace.o |
Oops, something went wrong.