0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/module.h>
0009 #include <linux/net.h>
0010 #include <linux/skbuff.h>
0011 #include <linux/udp.h>
0012 #include <linux/crypto.h>
0013 #include <net/sock.h>
0014 #include <net/af_rxrpc.h>
0015 #include <keys/rxrpc-type.h>
0016 #include "ar-internal.h"
0017
0018 static const struct rxrpc_security *rxrpc_security_types[] = {
0019 [RXRPC_SECURITY_NONE] = &rxrpc_no_security,
0020 #ifdef CONFIG_RXKAD
0021 [RXRPC_SECURITY_RXKAD] = &rxkad,
0022 #endif
0023 };
0024
0025 int __init rxrpc_init_security(void)
0026 {
0027 int i, ret;
0028
0029 for (i = 0; i < ARRAY_SIZE(rxrpc_security_types); i++) {
0030 if (rxrpc_security_types[i]) {
0031 ret = rxrpc_security_types[i]->init();
0032 if (ret < 0)
0033 goto failed;
0034 }
0035 }
0036
0037 return 0;
0038
0039 failed:
0040 for (i--; i >= 0; i--)
0041 if (rxrpc_security_types[i])
0042 rxrpc_security_types[i]->exit();
0043 return ret;
0044 }
0045
0046 void rxrpc_exit_security(void)
0047 {
0048 int i;
0049
0050 for (i = 0; i < ARRAY_SIZE(rxrpc_security_types); i++)
0051 if (rxrpc_security_types[i])
0052 rxrpc_security_types[i]->exit();
0053 }
0054
0055
0056
0057
0058 const struct rxrpc_security *rxrpc_security_lookup(u8 security_index)
0059 {
0060 if (security_index >= ARRAY_SIZE(rxrpc_security_types))
0061 return NULL;
0062 return rxrpc_security_types[security_index];
0063 }
0064
0065
0066
0067
0068 int rxrpc_init_client_conn_security(struct rxrpc_connection *conn)
0069 {
0070 const struct rxrpc_security *sec;
0071 struct rxrpc_key_token *token;
0072 struct key *key = conn->params.key;
0073 int ret;
0074
0075 _enter("{%d},{%x}", conn->debug_id, key_serial(key));
0076
0077 if (!key)
0078 return 0;
0079
0080 ret = key_validate(key);
0081 if (ret < 0)
0082 return ret;
0083
0084 for (token = key->payload.data[0]; token; token = token->next) {
0085 sec = rxrpc_security_lookup(token->security_index);
0086 if (sec)
0087 goto found;
0088 }
0089 return -EKEYREJECTED;
0090
0091 found:
0092 conn->security = sec;
0093
0094 ret = conn->security->init_connection_security(conn, token);
0095 if (ret < 0) {
0096 conn->security = &rxrpc_no_security;
0097 return ret;
0098 }
0099
0100 _leave(" = 0");
0101 return 0;
0102 }
0103
0104
0105
0106
0107 const struct rxrpc_security *rxrpc_get_incoming_security(struct rxrpc_sock *rx,
0108 struct sk_buff *skb)
0109 {
0110 const struct rxrpc_security *sec;
0111 struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
0112
0113 _enter("");
0114
0115 sec = rxrpc_security_lookup(sp->hdr.securityIndex);
0116 if (!sec) {
0117 trace_rxrpc_abort(0, "SVS",
0118 sp->hdr.cid, sp->hdr.callNumber, sp->hdr.seq,
0119 RX_INVALID_OPERATION, EKEYREJECTED);
0120 skb->mark = RXRPC_SKB_MARK_REJECT_ABORT;
0121 skb->priority = RX_INVALID_OPERATION;
0122 return NULL;
0123 }
0124
0125 if (sp->hdr.securityIndex != RXRPC_SECURITY_NONE &&
0126 !rx->securities) {
0127 trace_rxrpc_abort(0, "SVR",
0128 sp->hdr.cid, sp->hdr.callNumber, sp->hdr.seq,
0129 RX_INVALID_OPERATION, EKEYREJECTED);
0130 skb->mark = RXRPC_SKB_MARK_REJECT_ABORT;
0131 skb->priority = sec->no_key_abort;
0132 return NULL;
0133 }
0134
0135 return sec;
0136 }
0137
0138
0139
0140
0141 struct key *rxrpc_look_up_server_security(struct rxrpc_connection *conn,
0142 struct sk_buff *skb,
0143 u32 kvno, u32 enctype)
0144 {
0145 struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
0146 struct rxrpc_sock *rx;
0147 struct key *key = ERR_PTR(-EKEYREJECTED);
0148 key_ref_t kref = NULL;
0149 char kdesc[5 + 1 + 3 + 1 + 12 + 1 + 12 + 1];
0150 int ret;
0151
0152 _enter("");
0153
0154 if (enctype)
0155 sprintf(kdesc, "%u:%u:%u:%u",
0156 sp->hdr.serviceId, sp->hdr.securityIndex, kvno, enctype);
0157 else if (kvno)
0158 sprintf(kdesc, "%u:%u:%u",
0159 sp->hdr.serviceId, sp->hdr.securityIndex, kvno);
0160 else
0161 sprintf(kdesc, "%u:%u",
0162 sp->hdr.serviceId, sp->hdr.securityIndex);
0163
0164 rcu_read_lock();
0165
0166 rx = rcu_dereference(conn->params.local->service);
0167 if (!rx)
0168 goto out;
0169
0170
0171 kref = keyring_search(make_key_ref(rx->securities, 1UL),
0172 &key_type_rxrpc_s, kdesc, true);
0173 if (IS_ERR(kref)) {
0174 key = ERR_CAST(kref);
0175 goto out;
0176 }
0177
0178 key = key_ref_to_ptr(kref);
0179
0180 ret = key_validate(key);
0181 if (ret < 0) {
0182 key_put(key);
0183 key = ERR_PTR(ret);
0184 goto out;
0185 }
0186
0187 out:
0188 rcu_read_unlock();
0189 return key;
0190 }