Changes to update Tomato RAF.
[tomato.git] / release / src / router / dropbear / svr-session.c
blob77d167b76df0d1acbf8bbc94352ff0130f8a6031
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:
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
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. */
25 #include "includes.h"
26 #include "session.h"
27 #include "dbutil.h"
28 #include "packet.h"
29 #include "algo.h"
30 #include "buffer.h"
31 #include "dss.h"
32 #include "ssh.h"
33 #include "random.h"
34 #include "kex.h"
35 #include "channel.h"
36 #include "chansession.h"
37 #include "atomicio.h"
38 #include "tcpfwd.h"
39 #include "service.h"
40 #include "auth.h"
41 #include "runopts.h"
43 static void svr_remoteclosed();
45 struct serversession svr_ses; /* GLOBAL */
47 static const packettype svr_packettypes[] = {
48 {SSH_MSG_CHANNEL_DATA, recv_msg_channel_data},
49 {SSH_MSG_CHANNEL_WINDOW_ADJUST, recv_msg_channel_window_adjust},
50 {SSH_MSG_USERAUTH_REQUEST, recv_msg_userauth_request}, /* server */
51 {SSH_MSG_SERVICE_REQUEST, recv_msg_service_request}, /* server */
52 {SSH_MSG_KEXINIT, recv_msg_kexinit},
53 {SSH_MSG_KEXDH_INIT, recv_msg_kexdh_init}, /* server */
54 {SSH_MSG_NEWKEYS, recv_msg_newkeys},
55 #ifdef ENABLE_SVR_REMOTETCPFWD
56 {SSH_MSG_GLOBAL_REQUEST, recv_msg_global_request_remotetcp},
57 #endif
58 {SSH_MSG_CHANNEL_REQUEST, recv_msg_channel_request},
59 {SSH_MSG_CHANNEL_OPEN, recv_msg_channel_open},
60 {SSH_MSG_CHANNEL_EOF, recv_msg_channel_eof},
61 {SSH_MSG_CHANNEL_CLOSE, recv_msg_channel_close},
62 #ifdef USING_LISTENERS
63 {SSH_MSG_CHANNEL_OPEN_CONFIRMATION, recv_msg_channel_open_confirmation},
64 {SSH_MSG_CHANNEL_OPEN_FAILURE, recv_msg_channel_open_failure},
65 #endif
66 {0, 0} /* End */
69 static const struct ChanType *svr_chantypes[] = {
70 &svrchansess,
71 #ifdef ENABLE_SVR_LOCALTCPFWD
72 &svr_chan_tcpdirect,
73 #endif
74 NULL /* Null termination is mandatory. */
77 void svr_session(int sock, int childpipe) {
78 char *host, *port;
79 size_t len;
80 reseedrandom();
82 crypto_init();
83 common_session_init(sock, sock);
85 /* Initialise server specific parts of the session */
86 svr_ses.childpipe = childpipe;
87 #ifdef __uClinux__
88 svr_ses.server_pid = getpid();
89 #endif
90 svr_authinitialise();
91 chaninitialise(svr_chantypes);
92 svr_chansessinitialise();
94 ses.connect_time = time(NULL);
96 /* for logging the remote address */
97 get_socket_address(ses.sock_in, NULL, NULL, &host, &port, 0);
98 len = strlen(host) + strlen(port) + 2;
99 svr_ses.addrstring = m_malloc(len);
100 snprintf(svr_ses.addrstring, len, "%s:%s", host, port);
101 m_free(host);
102 m_free(port);
104 get_socket_address(ses.sock_in, NULL, NULL,
105 &svr_ses.remotehost, NULL, 1);
107 /* set up messages etc */
108 ses.remoteclosed = svr_remoteclosed;
110 /* packet handlers */
111 ses.packettypes = svr_packettypes;
112 ses.buf_match_algo = svr_buf_match_algo;
114 ses.isserver = 1;
116 /* We're ready to go now */
117 sessinitdone = 1;
119 /* exchange identification, version etc */
120 session_identification();
122 /* start off with key exchange */
123 send_msg_kexinit();
125 /* Run the main for loop. NULL is for the dispatcher - only the client
126 * code makes use of it */
127 session_loop(NULL);
129 /* Not reached */
133 /* failure exit - format must be <= 100 chars */
134 void svr_dropbear_exit(int exitcode, const char* format, va_list param) {
136 char fmtbuf[300];
138 if (!sessinitdone) {
139 /* before session init */
140 snprintf(fmtbuf, sizeof(fmtbuf),
141 "Premature exit: %s", format);
142 } else if (ses.authstate.authdone) {
143 /* user has authenticated */
144 snprintf(fmtbuf, sizeof(fmtbuf),
145 "Exit (%s): %s",
146 ses.authstate.pw_name, format);
147 } else if (ses.authstate.pw_name) {
148 /* we have a potential user */
149 snprintf(fmtbuf, sizeof(fmtbuf),
150 "Exit before auth (user '%s', %d fails): %s",
151 ses.authstate.pw_name, ses.authstate.failcount, format);
152 } else {
153 /* before userauth */
154 snprintf(fmtbuf, sizeof(fmtbuf),
155 "Exit before auth: %s", format);
158 _dropbear_log(LOG_INFO, fmtbuf, param);
160 #ifdef __uClinux__
161 /* only the main server process should cleanup - we don't want
162 * forked children doing that */
163 if (svr_ses.server_pid == getpid())
164 #else
165 if (1)
166 #endif
168 /* free potential public key options */
169 svr_pubkey_options_cleanup();
171 /* must be after we've done with username etc */
172 common_session_cleanup();
175 exit(exitcode);
179 /* priority is priority as with syslog() */
180 void svr_dropbear_log(int priority, const char* format, va_list param) {
182 char printbuf[1024];
183 char datestr[20];
184 time_t timesec;
185 int havetrace = 0;
187 vsnprintf(printbuf, sizeof(printbuf), format, param);
189 #ifndef DISABLE_SYSLOG
190 if (svr_opts.usingsyslog) {
191 syslog(priority, "%s", printbuf);
193 #endif
195 /* if we are using DEBUG_TRACE, we want to print to stderr even if
196 * syslog is used, so it is included in error reports */
197 #ifdef DEBUG_TRACE
198 havetrace = debug_trace;
199 #endif
201 if (!svr_opts.usingsyslog || havetrace)
203 struct tm * local_tm = NULL;
204 timesec = time(NULL);
205 local_tm = localtime(&timesec);
206 if (local_tm == NULL
207 || strftime(datestr, sizeof(datestr), "%b %d %H:%M:%S",
208 local_tm) == 0)
210 /* upon failure, just print the epoch-seconds time. */
211 snprintf(datestr, sizeof(datestr), "%d", (int)timesec);
213 fprintf(stderr, "[%d] %s %s\n", getpid(), datestr, printbuf);
217 /* called when the remote side closes the connection */
218 static void svr_remoteclosed() {
220 m_close(ses.sock_in);
221 m_close(ses.sock_out);
222 ses.sock_in = -1;
223 ses.sock_out = -1;
224 dropbear_close("Exited normally");