comparison common-session.c @ 26:0969767bca0d

snapshot of stuff
author Matt Johnston <matt@ucc.asn.au>
date Mon, 26 Jul 2004 02:44:20 +0000
parents 469950e86d0f
children f789045062e6
comparison
equal deleted inserted replaced
25:e4b6e2d569b2 26:0969767bca0d
33 #include "random.h" 33 #include "random.h"
34 #include "kex.h" 34 #include "kex.h"
35 #include "channel.h" 35 #include "channel.h"
36 #include "atomicio.h" 36 #include "atomicio.h"
37 37
38
38 struct sshsession ses; /* GLOBAL */ 39 struct sshsession ses; /* GLOBAL */
39 40
40 /* need to know if the session struct has been initialised, this way isn't the 41 /* need to know if the session struct has been initialised, this way isn't the
41 * cleanest, but works OK */ 42 * cleanest, but works OK */
42 int sessinitdone = 0; /* GLOBAL */ 43 int sessinitdone = 0; /* GLOBAL */
43 44
44 /* this is set when we get SIGINT or SIGTERM, the handler is in main.c */ 45 /* this is set when we get SIGINT or SIGTERM, the handler is in main.c */
45 int exitflag = 0; /* GLOBAL */ 46 int exitflag = 0; /* GLOBAL */
46 47
48 void(*session_remoteclosed)() = NULL;
49
50
51 static void checktimeouts();
47 static int ident_readln(int fd, char* buf, int count); 52 static int ident_readln(int fd, char* buf, int count);
48 53
49
50 void(*session_remoteclosed)() = NULL;
51
52
53 /* called only at the start of a session, set up initial state */ 54 /* called only at the start of a session, set up initial state */
54 void common_session_init(int sock) { 55 void common_session_init(int sock, char* remotehost) {
55 56
56 TRACE(("enter session_init")); 57 TRACE(("enter session_init"));
57 58
58 ses.remoteaddr = NULL; 59 ses.remotehost = remotehost;
59 ses.remotehost = NULL;
60 60
61 ses.sock = sock; 61 ses.sock = sock;
62 ses.maxfd = sock; 62 ses.maxfd = sock;
63 63
64 ses.connecttimeout = 0; 64 ses.connecttimeout = 0;
112 112
113 113
114 TRACE(("leave session_init")); 114 TRACE(("leave session_init"));
115 } 115 }
116 116
117 void session_loop(void(*loophandler)()) {
118
119 fd_set readfd, writefd;
120 struct timeval timeout;
121 int val;
122
123 /* main loop, select()s for all sockets in use */
124 for(;;) {
125
126 timeout.tv_sec = SELECT_TIMEOUT;
127 timeout.tv_usec = 0;
128 FD_ZERO(&writefd);
129 FD_ZERO(&readfd);
130 assert(ses.payload == NULL);
131 if (ses.sock != -1) {
132 FD_SET(ses.sock, &readfd);
133 if (!isempty(&ses.writequeue)) {
134 FD_SET(ses.sock, &writefd);
135 }
136 }
137
138 /* set up for channels which require reading/writing */
139 if (ses.dataallowed) {
140 setchannelfds(&readfd, &writefd);
141 }
142 val = select(ses.maxfd+1, &readfd, &writefd, NULL, &timeout);
143
144 if (exitflag) {
145 dropbear_exit("Terminated by signal");
146 }
147
148 if (val < 0) {
149 if (errno == EINTR) {
150 continue;
151 } else {
152 dropbear_exit("Error in select");
153 }
154 }
155
156 /* check for auth timeout, rekeying required etc */
157 checktimeouts();
158
159 if (val == 0) {
160 /* timeout */
161 TRACE(("select timeout"));
162 continue;
163 }
164
165 /* process session socket's incoming/outgoing data */
166 if (ses.sock != -1) {
167 if (FD_ISSET(ses.sock, &writefd) && !isempty(&ses.writequeue)) {
168 write_packet();
169 }
170
171 if (FD_ISSET(ses.sock, &readfd)) {
172 read_packet();
173 }
174
175 /* Process the decrypted packet. After this, the read buffer
176 * will be ready for a new packet */
177 if (ses.payload != NULL) {
178 process_packet();
179 }
180 }
181
182 /* process pipes etc for the channels, ses.dataallowed == 0
183 * during rekeying ) */
184 if (ses.dataallowed) {
185 channelio(&readfd, &writefd);
186 }
187
188 if (loophandler) {
189 loophandler();
190 }
191
192 } /* for(;;) */
193
194 /* Not reached */
195 }
196
117 /* clean up a session on exit */ 197 /* clean up a session on exit */
118 void common_session_cleanup() { 198 void common_session_cleanup() {
119 199
120 TRACE(("enter session_cleanup")); 200 TRACE(("enter session_cleanup"));
121 201
132 chancleanup(); 212 chancleanup();
133 213
134 TRACE(("leave session_cleanup")); 214 TRACE(("leave session_cleanup"));
135 } 215 }
136 216
137 /* Check all timeouts which are required. Currently these are the time for 217
138 * user authentication, and the automatic rekeying. */
139 void checktimeouts() {
140
141 struct timeval tv;
142 long secs;
143
144 if (gettimeofday(&tv, 0) < 0) {
145 dropbear_exit("Error getting time");
146 }
147
148 secs = tv.tv_sec;
149
150 if (ses.connecttimeout != 0 && secs > ses.connecttimeout) {
151 dropbear_close("Timeout before auth");
152 }
153
154 /* we can't rekey if we haven't done remote ident exchange yet */
155 if (ses.remoteident == NULL) {
156 return;
157 }
158
159 if (!ses.kexstate.sentkexinit
160 && (secs - ses.kexstate.lastkextime >= KEX_REKEY_TIMEOUT
161 || ses.kexstate.datarecv+ses.kexstate.datatrans >= KEX_REKEY_DATA)){
162 TRACE(("rekeying after timeout or max data reached"));
163 send_msg_kexinit();
164 }
165 }
166 void session_identification() { 218 void session_identification() {
167 219
168 /* max length of 255 chars */ 220 /* max length of 255 chars */
169 char linebuf[256]; 221 char linebuf[256];
170 int len = 0; 222 int len = 0;
266 buf[pos] = '\0'; 318 buf[pos] = '\0';
267 TRACE(("leave ident_readln: return %d", pos+1)); 319 TRACE(("leave ident_readln: return %d", pos+1));
268 return pos+1; 320 return pos+1;
269 } 321 }
270 322
323 /* Check all timeouts which are required. Currently these are the time for
324 * user authentication, and the automatic rekeying. */
325 static void checktimeouts() {
326
327 struct timeval tv;
328 long secs;
329
330 if (gettimeofday(&tv, 0) < 0) {
331 dropbear_exit("Error getting time");
332 }
333
334 secs = tv.tv_sec;
335
336 if (ses.connecttimeout != 0 && secs > ses.connecttimeout) {
337 dropbear_close("Timeout before auth");
338 }
339
340 /* we can't rekey if we haven't done remote ident exchange yet */
341 if (ses.remoteident == NULL) {
342 return;
343 }
344
345 if (!ses.kexstate.sentkexinit
346 && (secs - ses.kexstate.lastkextime >= KEX_REKEY_TIMEOUT
347 || ses.kexstate.datarecv+ses.kexstate.datatrans >= KEX_REKEY_DATA)){
348 TRACE(("rekeying after timeout or max data reached"));
349 send_msg_kexinit();
350 }
351 }
352