security.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  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 ([email protected])
  6. */
  7. #include <linux/module.h>
  8. #include <linux/net.h>
  9. #include <linux/skbuff.h>
  10. #include <linux/udp.h>
  11. #include <linux/crypto.h>
  12. #include <net/sock.h>
  13. #include <net/af_rxrpc.h>
  14. #include <keys/rxrpc-type.h>
  15. #include "ar-internal.h"
  16. static const struct rxrpc_security *rxrpc_security_types[] = {
  17. [RXRPC_SECURITY_NONE] = &rxrpc_no_security,
  18. #ifdef CONFIG_RXKAD
  19. [RXRPC_SECURITY_RXKAD] = &rxkad,
  20. #endif
  21. };
  22. int __init rxrpc_init_security(void)
  23. {
  24. int i, ret;
  25. for (i = 0; i < ARRAY_SIZE(rxrpc_security_types); i++) {
  26. if (rxrpc_security_types[i]) {
  27. ret = rxrpc_security_types[i]->init();
  28. if (ret < 0)
  29. goto failed;
  30. }
  31. }
  32. return 0;
  33. failed:
  34. for (i--; i >= 0; i--)
  35. if (rxrpc_security_types[i])
  36. rxrpc_security_types[i]->exit();
  37. return ret;
  38. }
  39. void rxrpc_exit_security(void)
  40. {
  41. int i;
  42. for (i = 0; i < ARRAY_SIZE(rxrpc_security_types); i++)
  43. if (rxrpc_security_types[i])
  44. rxrpc_security_types[i]->exit();
  45. }
  46. /*
  47. * look up an rxrpc security module
  48. */
  49. const struct rxrpc_security *rxrpc_security_lookup(u8 security_index)
  50. {
  51. if (security_index >= ARRAY_SIZE(rxrpc_security_types))
  52. return NULL;
  53. return rxrpc_security_types[security_index];
  54. }
  55. /*
  56. * initialise the security on a client connection
  57. */
  58. int rxrpc_init_client_conn_security(struct rxrpc_connection *conn)
  59. {
  60. const struct rxrpc_security *sec;
  61. struct rxrpc_key_token *token;
  62. struct key *key = conn->params.key;
  63. int ret;
  64. _enter("{%d},{%x}", conn->debug_id, key_serial(key));
  65. if (!key)
  66. return 0;
  67. ret = key_validate(key);
  68. if (ret < 0)
  69. return ret;
  70. for (token = key->payload.data[0]; token; token = token->next) {
  71. sec = rxrpc_security_lookup(token->security_index);
  72. if (sec)
  73. goto found;
  74. }
  75. return -EKEYREJECTED;
  76. found:
  77. conn->security = sec;
  78. ret = conn->security->init_connection_security(conn, token);
  79. if (ret < 0) {
  80. conn->security = &rxrpc_no_security;
  81. return ret;
  82. }
  83. _leave(" = 0");
  84. return 0;
  85. }
  86. /*
  87. * Set the ops a server connection.
  88. */
  89. const struct rxrpc_security *rxrpc_get_incoming_security(struct rxrpc_sock *rx,
  90. struct sk_buff *skb)
  91. {
  92. const struct rxrpc_security *sec;
  93. struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
  94. _enter("");
  95. sec = rxrpc_security_lookup(sp->hdr.securityIndex);
  96. if (!sec) {
  97. trace_rxrpc_abort(0, "SVS",
  98. sp->hdr.cid, sp->hdr.callNumber, sp->hdr.seq,
  99. RX_INVALID_OPERATION, EKEYREJECTED);
  100. skb->mark = RXRPC_SKB_MARK_REJECT_ABORT;
  101. skb->priority = RX_INVALID_OPERATION;
  102. return NULL;
  103. }
  104. if (sp->hdr.securityIndex != RXRPC_SECURITY_NONE &&
  105. !rx->securities) {
  106. trace_rxrpc_abort(0, "SVR",
  107. sp->hdr.cid, sp->hdr.callNumber, sp->hdr.seq,
  108. RX_INVALID_OPERATION, EKEYREJECTED);
  109. skb->mark = RXRPC_SKB_MARK_REJECT_ABORT;
  110. skb->priority = sec->no_key_abort;
  111. return NULL;
  112. }
  113. return sec;
  114. }
  115. /*
  116. * Find the security key for a server connection.
  117. */
  118. struct key *rxrpc_look_up_server_security(struct rxrpc_connection *conn,
  119. struct sk_buff *skb,
  120. u32 kvno, u32 enctype)
  121. {
  122. struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
  123. struct rxrpc_sock *rx;
  124. struct key *key = ERR_PTR(-EKEYREJECTED);
  125. key_ref_t kref = NULL;
  126. char kdesc[5 + 1 + 3 + 1 + 12 + 1 + 12 + 1];
  127. int ret;
  128. _enter("");
  129. if (enctype)
  130. sprintf(kdesc, "%u:%u:%u:%u",
  131. sp->hdr.serviceId, sp->hdr.securityIndex, kvno, enctype);
  132. else if (kvno)
  133. sprintf(kdesc, "%u:%u:%u",
  134. sp->hdr.serviceId, sp->hdr.securityIndex, kvno);
  135. else
  136. sprintf(kdesc, "%u:%u",
  137. sp->hdr.serviceId, sp->hdr.securityIndex);
  138. rcu_read_lock();
  139. rx = rcu_dereference(conn->params.local->service);
  140. if (!rx)
  141. goto out;
  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. key = ERR_CAST(kref);
  147. goto out;
  148. }
  149. key = key_ref_to_ptr(kref);
  150. ret = key_validate(key);
  151. if (ret < 0) {
  152. key_put(key);
  153. key = ERR_PTR(ret);
  154. goto out;
  155. }
  156. out:
  157. rcu_read_unlock();
  158. return key;
  159. }