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