security.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  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 const struct rxrpc_security *rxrpc_security_types[] = {
  21. [RXRPC_SECURITY_NONE] = &rxrpc_no_security,
  22. #ifdef CONFIG_RXKAD
  23. [RXRPC_SECURITY_RXKAD] = &rxkad,
  24. #endif
  25. };
  26. int __init rxrpc_init_security(void)
  27. {
  28. int i, ret;
  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. return 0;
  37. failed:
  38. for (i--; i >= 0; i--)
  39. if (rxrpc_security_types[i])
  40. rxrpc_security_types[i]->exit();
  41. return ret;
  42. }
  43. void rxrpc_exit_security(void)
  44. {
  45. int i;
  46. for (i = 0; i < ARRAY_SIZE(rxrpc_security_types); i++)
  47. if (rxrpc_security_types[i])
  48. rxrpc_security_types[i]->exit();
  49. }
  50. /*
  51. * look up an rxrpc security module
  52. */
  53. static const struct rxrpc_security *rxrpc_security_lookup(u8 security_index)
  54. {
  55. if (security_index >= ARRAY_SIZE(rxrpc_security_types))
  56. return NULL;
  57. return rxrpc_security_types[security_index];
  58. }
  59. /*
  60. * initialise the security on a client connection
  61. */
  62. int rxrpc_init_client_conn_security(struct rxrpc_connection *conn)
  63. {
  64. const struct rxrpc_security *sec;
  65. struct rxrpc_key_token *token;
  66. struct key *key = conn->params.key;
  67. int ret;
  68. _enter("{%d},{%x}", conn->debug_id, key_serial(key));
  69. if (!key)
  70. return 0;
  71. ret = key_validate(key);
  72. if (ret < 0)
  73. return ret;
  74. token = key->payload.data[0];
  75. if (!token)
  76. return -EKEYREJECTED;
  77. sec = rxrpc_security_lookup(token->security_index);
  78. if (!sec)
  79. return -EKEYREJECTED;
  80. conn->security = sec;
  81. ret = conn->security->init_connection_security(conn);
  82. if (ret < 0) {
  83. conn->security = &rxrpc_no_security;
  84. return ret;
  85. }
  86. _leave(" = 0");
  87. return 0;
  88. }
  89. /*
  90. * initialise the security on a server connection
  91. */
  92. int rxrpc_init_server_conn_security(struct rxrpc_connection *conn)
  93. {
  94. const struct rxrpc_security *sec;
  95. struct rxrpc_local *local = conn->params.local;
  96. struct rxrpc_sock *rx;
  97. struct key *key;
  98. key_ref_t kref;
  99. char kdesc[5 + 1 + 3 + 1];
  100. _enter("");
  101. sprintf(kdesc, "%u:%u", conn->service_id, conn->security_ix);
  102. sec = rxrpc_security_lookup(conn->security_ix);
  103. if (!sec) {
  104. _leave(" = -ENOKEY [lookup]");
  105. return -ENOKEY;
  106. }
  107. /* find the service */
  108. read_lock(&local->services_lock);
  109. rx = rcu_dereference_protected(local->service,
  110. lockdep_is_held(&local->services_lock));
  111. if (rx && (rx->srx.srx_service == conn->service_id ||
  112. rx->second_service == conn->service_id))
  113. goto found_service;
  114. /* the service appears to have died */
  115. read_unlock(&local->services_lock);
  116. _leave(" = -ENOENT");
  117. return -ENOENT;
  118. found_service:
  119. if (!rx->securities) {
  120. read_unlock(&local->services_lock);
  121. _leave(" = -ENOKEY");
  122. return -ENOKEY;
  123. }
  124. /* look through the service's keyring */
  125. kref = keyring_search(make_key_ref(rx->securities, 1UL),
  126. &key_type_rxrpc_s, kdesc);
  127. if (IS_ERR(kref)) {
  128. read_unlock(&local->services_lock);
  129. _leave(" = %ld [search]", PTR_ERR(kref));
  130. return PTR_ERR(kref);
  131. }
  132. key = key_ref_to_ptr(kref);
  133. read_unlock(&local->services_lock);
  134. conn->server_key = key;
  135. conn->security = sec;
  136. _leave(" = 0");
  137. return 0;
  138. }