svr-session.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. /*
  2. * Dropbear - a SSH2 server
  3. *
  4. * Copyright (c) 2002,2003 Matt Johnston
  5. * All rights reserved.
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a copy
  8. * of this software and associated documentation files (the "Software"), to deal
  9. * in the Software without restriction, including without limitation the rights
  10. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. * copies of the Software, and to permit persons to whom the Software is
  12. * furnished to do so, subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be included in
  15. * all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  23. * SOFTWARE. */
  24. #include "includes.h"
  25. #include "session.h"
  26. #include "dbutil.h"
  27. #include "packet.h"
  28. #include "algo.h"
  29. #include "buffer.h"
  30. #include "dss.h"
  31. #include "ssh.h"
  32. #include "dbrandom.h"
  33. #include "kex.h"
  34. #include "channel.h"
  35. #include "chansession.h"
  36. #include "atomicio.h"
  37. #include "tcpfwd.h"
  38. #include "service.h"
  39. #include "auth.h"
  40. #include "runopts.h"
  41. #include "crypto_desc.h"
  42. static void svr_remoteclosed(void);
  43. struct serversession svr_ses; /* GLOBAL */
  44. static const packettype svr_packettypes[] = {
  45. {SSH_MSG_CHANNEL_DATA, recv_msg_channel_data},
  46. {SSH_MSG_CHANNEL_WINDOW_ADJUST, recv_msg_channel_window_adjust},
  47. {SSH_MSG_USERAUTH_REQUEST, recv_msg_userauth_request}, /* server */
  48. {SSH_MSG_SERVICE_REQUEST, recv_msg_service_request}, /* server */
  49. {SSH_MSG_KEXINIT, recv_msg_kexinit},
  50. {SSH_MSG_KEXDH_INIT, recv_msg_kexdh_init}, /* server */
  51. {SSH_MSG_NEWKEYS, recv_msg_newkeys},
  52. {SSH_MSG_GLOBAL_REQUEST, recv_msg_global_request_remotetcp},
  53. {SSH_MSG_CHANNEL_REQUEST, recv_msg_channel_request},
  54. {SSH_MSG_CHANNEL_OPEN, recv_msg_channel_open},
  55. {SSH_MSG_CHANNEL_EOF, recv_msg_channel_eof},
  56. {SSH_MSG_CHANNEL_CLOSE, recv_msg_channel_close},
  57. {SSH_MSG_CHANNEL_SUCCESS, ignore_recv_response},
  58. {SSH_MSG_CHANNEL_FAILURE, ignore_recv_response},
  59. {SSH_MSG_REQUEST_FAILURE, ignore_recv_response}, /* for keepalive */
  60. {SSH_MSG_REQUEST_SUCCESS, ignore_recv_response}, /* client */
  61. #ifdef USING_LISTENERS
  62. {SSH_MSG_CHANNEL_OPEN_CONFIRMATION, recv_msg_channel_open_confirmation},
  63. {SSH_MSG_CHANNEL_OPEN_FAILURE, recv_msg_channel_open_failure},
  64. #endif
  65. {0, 0} /* End */
  66. };
  67. static const struct ChanType *svr_chantypes[] = {
  68. &svrchansess,
  69. #ifdef ENABLE_SVR_LOCALTCPFWD
  70. &svr_chan_tcpdirect,
  71. #endif
  72. NULL /* Null termination is mandatory. */
  73. };
  74. static void
  75. svr_session_cleanup(void) {
  76. /* free potential public key options */
  77. svr_pubkey_options_cleanup();
  78. m_free(svr_ses.addrstring);
  79. m_free(svr_ses.remotehost);
  80. m_free(svr_ses.childpids);
  81. svr_ses.childpidsize = 0;
  82. }
  83. void svr_session(int sock, int childpipe) {
  84. char *host, *port;
  85. size_t len;
  86. common_session_init(sock, sock);
  87. /* Initialise server specific parts of the session */
  88. svr_ses.childpipe = childpipe;
  89. #ifdef USE_VFORK
  90. svr_ses.server_pid = getpid();
  91. #endif
  92. svr_authinitialise();
  93. chaninitialise(svr_chantypes);
  94. svr_chansessinitialise();
  95. /* for logging the remote address */
  96. get_socket_address(ses.sock_in, NULL, NULL, &host, &port, 0);
  97. len = strlen(host) + strlen(port) + 2;
  98. svr_ses.addrstring = m_malloc(len);
  99. snprintf(svr_ses.addrstring, len, "%s:%s", host, port);
  100. m_free(host);
  101. m_free(port);
  102. get_socket_address(ses.sock_in, NULL, NULL,
  103. &svr_ses.remotehost, NULL, 1);
  104. /* set up messages etc */
  105. ses.remoteclosed = svr_remoteclosed;
  106. ses.extra_session_cleanup = svr_session_cleanup;
  107. /* packet handlers */
  108. ses.packettypes = svr_packettypes;
  109. ses.isserver = 1;
  110. /* We're ready to go now */
  111. sessinitdone = 1;
  112. /* exchange identification, version etc */
  113. send_session_identification();
  114. kexfirstinitialise(); /* initialise the kex state */
  115. /* start off with key exchange */
  116. send_msg_kexinit();
  117. /* Run the main for loop. NULL is for the dispatcher - only the client
  118. * code makes use of it */
  119. session_loop(NULL);
  120. /* Not reached */
  121. }
  122. /* failure exit - format must be <= 100 chars */
  123. void svr_dropbear_exit(int exitcode, const char* format, va_list param) {
  124. char exitmsg[150];
  125. char fullmsg[300];
  126. int i;
  127. /* Render the formatted exit message */
  128. vsnprintf(exitmsg, sizeof(exitmsg), format, param);
  129. /* Add the prefix depending on session/auth state */
  130. if (!sessinitdone) {
  131. /* before session init */
  132. snprintf(fullmsg, sizeof(fullmsg), "Early exit: %s", exitmsg);
  133. } else if (ses.authstate.authdone) {
  134. /* user has authenticated */
  135. snprintf(fullmsg, sizeof(fullmsg),
  136. "Exit (%s): %s",
  137. ses.authstate.pw_name, exitmsg);
  138. } else if (ses.authstate.pw_name) {
  139. /* we have a potential user */
  140. snprintf(fullmsg, sizeof(fullmsg),
  141. "Exit before auth (user '%s', %u fails): %s",
  142. ses.authstate.pw_name, ses.authstate.failcount, exitmsg);
  143. } else {
  144. /* before userauth */
  145. snprintf(fullmsg, sizeof(fullmsg), "Exit before auth: %s", exitmsg);
  146. }
  147. dropbear_log(LOG_INFO, "%s", fullmsg);
  148. #ifdef USE_VFORK
  149. /* For uclinux only the main server process should cleanup - we don't want
  150. * forked children doing that */
  151. if (svr_ses.server_pid == getpid())
  152. #endif
  153. {
  154. /* must be after we've done with username etc */
  155. session_cleanup();
  156. }
  157. if (svr_opts.hostkey) {
  158. sign_key_free(svr_opts.hostkey);
  159. svr_opts.hostkey = NULL;
  160. }
  161. for (i = 0; i < DROPBEAR_MAX_PORTS; i++) {
  162. m_free(svr_opts.addresses[i]);
  163. m_free(svr_opts.ports[i]);
  164. }
  165. exit(exitcode);
  166. }
  167. /* priority is priority as with syslog() */
  168. void svr_dropbear_log(int priority, const char* format, va_list param) {
  169. char printbuf[1024];
  170. char datestr[20];
  171. time_t timesec;
  172. int havetrace = 0;
  173. vsnprintf(printbuf, sizeof(printbuf), format, param);
  174. #ifndef DISABLE_SYSLOG
  175. if (opts.usingsyslog) {
  176. syslog(priority, "%s", printbuf);
  177. }
  178. #endif
  179. /* if we are using DEBUG_TRACE, we want to print to stderr even if
  180. * syslog is used, so it is included in error reports */
  181. #ifdef DEBUG_TRACE
  182. havetrace = debug_trace;
  183. #endif
  184. if (!opts.usingsyslog || havetrace) {
  185. struct tm * local_tm = NULL;
  186. timesec = time(NULL);
  187. local_tm = localtime(&timesec);
  188. if (local_tm == NULL
  189. || strftime(datestr, sizeof(datestr), "%b %d %H:%M:%S",
  190. local_tm) == 0)
  191. {
  192. /* upon failure, just print the epoch-seconds time. */
  193. snprintf(datestr, sizeof(datestr), "%d", (int)timesec);
  194. }
  195. fprintf(stderr, "[%d] %s %s\n", getpid(), datestr, printbuf);
  196. }
  197. }
  198. /* called when the remote side closes the connection */
  199. static void svr_remoteclosed() {
  200. m_close(ses.sock_in);
  201. m_close(ses.sock_out);
  202. ses.sock_in = -1;
  203. ses.sock_out = -1;
  204. dropbear_close("Exited normally");
  205. }