root/net/rxrpc/security.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. rxrpc_init_security
  2. rxrpc_exit_security
  3. rxrpc_security_lookup
  4. rxrpc_init_client_conn_security
  5. rxrpc_look_up_server_security

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /* RxRPC security handling
   3  *
   4  * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
   5  * Written by David Howells (dhowells@redhat.com)
   6  */
   7 
   8 #include <linux/module.h>
   9 #include <linux/net.h>
  10 #include <linux/skbuff.h>
  11 #include <linux/udp.h>
  12 #include <linux/crypto.h>
  13 #include <net/sock.h>
  14 #include <net/af_rxrpc.h>
  15 #include <keys/rxrpc-type.h>
  16 #include "ar-internal.h"
  17 
  18 static const struct rxrpc_security *rxrpc_security_types[] = {
  19         [RXRPC_SECURITY_NONE]   = &rxrpc_no_security,
  20 #ifdef CONFIG_RXKAD
  21         [RXRPC_SECURITY_RXKAD]  = &rxkad,
  22 #endif
  23 };
  24 
  25 int __init rxrpc_init_security(void)
  26 {
  27         int i, ret;
  28 
  29         for (i = 0; i < ARRAY_SIZE(rxrpc_security_types); i++) {
  30                 if (rxrpc_security_types[i]) {
  31                         ret = rxrpc_security_types[i]->init();
  32                         if (ret < 0)
  33                                 goto failed;
  34                 }
  35         }
  36 
  37         return 0;
  38 
  39 failed:
  40         for (i--; i >= 0; i--)
  41                 if (rxrpc_security_types[i])
  42                         rxrpc_security_types[i]->exit();
  43         return ret;
  44 }
  45 
  46 void rxrpc_exit_security(void)
  47 {
  48         int i;
  49 
  50         for (i = 0; i < ARRAY_SIZE(rxrpc_security_types); i++)
  51                 if (rxrpc_security_types[i])
  52                         rxrpc_security_types[i]->exit();
  53 }
  54 
  55 /*
  56  * look up an rxrpc security module
  57  */
  58 static const struct rxrpc_security *rxrpc_security_lookup(u8 security_index)
  59 {
  60         if (security_index >= ARRAY_SIZE(rxrpc_security_types))
  61                 return NULL;
  62         return rxrpc_security_types[security_index];
  63 }
  64 
  65 /*
  66  * initialise the security on a client connection
  67  */
  68 int rxrpc_init_client_conn_security(struct rxrpc_connection *conn)
  69 {
  70         const struct rxrpc_security *sec;
  71         struct rxrpc_key_token *token;
  72         struct key *key = conn->params.key;
  73         int ret;
  74 
  75         _enter("{%d},{%x}", conn->debug_id, key_serial(key));
  76 
  77         if (!key)
  78                 return 0;
  79 
  80         ret = key_validate(key);
  81         if (ret < 0)
  82                 return ret;
  83 
  84         token = key->payload.data[0];
  85         if (!token)
  86                 return -EKEYREJECTED;
  87 
  88         sec = rxrpc_security_lookup(token->security_index);
  89         if (!sec)
  90                 return -EKEYREJECTED;
  91         conn->security = sec;
  92 
  93         ret = conn->security->init_connection_security(conn);
  94         if (ret < 0) {
  95                 conn->security = &rxrpc_no_security;
  96                 return ret;
  97         }
  98 
  99         _leave(" = 0");
 100         return 0;
 101 }
 102 
 103 /*
 104  * Find the security key for a server connection.
 105  */
 106 bool rxrpc_look_up_server_security(struct rxrpc_local *local, struct rxrpc_sock *rx,
 107                                    const struct rxrpc_security **_sec,
 108                                    struct key **_key,
 109                                    struct sk_buff *skb)
 110 {
 111         const struct rxrpc_security *sec;
 112         struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
 113         key_ref_t kref = NULL;
 114         char kdesc[5 + 1 + 3 + 1];
 115 
 116         _enter("");
 117 
 118         sprintf(kdesc, "%u:%u", sp->hdr.serviceId, sp->hdr.securityIndex);
 119 
 120         sec = rxrpc_security_lookup(sp->hdr.securityIndex);
 121         if (!sec) {
 122                 trace_rxrpc_abort(0, "SVS",
 123                                   sp->hdr.cid, sp->hdr.callNumber, sp->hdr.seq,
 124                                   RX_INVALID_OPERATION, EKEYREJECTED);
 125                 skb->mark = RXRPC_SKB_MARK_REJECT_ABORT;
 126                 skb->priority = RX_INVALID_OPERATION;
 127                 return false;
 128         }
 129 
 130         if (sp->hdr.securityIndex == RXRPC_SECURITY_NONE)
 131                 goto out;
 132 
 133         if (!rx->securities) {
 134                 trace_rxrpc_abort(0, "SVR",
 135                                   sp->hdr.cid, sp->hdr.callNumber, sp->hdr.seq,
 136                                   RX_INVALID_OPERATION, EKEYREJECTED);
 137                 skb->mark = RXRPC_SKB_MARK_REJECT_ABORT;
 138                 skb->priority = RX_INVALID_OPERATION;
 139                 return false;
 140         }
 141 
 142         /* look through the service's keyring */
 143         kref = keyring_search(make_key_ref(rx->securities, 1UL),
 144                               &key_type_rxrpc_s, kdesc, true);
 145         if (IS_ERR(kref)) {
 146                 trace_rxrpc_abort(0, "SVK",
 147                                   sp->hdr.cid, sp->hdr.callNumber, sp->hdr.seq,
 148                                   sec->no_key_abort, EKEYREJECTED);
 149                 skb->mark = RXRPC_SKB_MARK_REJECT_ABORT;
 150                 skb->priority = sec->no_key_abort;
 151                 return false;
 152         }
 153 
 154 out:
 155         *_sec = sec;
 156         *_key = key_ref_to_ptr(kref);
 157         return true;
 158 }

/* [<][>][^][v][top][bottom][index][help] */