Commit 41057ebd authored by David Howells's avatar David Howells

rxrpc: Support keys with multiple authentication tokens

rxrpc-type keys can have multiple tokens attached for different security
classes.  Currently, rxrpc always picks the first one, whether or not the
security class it indicates is supported.

Add preliminary support for choosing which security class will be used
(this will need to be directed from a higher layer) and go through the
tokens to find one that's supported.
Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
parent 0727d3ec
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <net/netns/generic.h> #include <net/netns/generic.h>
#include <net/sock.h> #include <net/sock.h>
#include <net/af_rxrpc.h> #include <net/af_rxrpc.h>
#include <keys/rxrpc-type.h>
#include "protocol.h" #include "protocol.h"
#if 0 #if 0
...@@ -217,7 +218,8 @@ struct rxrpc_security { ...@@ -217,7 +218,8 @@ struct rxrpc_security {
void (*exit)(void); void (*exit)(void);
/* initialise a connection's security */ /* initialise a connection's security */
int (*init_connection_security)(struct rxrpc_connection *); int (*init_connection_security)(struct rxrpc_connection *,
struct rxrpc_key_token *);
/* prime a connection's packet security */ /* prime a connection's packet security */
int (*prime_packet_security)(struct rxrpc_connection *); int (*prime_packet_security)(struct rxrpc_connection *);
......
...@@ -333,7 +333,8 @@ static int rxrpc_process_event(struct rxrpc_connection *conn, ...@@ -333,7 +333,8 @@ static int rxrpc_process_event(struct rxrpc_connection *conn,
if (ret < 0) if (ret < 0)
return ret; return ret;
ret = conn->security->init_connection_security(conn); ret = conn->security->init_connection_security(
conn, conn->params.key->payload.data[0]);
if (ret < 0) if (ret < 0)
return ret; return ret;
......
...@@ -8,7 +8,8 @@ ...@@ -8,7 +8,8 @@
#include <net/af_rxrpc.h> #include <net/af_rxrpc.h>
#include "ar-internal.h" #include "ar-internal.h"
static int none_init_connection_security(struct rxrpc_connection *conn) static int none_init_connection_security(struct rxrpc_connection *conn,
struct rxrpc_key_token *token)
{ {
return 0; return 0;
} }
......
...@@ -49,15 +49,14 @@ static DEFINE_MUTEX(rxkad_ci_mutex); ...@@ -49,15 +49,14 @@ static DEFINE_MUTEX(rxkad_ci_mutex);
/* /*
* initialise connection security * initialise connection security
*/ */
static int rxkad_init_connection_security(struct rxrpc_connection *conn) static int rxkad_init_connection_security(struct rxrpc_connection *conn,
struct rxrpc_key_token *token)
{ {
struct crypto_sync_skcipher *ci; struct crypto_sync_skcipher *ci;
struct rxrpc_key_token *token;
int ret; int ret;
_enter("{%d},{%x}", conn->debug_id, key_serial(conn->params.key)); _enter("{%d},{%x}", conn->debug_id, key_serial(conn->params.key));
token = conn->params.key->payload.data[0];
conn->security_ix = token->security_index; conn->security_ix = token->security_index;
ci = crypto_alloc_sync_skcipher("pcbc(fcrypt)", 0, 0); ci = crypto_alloc_sync_skcipher("pcbc(fcrypt)", 0, 0);
......
...@@ -81,16 +81,17 @@ int rxrpc_init_client_conn_security(struct rxrpc_connection *conn) ...@@ -81,16 +81,17 @@ int rxrpc_init_client_conn_security(struct rxrpc_connection *conn)
if (ret < 0) if (ret < 0)
return ret; return ret;
token = key->payload.data[0]; for (token = key->payload.data[0]; token; token = token->next) {
if (!token)
return -EKEYREJECTED;
sec = rxrpc_security_lookup(token->security_index); sec = rxrpc_security_lookup(token->security_index);
if (!sec) if (sec)
goto found;
}
return -EKEYREJECTED; return -EKEYREJECTED;
found:
conn->security = sec; conn->security = sec;
ret = conn->security->init_connection_security(conn); ret = conn->security->init_connection_security(conn, token);
if (ret < 0) { if (ret < 0) {
conn->security = &rxrpc_no_security; conn->security = &rxrpc_no_security;
return ret; return ret;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment