Mercurial > dropbear
comparison svr-session.c @ 285:1b9e69c058d2
propagate from branch 'au.asn.ucc.matt.ltc.dropbear' (head 20dccfc09627970a312d77fb41dc2970b62689c3)
to branch 'au.asn.ucc.matt.dropbear' (head fdf4a7a3b97ae5046139915de7e40399cceb2c01)
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Wed, 08 Mar 2006 13:23:58 +0000 |
parents | 3be7ae2e8dfa |
children | 973fccb59ea4 a588558bfc94 |
comparison
equal
deleted
inserted
replaced
281:997e6f7dc01e | 285:1b9e69c058d2 |
---|---|
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 | |
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" | |
42 | |
43 static void svr_remoteclosed(); | |
44 | |
45 struct serversession svr_ses; /* GLOBAL */ | |
46 | |
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 */ | |
67 }; | |
68 | |
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. */ | |
75 }; | |
76 | |
77 void svr_session(int sock, int childpipe, | |
78 char* remotehost, char *addrstring) { | |
79 | |
80 struct timeval timeout; | |
81 | |
82 reseedrandom(); | |
83 | |
84 crypto_init(); | |
85 common_session_init(sock, remotehost); | |
86 | |
87 /* Initialise server specific parts of the session */ | |
88 svr_ses.childpipe = childpipe; | |
89 svr_ses.addrstring = addrstring; | |
90 svr_authinitialise(); | |
91 chaninitialise(svr_chantypes); | |
92 svr_chansessinitialise(); | |
93 | |
94 if (gettimeofday(&timeout, 0) < 0) { | |
95 dropbear_exit("Error getting time"); | |
96 } | |
97 | |
98 ses.connecttimeout = timeout.tv_sec + AUTH_TIMEOUT; | |
99 | |
100 /* set up messages etc */ | |
101 ses.remoteclosed = svr_remoteclosed; | |
102 | |
103 /* packet handlers */ | |
104 ses.packettypes = svr_packettypes; | |
105 ses.buf_match_algo = svr_buf_match_algo; | |
106 | |
107 ses.isserver = 1; | |
108 | |
109 /* We're ready to go now */ | |
110 sessinitdone = 1; | |
111 | |
112 /* exchange identification, version etc */ | |
113 session_identification(); | |
114 | |
115 /* start off with key exchange */ | |
116 send_msg_kexinit(); | |
117 | |
118 /* Run the main for loop. NULL is for the dispatcher - only the client | |
119 * code makes use of it */ | |
120 session_loop(NULL); | |
121 | |
122 /* Not reached */ | |
123 | |
124 } | |
125 | |
126 /* failure exit - format must be <= 100 chars */ | |
127 void svr_dropbear_exit(int exitcode, const char* format, va_list param) { | |
128 | |
129 char fmtbuf[300]; | |
130 | |
131 if (!sessinitdone) { | |
132 /* before session init */ | |
133 snprintf(fmtbuf, sizeof(fmtbuf), | |
134 "premature exit: %s", format); | |
135 } else if (ses.authstate.authdone) { | |
136 /* user has authenticated */ | |
137 snprintf(fmtbuf, sizeof(fmtbuf), | |
138 "exit after auth (%s): %s", | |
139 ses.authstate.printableuser, format); | |
140 } else if (ses.authstate.printableuser) { | |
141 /* we have a potential user */ | |
142 snprintf(fmtbuf, sizeof(fmtbuf), | |
143 "exit before auth (user '%s', %d fails): %s", | |
144 ses.authstate.printableuser, ses.authstate.failcount, format); | |
145 } else { | |
146 /* before userauth */ | |
147 snprintf(fmtbuf, sizeof(fmtbuf), | |
148 "exit before auth: %s", format); | |
149 } | |
150 | |
151 _dropbear_log(LOG_INFO, fmtbuf, param); | |
152 | |
153 /* must be after we've done with username etc */ | |
154 common_session_cleanup(); | |
155 | |
156 exit(exitcode); | |
157 | |
158 } | |
159 | |
160 /* priority is priority as with syslog() */ | |
161 void svr_dropbear_log(int priority, const char* format, va_list param) { | |
162 | |
163 char printbuf[1024]; | |
164 char datestr[20]; | |
165 time_t timesec; | |
166 int havetrace = 0; | |
167 | |
168 vsnprintf(printbuf, sizeof(printbuf), format, param); | |
169 | |
170 #ifndef DISABLE_SYSLOG | |
171 if (svr_opts.usingsyslog) { | |
172 syslog(priority, "%s", printbuf); | |
173 } | |
174 #endif | |
175 | |
176 /* if we are using DEBUG_TRACE, we want to print to stderr even if | |
177 * syslog is used, so it is included in error reports */ | |
178 #ifdef DEBUG_TRACE | |
179 havetrace = debug_trace; | |
180 #endif | |
181 | |
182 if (!svr_opts.usingsyslog || havetrace) | |
183 { | |
184 timesec = time(NULL); | |
185 if (strftime(datestr, sizeof(datestr), "%b %d %H:%M:%S", | |
186 localtime(×ec)) == 0) { | |
187 datestr[0] = '?'; datestr[1] = '\0'; | |
188 } | |
189 fprintf(stderr, "[%d] %s %s\n", getpid(), datestr, printbuf); | |
190 } | |
191 } | |
192 | |
193 /* called when the remote side closes the connection */ | |
194 static void svr_remoteclosed() { | |
195 | |
196 close(ses.sock); | |
197 ses.sock = -1; | |
198 dropbear_close("Exited normally"); | |
199 | |
200 } | |
201 |