Mercurial > dropbear
annotate cli-session.c @ 43:942b22d7dd1c
Banner printing
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Mon, 02 Aug 2004 04:25:05 +0000 |
parents | 18eccbfb9641 |
children | 9ee8996a375f |
rev | line source |
---|---|
26 | 1 #include "includes.h" |
2 #include "session.h" | |
3 #include "dbutil.h" | |
4 #include "kex.h" | |
5 #include "ssh.h" | |
6 #include "packet.h" | |
7 #include "tcpfwd-direct.h" | |
8 #include "tcpfwd-remote.h" | |
9 #include "channel.h" | |
10 #include "random.h" | |
33 | 11 #include "service.h" |
40
b4874d772210
- Added terminal mode handling etc for the client, and window change
Matt Johnston <matt@ucc.asn.au>
parents:
39
diff
changeset
|
12 #include "runopts.h" |
b4874d772210
- Added terminal mode handling etc for the client, and window change
Matt Johnston <matt@ucc.asn.au>
parents:
39
diff
changeset
|
13 #include "chansession.h" |
26 | 14 |
15 static void cli_remoteclosed(); | |
16 static void cli_sessionloop(); | |
33 | 17 static void cli_session_init(); |
40
b4874d772210
- Added terminal mode handling etc for the client, and window change
Matt Johnston <matt@ucc.asn.au>
parents:
39
diff
changeset
|
18 static void cli_finished(); |
26 | 19 |
20 struct clientsession cli_ses; /* GLOBAL */ | |
21 | |
22 static const packettype cli_packettypes[] = { | |
23 /* TYPE, AUTHREQUIRED, FUNCTION */ | |
24 {SSH_MSG_KEXINIT, recv_msg_kexinit}, | |
25 {SSH_MSG_KEXDH_REPLY, recv_msg_kexdh_reply}, // client | |
26 {SSH_MSG_NEWKEYS, recv_msg_newkeys}, | |
34
e2a1eaa19f22
Client mostly works up to password auth
Matt Johnston <matt@ucc.asn.au>
parents:
33
diff
changeset
|
27 {SSH_MSG_SERVICE_ACCEPT, recv_msg_service_accept}, // client |
26 | 28 {SSH_MSG_CHANNEL_DATA, recv_msg_channel_data}, |
29 {SSH_MSG_CHANNEL_WINDOW_ADJUST, recv_msg_channel_window_adjust}, | |
30 {SSH_MSG_GLOBAL_REQUEST, recv_msg_global_request_remotetcp}, | |
31 {SSH_MSG_CHANNEL_REQUEST, recv_msg_channel_request}, | |
32 {SSH_MSG_CHANNEL_OPEN, recv_msg_channel_open}, | |
33 {SSH_MSG_CHANNEL_EOF, recv_msg_channel_eof}, | |
34 {SSH_MSG_CHANNEL_CLOSE, recv_msg_channel_close}, | |
35 {SSH_MSG_CHANNEL_OPEN_CONFIRMATION, recv_msg_channel_open_confirmation}, | |
36 {SSH_MSG_CHANNEL_OPEN_FAILURE, recv_msg_channel_open_failure}, | |
34
e2a1eaa19f22
Client mostly works up to password auth
Matt Johnston <matt@ucc.asn.au>
parents:
33
diff
changeset
|
37 {SSH_MSG_USERAUTH_FAILURE, recv_msg_userauth_failure}, // client |
e2a1eaa19f22
Client mostly works up to password auth
Matt Johnston <matt@ucc.asn.au>
parents:
33
diff
changeset
|
38 {SSH_MSG_USERAUTH_SUCCESS, recv_msg_userauth_success}, // client |
43 | 39 {SSH_MSG_USERAUTH_BANNER, recv_msg_userauth_banner}, // client |
26 | 40 {0, 0} /* End */ |
41 }; | |
42 | |
43 static const struct ChanType *cli_chantypes[] = { | |
44 /* &chan_tcpdirect etc, though need to only allow if we've requested | |
45 * that forwarding */ | |
46 NULL /* Null termination */ | |
47 }; | |
33 | 48 |
26 | 49 void cli_session(int sock, char* remotehost) { |
50 | |
51 crypto_init(); | |
52 common_session_init(sock, remotehost); | |
53 | |
54 chaninitialise(cli_chantypes); | |
55 | |
56 | |
33 | 57 /* Set up cli_ses vars */ |
58 cli_session_init(); | |
26 | 59 |
60 /* Ready to go */ | |
61 sessinitdone = 1; | |
62 | |
63 /* Exchange identification */ | |
64 session_identification(); | |
65 | |
66 seedrandom(); | |
67 | |
68 send_msg_kexinit(); | |
69 | |
70 /* XXX here we do stuff differently */ | |
71 | |
72 session_loop(cli_sessionloop); | |
73 | |
74 /* Not reached */ | |
75 | |
33 | 76 } |
26 | 77 |
33 | 78 static void cli_session_init() { |
79 | |
80 cli_ses.state = STATE_NOTHING; | |
81 cli_ses.kex_state = KEX_NOTHING; | |
82 | |
39
0883c0906870
tty raw mode support works mostly
Matt Johnston <matt@ucc.asn.au>
parents:
37
diff
changeset
|
83 cli_ses.tty_raw_mode = 0; |
41
18eccbfb9641
added window-size change handling
Matt Johnston <matt@ucc.asn.au>
parents:
40
diff
changeset
|
84 cli_ses.winchange = 0; |
39
0883c0906870
tty raw mode support works mostly
Matt Johnston <matt@ucc.asn.au>
parents:
37
diff
changeset
|
85 |
33 | 86 /* For printing "remote host closed" for the user */ |
87 ses.remoteclosed = cli_remoteclosed; | |
88 ses.buf_match_algo = cli_buf_match_algo; | |
89 | |
90 /* packet handlers */ | |
91 ses.packettypes = cli_packettypes; | |
35
0ad5fb979f42
set the isserver flag (oops)
Matt Johnston <matt@ucc.asn.au>
parents:
34
diff
changeset
|
92 |
0ad5fb979f42
set the isserver flag (oops)
Matt Johnston <matt@ucc.asn.au>
parents:
34
diff
changeset
|
93 ses.isserver = 0; |
26 | 94 } |
95 | |
33 | 96 /* This function drives the progress of the session - it initiates KEX, |
97 * service, userauth and channel requests */ | |
26 | 98 static void cli_sessionloop() { |
99 | |
33 | 100 TRACE(("enter cli_sessionloop")); |
101 | |
34
e2a1eaa19f22
Client mostly works up to password auth
Matt Johnston <matt@ucc.asn.au>
parents:
33
diff
changeset
|
102 if (ses.lastpacket == SSH_MSG_KEXINIT && cli_ses.kex_state == KEX_NOTHING) { |
e2a1eaa19f22
Client mostly works up to password auth
Matt Johnston <matt@ucc.asn.au>
parents:
33
diff
changeset
|
103 cli_ses.kex_state = KEXINIT_RCVD; |
33 | 104 } |
105 | |
34
e2a1eaa19f22
Client mostly works up to password auth
Matt Johnston <matt@ucc.asn.au>
parents:
33
diff
changeset
|
106 if (cli_ses.kex_state == KEXINIT_RCVD) { |
33 | 107 |
108 /* We initiate the KEXDH. If DH wasn't the correct type, the KEXINIT | |
109 * negotiation would have failed. */ | |
110 send_msg_kexdh_init(); | |
111 cli_ses.kex_state = KEXDH_INIT_SENT; | |
112 TRACE(("leave cli_sessionloop: done with KEXINIT_RCVD")); | |
113 return; | |
114 } | |
115 | |
116 /* A KEX has finished, so we should go back to our KEX_NOTHING state */ | |
117 if (cli_ses.kex_state != KEX_NOTHING && ses.kexstate.recvkexinit == 0 | |
118 && ses.kexstate.sentkexinit == 0) { | |
119 cli_ses.kex_state = KEX_NOTHING; | |
120 } | |
121 | |
122 /* We shouldn't do anything else if a KEX is in progress */ | |
123 if (cli_ses.kex_state != KEX_NOTHING) { | |
124 TRACE(("leave cli_sessionloop: kex_state != KEX_NOTHING")); | |
125 return; | |
126 } | |
127 | |
128 /* We should exit if we haven't donefirstkex: we shouldn't reach here | |
129 * in normal operation */ | |
130 if (ses.kexstate.donefirstkex == 0) { | |
131 TRACE(("XXX XXX might be bad! leave cli_sessionloop: haven't donefirstkex")); | |
34
e2a1eaa19f22
Client mostly works up to password auth
Matt Johnston <matt@ucc.asn.au>
parents:
33
diff
changeset
|
132 return; |
33 | 133 } |
134 | |
26 | 135 switch (cli_ses.state) { |
136 | |
33 | 137 case STATE_NOTHING: |
138 /* We've got the transport layer sorted, we now need to request | |
139 * userauth */ | |
140 send_msg_service_request(SSH_SERVICE_USERAUTH); | |
141 cli_ses.state = SERVICE_AUTH_REQ_SENT; | |
34
e2a1eaa19f22
Client mostly works up to password auth
Matt Johnston <matt@ucc.asn.au>
parents:
33
diff
changeset
|
142 TRACE(("leave cli_sessionloop: sent userauth service req")); |
33 | 143 return; |
26 | 144 |
33 | 145 /* userauth code */ |
146 case SERVICE_AUTH_ACCEPT_RCVD: | |
147 cli_auth_getmethods(); | |
148 cli_ses.state = USERAUTH_METHODS_SENT; | |
34
e2a1eaa19f22
Client mostly works up to password auth
Matt Johnston <matt@ucc.asn.au>
parents:
33
diff
changeset
|
149 TRACE(("leave cli_sessionloop: sent userauth methods req")); |
33 | 150 return; |
151 | |
152 case USERAUTH_FAIL_RCVD: | |
153 cli_auth_try(); | |
34
e2a1eaa19f22
Client mostly works up to password auth
Matt Johnston <matt@ucc.asn.au>
parents:
33
diff
changeset
|
154 TRACE(("leave cli_sessionloop: cli_auth_try")); |
33 | 155 return; |
156 | |
37 | 157 /* |
158 case USERAUTH_SUCCESS_RCVD: | |
159 send_msg_service_request(SSH_SERVICE_CONNECTION); | |
160 cli_ses.state = SERVICE_CONN_REQ_SENT; | |
161 TRACE(("leave cli_sessionloop: sent ssh-connection service req")); | |
162 return; | |
163 */ | |
164 | |
165 case USERAUTH_SUCCESS_RCVD: | |
166 cli_send_chansess_request(); | |
167 TRACE(("leave cli_sessionloop: cli_send_chansess_request")); | |
168 cli_ses.state = SESSION_RUNNING; | |
169 return; | |
170 | |
40
b4874d772210
- Added terminal mode handling etc for the client, and window change
Matt Johnston <matt@ucc.asn.au>
parents:
39
diff
changeset
|
171 case SESSION_RUNNING: |
b4874d772210
- Added terminal mode handling etc for the client, and window change
Matt Johnston <matt@ucc.asn.au>
parents:
39
diff
changeset
|
172 if (ses.chancount < 1) { |
b4874d772210
- Added terminal mode handling etc for the client, and window change
Matt Johnston <matt@ucc.asn.au>
parents:
39
diff
changeset
|
173 cli_finished(); |
b4874d772210
- Added terminal mode handling etc for the client, and window change
Matt Johnston <matt@ucc.asn.au>
parents:
39
diff
changeset
|
174 } |
41
18eccbfb9641
added window-size change handling
Matt Johnston <matt@ucc.asn.au>
parents:
40
diff
changeset
|
175 |
18eccbfb9641
added window-size change handling
Matt Johnston <matt@ucc.asn.au>
parents:
40
diff
changeset
|
176 if (cli_ses.winchange) { |
18eccbfb9641
added window-size change handling
Matt Johnston <matt@ucc.asn.au>
parents:
40
diff
changeset
|
177 cli_chansess_winchange(); |
18eccbfb9641
added window-size change handling
Matt Johnston <matt@ucc.asn.au>
parents:
40
diff
changeset
|
178 } |
40
b4874d772210
- Added terminal mode handling etc for the client, and window change
Matt Johnston <matt@ucc.asn.au>
parents:
39
diff
changeset
|
179 return; |
b4874d772210
- Added terminal mode handling etc for the client, and window change
Matt Johnston <matt@ucc.asn.au>
parents:
39
diff
changeset
|
180 |
33 | 181 /* XXX more here needed */ |
182 | |
183 | |
184 default: | |
185 break; | |
26 | 186 } |
187 | |
34
e2a1eaa19f22
Client mostly works up to password auth
Matt Johnston <matt@ucc.asn.au>
parents:
33
diff
changeset
|
188 TRACE(("leave cli_sessionloop: fell out")); |
26 | 189 |
190 } | |
191 | |
40
b4874d772210
- Added terminal mode handling etc for the client, and window change
Matt Johnston <matt@ucc.asn.au>
parents:
39
diff
changeset
|
192 void cli_session_cleanup() { |
b4874d772210
- Added terminal mode handling etc for the client, and window change
Matt Johnston <matt@ucc.asn.au>
parents:
39
diff
changeset
|
193 |
b4874d772210
- Added terminal mode handling etc for the client, and window change
Matt Johnston <matt@ucc.asn.au>
parents:
39
diff
changeset
|
194 if (!sessinitdone) { |
b4874d772210
- Added terminal mode handling etc for the client, and window change
Matt Johnston <matt@ucc.asn.au>
parents:
39
diff
changeset
|
195 return; |
b4874d772210
- Added terminal mode handling etc for the client, and window change
Matt Johnston <matt@ucc.asn.au>
parents:
39
diff
changeset
|
196 } |
b4874d772210
- Added terminal mode handling etc for the client, and window change
Matt Johnston <matt@ucc.asn.au>
parents:
39
diff
changeset
|
197 cli_tty_cleanup(); |
b4874d772210
- Added terminal mode handling etc for the client, and window change
Matt Johnston <matt@ucc.asn.au>
parents:
39
diff
changeset
|
198 |
b4874d772210
- Added terminal mode handling etc for the client, and window change
Matt Johnston <matt@ucc.asn.au>
parents:
39
diff
changeset
|
199 } |
b4874d772210
- Added terminal mode handling etc for the client, and window change
Matt Johnston <matt@ucc.asn.au>
parents:
39
diff
changeset
|
200 |
b4874d772210
- Added terminal mode handling etc for the client, and window change
Matt Johnston <matt@ucc.asn.au>
parents:
39
diff
changeset
|
201 static void cli_finished() { |
b4874d772210
- Added terminal mode handling etc for the client, and window change
Matt Johnston <matt@ucc.asn.au>
parents:
39
diff
changeset
|
202 |
b4874d772210
- Added terminal mode handling etc for the client, and window change
Matt Johnston <matt@ucc.asn.au>
parents:
39
diff
changeset
|
203 cli_session_cleanup(); |
b4874d772210
- Added terminal mode handling etc for the client, and window change
Matt Johnston <matt@ucc.asn.au>
parents:
39
diff
changeset
|
204 common_session_cleanup(); |
b4874d772210
- Added terminal mode handling etc for the client, and window change
Matt Johnston <matt@ucc.asn.au>
parents:
39
diff
changeset
|
205 fprintf(stderr, "Connection to %s@%s:%s closed.\n", cli_opts.username, |
b4874d772210
- Added terminal mode handling etc for the client, and window change
Matt Johnston <matt@ucc.asn.au>
parents:
39
diff
changeset
|
206 cli_opts.remotehost, cli_opts.remoteport); |
b4874d772210
- Added terminal mode handling etc for the client, and window change
Matt Johnston <matt@ucc.asn.au>
parents:
39
diff
changeset
|
207 exit(EXIT_SUCCESS); |
b4874d772210
- Added terminal mode handling etc for the client, and window change
Matt Johnston <matt@ucc.asn.au>
parents:
39
diff
changeset
|
208 } |
b4874d772210
- Added terminal mode handling etc for the client, and window change
Matt Johnston <matt@ucc.asn.au>
parents:
39
diff
changeset
|
209 |
b4874d772210
- Added terminal mode handling etc for the client, and window change
Matt Johnston <matt@ucc.asn.au>
parents:
39
diff
changeset
|
210 |
b4874d772210
- Added terminal mode handling etc for the client, and window change
Matt Johnston <matt@ucc.asn.au>
parents:
39
diff
changeset
|
211 |
26 | 212 /* called when the remote side closes the connection */ |
213 static void cli_remoteclosed() { | |
214 | |
215 /* XXX TODO perhaps print a friendlier message if we get this but have | |
216 * already sent/received disconnect message(s) ??? */ | |
217 close(ses.sock); | |
218 ses.sock = -1; | |
33 | 219 dropbear_exit("remote closed the connection"); |
26 | 220 } |
43 | 221 |
222 /* Operates in-place turning dirty (untrusted potentially containing control | |
223 * characters) text into clean text. */ | |
224 void cleantext(unsigned char* dirtytext) { | |
225 | |
226 unsigned int i, j; | |
227 unsigned char c, lastchar; | |
228 | |
229 j = 0; | |
230 for (i = 0; dirtytext[i] != '\0'; i++) { | |
231 | |
232 c = dirtytext[i]; | |
233 /* We can ignore '\r's */ | |
234 if ( (c >= ' ' && c <= '~') || c == '\n' || c == '\t') { | |
235 dirtytext[j] = c; | |
236 j++; | |
237 } | |
238 } | |
239 /* Null terminate */ | |
240 dirtytext[j] = '\0'; | |
241 } |