ar-security.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. /* RxRPC security handling
  2. *
  3. * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
  4. * Written by David Howells (dhowells@redhat.com)
  5. *
  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.
  10. */
  11. #include <linux/module.h>
  12. #include <linux/net.h>
  13. #include <linux/skbuff.h>
  14. #include <linux/udp.h>
  15. #include <linux/crypto.h>
  16. #include <net/sock.h>
  17. #include <net/af_rxrpc.h>
  18. #include <keys/rxrpc-type.h>
  19. #include "ar-internal.h"
  20. static LIST_HEAD(rxrpc_security_methods);
  21. static DECLARE_RWSEM(rxrpc_security_sem);
  22. /*
  23. * get an RxRPC security module
  24. */
  25. static struct rxrpc_security *rxrpc_security_get(struct rxrpc_security *sec)
  26. {
  27. return try_module_get(sec->owner) ? sec : NULL;
  28. }
  29. /*
  30. * release an RxRPC security module
  31. */
  32. static void rxrpc_security_put(struct rxrpc_security *sec)
  33. {
  34. module_put(sec->owner);
  35. }
  36. /*
  37. * look up an rxrpc security module
  38. */
  39. static struct rxrpc_security *rxrpc_security_lookup(u8 security_index)
  40. {
  41. struct rxrpc_security *sec = NULL;
  42. _enter("");
  43. down_read(&rxrpc_security_sem);
  44. list_for_each_entry(sec, &rxrpc_security_methods, link) {
  45. if (sec->security_index == security_index) {
  46. if (unlikely(!rxrpc_security_get(sec)))
  47. break;
  48. goto out;
  49. }
  50. }
  51. sec = NULL;
  52. out:
  53. up_read(&rxrpc_security_sem);
  54. _leave(" = %p [%s]", sec, sec ? sec->name : "");
  55. return sec;
  56. }
  57. /**
  58. * rxrpc_register_security - register an RxRPC security handler
  59. * @sec: security module
  60. *
  61. * register an RxRPC security handler for use by RxRPC
  62. */
  63. int rxrpc_register_security(struct rxrpc_security *sec)
  64. {
  65. struct rxrpc_security *psec;
  66. int ret;
  67. _enter("");
  68. down_write(&rxrpc_security_sem);
  69. ret = -EEXIST;
  70. list_for_each_entry(psec, &rxrpc_security_methods, link) {
  71. if (psec->security_index == sec->security_index)
  72. goto out;
  73. }
  74. list_add(&sec->link, &rxrpc_security_methods);
  75. printk(KERN_NOTICE "RxRPC: Registered security type %d '%s'\n",
  76. sec->security_index, sec->name);
  77. ret = 0;
  78. out:
  79. up_write(&rxrpc_security_sem);
  80. _leave(" = %d", ret);
  81. return ret;
  82. }
  83. EXPORT_SYMBOL_GPL(rxrpc_register_security);
  84. /**
  85. * rxrpc_unregister_security - unregister an RxRPC security handler
  86. * @sec: security module
  87. *
  88. * unregister an RxRPC security handler
  89. */
  90. void rxrpc_unregister_security(struct rxrpc_security *sec)
  91. {
  92. _enter("");
  93. down_write(&rxrpc_security_sem);
  94. list_del_init(&sec->link);
  95. up_write(&rxrpc_security_sem);
  96. printk(KERN_NOTICE "RxRPC: Unregistered security type %d '%s'\n",
  97. sec->security_index, sec->name);
  98. }
  99. EXPORT_SYMBOL_GPL(rxrpc_unregister_security);
  100. /*
  101. * initialise the security on a client connection
  102. */
  103. int rxrpc_init_client_conn_security(struct rxrpc_connection *conn)
  104. {
  105. struct rxrpc_key_token *token;
  106. struct rxrpc_security *sec;
  107. struct key *key = conn->key;
  108. int ret;
  109. _enter("{%d},{%x}", conn->debug_id, key_serial(key));
  110. if (!key)
  111. return 0;
  112. ret = key_validate(key);
  113. if (ret < 0)
  114. return ret;
  115. token = key->payload.data[0];
  116. if (!token)
  117. return -EKEYREJECTED;
  118. sec = rxrpc_security_lookup(token->security_index);
  119. if (!sec)
  120. return -EKEYREJECTED;
  121. conn->security = sec;
  122. ret = conn->security->init_connection_security(conn);
  123. if (ret < 0) {
  124. rxrpc_security_put(conn->security);
  125. conn->security = NULL;
  126. return ret;
  127. }
  128. _leave(" = 0");
  129. return 0;
  130. }
  131. /*
  132. * initialise the security on a server connection
  133. */
  134. int rxrpc_init_server_conn_security(struct rxrpc_connection *conn)
  135. {
  136. struct rxrpc_security *sec;
  137. struct rxrpc_local *local = conn->trans->local;
  138. struct rxrpc_sock *rx;
  139. struct key *key;
  140. key_ref_t kref;
  141. char kdesc[5+1+3+1];
  142. _enter("");
  143. sprintf(kdesc, "%u:%u", ntohs(conn->service_id), conn->security_ix);
  144. sec = rxrpc_security_lookup(conn->security_ix);
  145. if (!sec) {
  146. _leave(" = -ENOKEY [lookup]");
  147. return -ENOKEY;
  148. }
  149. /* find the service */
  150. read_lock_bh(&local->services_lock);
  151. list_for_each_entry(rx, &local->services, listen_link) {
  152. if (rx->service_id == conn->service_id)
  153. goto found_service;
  154. }
  155. /* the service appears to have died */
  156. read_unlock_bh(&local->services_lock);
  157. rxrpc_security_put(sec);
  158. _leave(" = -ENOENT");
  159. return -ENOENT;
  160. found_service:
  161. if (!rx->securities) {
  162. read_unlock_bh(&local->services_lock);
  163. rxrpc_security_put(sec);
  164. _leave(" = -ENOKEY");
  165. return -ENOKEY;
  166. }
  167. /* look through the service's keyring */
  168. kref = keyring_search(make_key_ref(rx->securities, 1UL),
  169. &key_type_rxrpc_s, kdesc);
  170. if (IS_ERR(kref)) {
  171. read_unlock_bh(&local->services_lock);
  172. rxrpc_security_put(sec);
  173. _leave(" = %ld [search]", PTR_ERR(kref));
  174. return PTR_ERR(kref);
  175. }
  176. key = key_ref_to_ptr(kref);
  177. read_unlock_bh(&local->services_lock);
  178. conn->server_key = key;
  179. conn->security = sec;
  180. _leave(" = 0");
  181. return 0;
  182. }
  183. /*
  184. * secure a packet prior to transmission
  185. */
  186. int rxrpc_secure_packet(const struct rxrpc_call *call,
  187. struct sk_buff *skb,
  188. size_t data_size,
  189. void *sechdr)
  190. {
  191. if (call->conn->security)
  192. return call->conn->security->secure_packet(
  193. call, skb, data_size, sechdr);
  194. return 0;
  195. }
  196. /*
  197. * secure a packet prior to transmission
  198. */
  199. int rxrpc_verify_packet(const struct rxrpc_call *call, struct sk_buff *skb,
  200. u32 *_abort_code)
  201. {
  202. if (call->conn->security)
  203. return call->conn->security->verify_packet(
  204. call, skb, _abort_code);
  205. return 0;
  206. }
  207. /*
  208. * clear connection security
  209. */
  210. void rxrpc_clear_conn_security(struct rxrpc_connection *conn)
  211. {
  212. _enter("{%d}", conn->debug_id);
  213. if (conn->security) {
  214. conn->security->clear(conn);
  215. rxrpc_security_put(conn->security);
  216. conn->security = NULL;
  217. }
  218. key_put(conn->key);
  219. key_put(conn->server_key);
  220. }