1 /* RxRPC security handling
3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
12 #include <linux/module.h>
13 #include <linux/net.h>
14 #include <linux/skbuff.h>
15 #include <linux/udp.h>
16 #include <linux/crypto.h>
18 #include <net/af_rxrpc.h>
19 #include <keys/rxrpc-type.h>
20 #include "ar-internal.h"
22 static LIST_HEAD(rxrpc_security_methods
);
23 static DECLARE_RWSEM(rxrpc_security_sem
);
26 * get an RxRPC security module
28 static struct rxrpc_security
*rxrpc_security_get(struct rxrpc_security
*sec
)
30 return try_module_get(sec
->owner
) ? sec
: NULL
;
34 * release an RxRPC security module
36 static void rxrpc_security_put(struct rxrpc_security
*sec
)
38 module_put(sec
->owner
);
42 * look up an rxrpc security module
44 static struct rxrpc_security
*rxrpc_security_lookup(u8 security_index
)
46 struct rxrpc_security
*sec
= NULL
;
50 down_read(&rxrpc_security_sem
);
52 list_for_each_entry(sec
, &rxrpc_security_methods
, link
) {
53 if (sec
->security_index
== security_index
) {
54 if (unlikely(!rxrpc_security_get(sec
)))
62 up_read(&rxrpc_security_sem
);
63 _leave(" = %p [%s]", sec
, sec
? sec
->name
: "");
68 * rxrpc_register_security - register an RxRPC security handler
69 * @sec: security module
71 * register an RxRPC security handler for use by RxRPC
73 int rxrpc_register_security(struct rxrpc_security
*sec
)
75 struct rxrpc_security
*psec
;
79 down_write(&rxrpc_security_sem
);
82 list_for_each_entry(psec
, &rxrpc_security_methods
, link
) {
83 if (psec
->security_index
== sec
->security_index
)
87 list_add(&sec
->link
, &rxrpc_security_methods
);
89 printk(KERN_NOTICE
"RxRPC: Registered security type %d '%s'\n",
90 sec
->security_index
, sec
->name
);
94 up_write(&rxrpc_security_sem
);
99 EXPORT_SYMBOL_GPL(rxrpc_register_security
);
102 * rxrpc_unregister_security - unregister an RxRPC security handler
103 * @sec: security module
105 * unregister an RxRPC security handler
107 void rxrpc_unregister_security(struct rxrpc_security
*sec
)
111 down_write(&rxrpc_security_sem
);
112 list_del_init(&sec
->link
);
113 up_write(&rxrpc_security_sem
);
115 printk(KERN_NOTICE
"RxRPC: Unregistered security type %d '%s'\n",
116 sec
->security_index
, sec
->name
);
119 EXPORT_SYMBOL_GPL(rxrpc_unregister_security
);
122 * initialise the security on a client connection
124 int rxrpc_init_client_conn_security(struct rxrpc_connection
*conn
)
126 struct rxrpc_key_token
*token
;
127 struct rxrpc_security
*sec
;
128 struct key
*key
= conn
->key
;
131 _enter("{%d},{%x}", conn
->debug_id
, key_serial(key
));
136 ret
= key_validate(key
);
140 token
= key
->payload
.data
[0];
142 return -EKEYREJECTED
;
144 sec
= rxrpc_security_lookup(token
->security_index
);
146 return -EKEYREJECTED
;
147 conn
->security
= sec
;
149 ret
= conn
->security
->init_connection_security(conn
);
151 rxrpc_security_put(conn
->security
);
152 conn
->security
= NULL
;
161 * initialise the security on a server connection
163 int rxrpc_init_server_conn_security(struct rxrpc_connection
*conn
)
165 struct rxrpc_security
*sec
;
166 struct rxrpc_local
*local
= conn
->trans
->local
;
167 struct rxrpc_sock
*rx
;
174 sprintf(kdesc
, "%u:%u", ntohs(conn
->service_id
), conn
->security_ix
);
176 sec
= rxrpc_security_lookup(conn
->security_ix
);
178 _leave(" = -ENOKEY [lookup]");
182 /* find the service */
183 read_lock_bh(&local
->services_lock
);
184 list_for_each_entry(rx
, &local
->services
, listen_link
) {
185 if (rx
->service_id
== conn
->service_id
)
189 /* the service appears to have died */
190 read_unlock_bh(&local
->services_lock
);
191 rxrpc_security_put(sec
);
192 _leave(" = -ENOENT");
196 if (!rx
->securities
) {
197 read_unlock_bh(&local
->services_lock
);
198 rxrpc_security_put(sec
);
199 _leave(" = -ENOKEY");
203 /* look through the service's keyring */
204 kref
= keyring_search(make_key_ref(rx
->securities
, 1UL),
205 &key_type_rxrpc_s
, kdesc
);
207 read_unlock_bh(&local
->services_lock
);
208 rxrpc_security_put(sec
);
209 _leave(" = %ld [search]", PTR_ERR(kref
));
210 return PTR_ERR(kref
);
213 key
= key_ref_to_ptr(kref
);
214 read_unlock_bh(&local
->services_lock
);
216 conn
->server_key
= key
;
217 conn
->security
= sec
;
224 * secure a packet prior to transmission
226 int rxrpc_secure_packet(const struct rxrpc_call
*call
,
231 if (call
->conn
->security
)
232 return call
->conn
->security
->secure_packet(
233 call
, skb
, data_size
, sechdr
);
238 * secure a packet prior to transmission
240 int rxrpc_verify_packet(const struct rxrpc_call
*call
, struct sk_buff
*skb
,
243 if (call
->conn
->security
)
244 return call
->conn
->security
->verify_packet(
245 call
, skb
, _abort_code
);
250 * clear connection security
252 void rxrpc_clear_conn_security(struct rxrpc_connection
*conn
)
254 _enter("{%d}", conn
->debug_id
);
256 if (conn
->security
) {
257 conn
->security
->clear(conn
);
258 rxrpc_security_put(conn
->security
);
259 conn
->security
= NULL
;
263 key_put(conn
->server_key
);