krxsecd.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. /* krxsecd.c: Rx security daemon
  2. *
  3. * Copyright (C) 2002 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. * This daemon deals with:
  12. * - consulting the application as to whether inbound peers and calls should be authorised
  13. * - generating security challenges for inbound connections
  14. * - responding to security challenges on outbound connections
  15. */
  16. #include <linux/module.h>
  17. #include <linux/sched.h>
  18. #include <linux/completion.h>
  19. #include <linux/spinlock.h>
  20. #include <linux/init.h>
  21. #include <rxrpc/krxsecd.h>
  22. #include <rxrpc/transport.h>
  23. #include <rxrpc/connection.h>
  24. #include <rxrpc/message.h>
  25. #include <rxrpc/peer.h>
  26. #include <rxrpc/call.h>
  27. #include <linux/udp.h>
  28. #include <linux/ip.h>
  29. #include <net/sock.h>
  30. #include "internal.h"
  31. static DECLARE_WAIT_QUEUE_HEAD(rxrpc_krxsecd_sleepq);
  32. static DECLARE_COMPLETION(rxrpc_krxsecd_dead);
  33. static volatile int rxrpc_krxsecd_die;
  34. static atomic_t rxrpc_krxsecd_qcount;
  35. /* queue of unprocessed inbound messages with seqno #1 and
  36. * RXRPC_CLIENT_INITIATED flag set */
  37. static LIST_HEAD(rxrpc_krxsecd_initmsgq);
  38. static DEFINE_SPINLOCK(rxrpc_krxsecd_initmsgq_lock);
  39. static void rxrpc_krxsecd_process_incoming_call(struct rxrpc_message *msg);
  40. /*****************************************************************************/
  41. /*
  42. * Rx security daemon
  43. */
  44. static int rxrpc_krxsecd(void *arg)
  45. {
  46. DECLARE_WAITQUEUE(krxsecd, current);
  47. int die;
  48. printk("Started krxsecd %d\n", current->pid);
  49. daemonize("krxsecd");
  50. /* loop around waiting for work to do */
  51. do {
  52. /* wait for work or to be told to exit */
  53. _debug("### Begin Wait");
  54. if (!atomic_read(&rxrpc_krxsecd_qcount)) {
  55. set_current_state(TASK_INTERRUPTIBLE);
  56. add_wait_queue(&rxrpc_krxsecd_sleepq, &krxsecd);
  57. for (;;) {
  58. set_current_state(TASK_INTERRUPTIBLE);
  59. if (atomic_read(&rxrpc_krxsecd_qcount) ||
  60. rxrpc_krxsecd_die ||
  61. signal_pending(current))
  62. break;
  63. schedule();
  64. }
  65. remove_wait_queue(&rxrpc_krxsecd_sleepq, &krxsecd);
  66. set_current_state(TASK_RUNNING);
  67. }
  68. die = rxrpc_krxsecd_die;
  69. _debug("### End Wait");
  70. /* see if there're incoming calls in need of authenticating */
  71. _debug("### Begin Inbound Calls");
  72. if (!list_empty(&rxrpc_krxsecd_initmsgq)) {
  73. struct rxrpc_message *msg = NULL;
  74. spin_lock(&rxrpc_krxsecd_initmsgq_lock);
  75. if (!list_empty(&rxrpc_krxsecd_initmsgq)) {
  76. msg = list_entry(rxrpc_krxsecd_initmsgq.next,
  77. struct rxrpc_message, link);
  78. list_del_init(&msg->link);
  79. atomic_dec(&rxrpc_krxsecd_qcount);
  80. }
  81. spin_unlock(&rxrpc_krxsecd_initmsgq_lock);
  82. if (msg) {
  83. rxrpc_krxsecd_process_incoming_call(msg);
  84. rxrpc_put_message(msg);
  85. }
  86. }
  87. _debug("### End Inbound Calls");
  88. try_to_freeze();
  89. /* discard pending signals */
  90. rxrpc_discard_my_signals();
  91. } while (!die);
  92. /* and that's all */
  93. complete_and_exit(&rxrpc_krxsecd_dead, 0);
  94. } /* end rxrpc_krxsecd() */
  95. /*****************************************************************************/
  96. /*
  97. * start up a krxsecd daemon
  98. */
  99. int __init rxrpc_krxsecd_init(void)
  100. {
  101. return kernel_thread(rxrpc_krxsecd, NULL, 0);
  102. } /* end rxrpc_krxsecd_init() */
  103. /*****************************************************************************/
  104. /*
  105. * kill the krxsecd daemon and wait for it to complete
  106. */
  107. void rxrpc_krxsecd_kill(void)
  108. {
  109. rxrpc_krxsecd_die = 1;
  110. wake_up_all(&rxrpc_krxsecd_sleepq);
  111. wait_for_completion(&rxrpc_krxsecd_dead);
  112. } /* end rxrpc_krxsecd_kill() */
  113. /*****************************************************************************/
  114. /*
  115. * clear all pending incoming calls for the specified transport
  116. */
  117. void rxrpc_krxsecd_clear_transport(struct rxrpc_transport *trans)
  118. {
  119. LIST_HEAD(tmp);
  120. struct rxrpc_message *msg;
  121. struct list_head *_p, *_n;
  122. _enter("%p",trans);
  123. /* move all the messages for this transport onto a temp list */
  124. spin_lock(&rxrpc_krxsecd_initmsgq_lock);
  125. list_for_each_safe(_p, _n, &rxrpc_krxsecd_initmsgq) {
  126. msg = list_entry(_p, struct rxrpc_message, link);
  127. if (msg->trans == trans) {
  128. list_move_tail(&msg->link, &tmp);
  129. atomic_dec(&rxrpc_krxsecd_qcount);
  130. }
  131. }
  132. spin_unlock(&rxrpc_krxsecd_initmsgq_lock);
  133. /* zap all messages on the temp list */
  134. while (!list_empty(&tmp)) {
  135. msg = list_entry(tmp.next, struct rxrpc_message, link);
  136. list_del_init(&msg->link);
  137. rxrpc_put_message(msg);
  138. }
  139. _leave("");
  140. } /* end rxrpc_krxsecd_clear_transport() */
  141. /*****************************************************************************/
  142. /*
  143. * queue a message on the incoming calls list
  144. */
  145. void rxrpc_krxsecd_queue_incoming_call(struct rxrpc_message *msg)
  146. {
  147. _enter("%p", msg);
  148. /* queue for processing by krxsecd */
  149. spin_lock(&rxrpc_krxsecd_initmsgq_lock);
  150. if (!rxrpc_krxsecd_die) {
  151. rxrpc_get_message(msg);
  152. list_add_tail(&msg->link, &rxrpc_krxsecd_initmsgq);
  153. atomic_inc(&rxrpc_krxsecd_qcount);
  154. }
  155. spin_unlock(&rxrpc_krxsecd_initmsgq_lock);
  156. wake_up(&rxrpc_krxsecd_sleepq);
  157. _leave("");
  158. } /* end rxrpc_krxsecd_queue_incoming_call() */
  159. /*****************************************************************************/
  160. /*
  161. * process the initial message of an incoming call
  162. */
  163. void rxrpc_krxsecd_process_incoming_call(struct rxrpc_message *msg)
  164. {
  165. struct rxrpc_transport *trans = msg->trans;
  166. struct rxrpc_service *srv;
  167. struct rxrpc_call *call;
  168. struct list_head *_p;
  169. unsigned short sid;
  170. int ret;
  171. _enter("%p{tr=%p}", msg, trans);
  172. ret = rxrpc_incoming_call(msg->conn, msg, &call);
  173. if (ret < 0)
  174. goto out;
  175. /* find the matching service on the transport */
  176. sid = ntohs(msg->hdr.serviceId);
  177. srv = NULL;
  178. spin_lock(&trans->lock);
  179. list_for_each(_p, &trans->services) {
  180. srv = list_entry(_p, struct rxrpc_service, link);
  181. if (srv->service_id == sid && try_module_get(srv->owner)) {
  182. /* found a match (made sure it won't vanish) */
  183. _debug("found service '%s'", srv->name);
  184. call->owner = srv->owner;
  185. break;
  186. }
  187. }
  188. spin_unlock(&trans->lock);
  189. /* report the new connection
  190. * - the func must inc the call's usage count to keep it
  191. */
  192. ret = -ENOENT;
  193. if (_p != &trans->services) {
  194. /* attempt to accept the call */
  195. call->conn->service = srv;
  196. call->app_attn_func = srv->attn_func;
  197. call->app_error_func = srv->error_func;
  198. call->app_aemap_func = srv->aemap_func;
  199. ret = srv->new_call(call);
  200. /* send an abort if an error occurred */
  201. if (ret < 0) {
  202. rxrpc_call_abort(call, ret);
  203. }
  204. else {
  205. /* formally receive and ACK the new packet */
  206. ret = rxrpc_conn_receive_call_packet(call->conn,
  207. call, msg);
  208. }
  209. }
  210. rxrpc_put_call(call);
  211. out:
  212. if (ret < 0)
  213. rxrpc_trans_immediate_abort(trans, msg, ret);
  214. _leave(" (%d)", ret);
  215. } /* end rxrpc_krxsecd_process_incoming_call() */