Mercurial > dropbear
comparison svr-session.c @ 4:fe6bca95afa7
Makefile.in contains updated files required
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Tue, 01 Jun 2004 02:46:09 +0000 |
parents | |
children | bc6477a6c393 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 4:fe6bca95afa7 |
---|---|
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 | |
39 static void svr_remoteclosed(); | |
40 static void svr_dropbear_exit(int exitcode, const char* format, va_list param); | |
41 static void svr_dropbear_log(int priority, const char* format, va_list param); | |
42 | |
43 struct serversession svr_ses; | |
44 | |
45 void svr_session(int sock, runopts *opts, int childpipe, | |
46 struct sockaddr* remoteaddr) { | |
47 | |
48 fd_set readfd, writefd; | |
49 struct timeval timeout; | |
50 int val; | |
51 | |
52 crypto_init(); | |
53 common_session_init(sock, opts); | |
54 | |
55 ses.remoteaddr = remoteaddr; | |
56 ses.remotehost = getaddrhostname(remoteaddr); | |
57 | |
58 /* Initialise server specific parts of the session */ | |
59 svr_ses.childpipe = childpipe; | |
60 authinitialise(); | |
61 svr_chansessinitialise(); | |
62 | |
63 if (gettimeofday(&timeout, 0) < 0) { | |
64 dropbear_exit("Error getting time"); | |
65 } | |
66 | |
67 ses.connecttimeout = timeout.tv_sec + AUTH_TIMEOUT; | |
68 | |
69 /* set up messages etc */ | |
70 session_remoteclosed = svr_remoteclosed; | |
71 _dropbear_exit = svr_dropbear_exit; | |
72 _dropbear_log = svr_dropbear_log; | |
73 | |
74 /* We're ready to go now */ | |
75 sessinitdone = 1; | |
76 | |
77 /* exchange identification, version etc */ | |
78 session_identification(); | |
79 | |
80 seedrandom(); | |
81 | |
82 /* start off with key exchange */ | |
83 send_msg_kexinit(); | |
84 | |
85 FD_ZERO(&readfd); | |
86 FD_ZERO(&writefd); | |
87 | |
88 /* main loop, select()s for all sockets in use */ | |
89 for(;;) { | |
90 | |
91 timeout.tv_sec = SELECT_TIMEOUT; | |
92 timeout.tv_usec = 0; | |
93 FD_ZERO(&writefd); | |
94 FD_ZERO(&readfd); | |
95 assert(ses.payload == NULL); | |
96 if (ses.sock != -1) { | |
97 FD_SET(ses.sock, &readfd); | |
98 if (!isempty(&ses.writequeue)) { | |
99 FD_SET(ses.sock, &writefd); | |
100 } | |
101 } | |
102 | |
103 /* set up for channels which require reading/writing */ | |
104 if (ses.dataallowed) { | |
105 setchannelfds(&readfd, &writefd); | |
106 } | |
107 val = select(ses.maxfd+1, &readfd, &writefd, NULL, &timeout); | |
108 | |
109 if (exitflag) { | |
110 dropbear_exit("Terminated by signal"); | |
111 } | |
112 | |
113 if (val < 0) { | |
114 if (errno == EINTR) { | |
115 continue; | |
116 } else { | |
117 dropbear_exit("Error in select"); | |
118 } | |
119 } | |
120 | |
121 /* check for auth timeout, rekeying required etc */ | |
122 checktimeouts(); | |
123 | |
124 if (val == 0) { | |
125 /* timeout */ | |
126 TRACE(("select timeout")); | |
127 continue; | |
128 } | |
129 | |
130 /* process session socket's incoming/outgoing data */ | |
131 if (ses.sock != -1) { | |
132 if (FD_ISSET(ses.sock, &writefd) && !isempty(&ses.writequeue)) { | |
133 write_packet(); | |
134 } | |
135 | |
136 if (FD_ISSET(ses.sock, &readfd)) { | |
137 read_packet(); | |
138 } | |
139 | |
140 /* Process the decrypted packet. After this, the read buffer | |
141 * will be ready for a new packet */ | |
142 if (ses.payload != NULL) { | |
143 svr_process_packet(); | |
144 } | |
145 } | |
146 | |
147 /* process pipes etc for the channels, ses.dataallowed == 0 | |
148 * during rekeying ) */ | |
149 if (ses.dataallowed) { | |
150 channelio(&readfd, &writefd); | |
151 } | |
152 | |
153 } /* for(;;) */ | |
154 } | |
155 | |
156 | |
157 | |
158 /* called when the remote side closes the connection */ | |
159 static void svr_remoteclosed() { | |
160 | |
161 close(ses.sock); | |
162 ses.sock = -1; | |
163 dropbear_close("Exited normally"); | |
164 | |
165 } | |
166 | |
167 /* failure exit - format must be <= 100 chars */ | |
168 static void svr_dropbear_exit(int exitcode, const char* format, va_list param) { | |
169 | |
170 char fmtbuf[300]; | |
171 | |
172 if (!sessinitdone) { | |
173 /* before session init */ | |
174 snprintf(fmtbuf, sizeof(fmtbuf), | |
175 "premature exit: %s", format); | |
176 } else if (svr_ses.authstate.authdone) { | |
177 /* user has authenticated */ | |
178 snprintf(fmtbuf, sizeof(fmtbuf), | |
179 "exit after auth (%s): %s", | |
180 svr_ses.authstate.printableuser, format); | |
181 } else if (svr_ses.authstate.printableuser) { | |
182 /* we have a potential user */ | |
183 snprintf(fmtbuf, sizeof(fmtbuf), | |
184 "exit before auth (user '%s', %d fails): %s", | |
185 svr_ses.authstate.printableuser, svr_ses.authstate.failcount, format); | |
186 } else { | |
187 /* before userauth */ | |
188 snprintf(fmtbuf, sizeof(fmtbuf), | |
189 "exit before auth: %s", format); | |
190 } | |
191 | |
192 if (errno != 0) { | |
193 /* XXX - is this valid? */ | |
194 snprintf(fmtbuf, sizeof(fmtbuf), "%s [%d %s]", fmtbuf, | |
195 errno, strerror(errno)); | |
196 } | |
197 | |
198 _dropbear_log(LOG_INFO, fmtbuf, param); | |
199 | |
200 /* must be after we've done with username etc */ | |
201 common_session_cleanup(); | |
202 | |
203 exit(exitcode); | |
204 | |
205 } | |
206 | |
207 /* priority is priority as with syslog() */ | |
208 static void svr_dropbear_log(int priority, const char* format, va_list param) { | |
209 | |
210 char printbuf[1024]; | |
211 char datestr[20]; | |
212 time_t timesec; | |
213 int havetrace = 0; | |
214 | |
215 vsnprintf(printbuf, sizeof(printbuf), format, param); | |
216 | |
217 #ifndef DISABLE_SYSLOG | |
218 if (usingsyslog) { | |
219 syslog(priority, "%s", printbuf); | |
220 } | |
221 #endif | |
222 | |
223 /* if we are using DEBUG_TRACE, we want to print to stderr even if | |
224 * syslog is used, so it is included in error reports */ | |
225 #ifdef DEBUG_TRACE | |
226 havetrace = 1; | |
227 #endif | |
228 | |
229 if (!usingsyslog || havetrace) | |
230 { | |
231 timesec = time(NULL); | |
232 if (strftime(datestr, sizeof(datestr), "%b %d %H:%M:%S", | |
233 localtime(×ec)) == 0) { | |
234 datestr[0] = '?'; datestr[1] = '\0'; | |
235 } | |
236 fprintf(stderr, "[%d] %s %s\n", getpid(), datestr, printbuf); | |
237 } | |
238 } |