krxsecd.c 6.8 KB

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