Mercurial > dropbear
comparison cli-runopts.c @ 1170:ff9bd50f1457
Bundling for dbclient
author | Guilhem Moulin <guilhem@fripost.org> |
---|---|
date | Mon, 23 Nov 2015 22:28:56 +0800 |
parents | 1b583b2994ba |
children | c745f720ae2e |
comparison
equal
deleted
inserted
replaced
1169:41a5820cab8b | 1170:ff9bd50f1457 |
---|---|
103 } | 103 } |
104 | 104 |
105 void cli_getopts(int argc, char ** argv) { | 105 void cli_getopts(int argc, char ** argv) { |
106 unsigned int i, j; | 106 unsigned int i, j; |
107 char ** next = 0; | 107 char ** next = 0; |
108 enum { | |
109 #ifdef ENABLE_CLI_PUBKEY_AUTH | |
110 OPT_AUTHKEY, | |
111 #endif | |
112 #ifdef ENABLE_CLI_LOCALTCPFWD | |
113 OPT_LOCALTCPFWD, | |
114 #endif | |
115 #ifdef ENABLE_CLI_REMOTETCPFWD | |
116 OPT_REMOTETCPFWD, | |
117 #endif | |
118 #ifdef ENABLE_CLI_NETCAT | |
119 OPT_NETCAT, | |
120 #endif | |
121 /* a flag (no arg) if 'next' is NULL, a string-valued option otherwise */ | |
122 OPT_OTHER | |
123 } opt; | |
108 unsigned int cmdlen; | 124 unsigned int cmdlen; |
109 #ifdef ENABLE_CLI_PUBKEY_AUTH | |
110 int nextiskey = 0; /* A flag if the next argument is a keyfile */ | |
111 #endif | |
112 #ifdef ENABLE_CLI_LOCALTCPFWD | |
113 int nextislocal = 0; | |
114 #endif | |
115 #ifdef ENABLE_CLI_REMOTETCPFWD | |
116 int nextisremote = 0; | |
117 #endif | |
118 #ifdef ENABLE_CLI_NETCAT | |
119 int nextisnetcat = 0; | |
120 #endif | |
121 char* dummy = NULL; /* Not used for anything real */ | 125 char* dummy = NULL; /* Not used for anything real */ |
122 | 126 |
123 char* recv_window_arg = NULL; | 127 char* recv_window_arg = NULL; |
124 char* keepalive_arg = NULL; | 128 char* keepalive_arg = NULL; |
125 char* idle_timeout_arg = NULL; | 129 char* idle_timeout_arg = NULL; |
126 char *host_arg = NULL; | 130 char *host_arg = NULL; |
131 char c; | |
127 | 132 |
128 /* see printhelp() for options */ | 133 /* see printhelp() for options */ |
129 cli_opts.progname = argv[0]; | 134 cli_opts.progname = argv[0]; |
130 cli_opts.remotehost = NULL; | 135 cli_opts.remotehost = NULL; |
131 cli_opts.remoteport = NULL; | 136 cli_opts.remoteport = NULL; |
170 opts.keepalive_secs = DEFAULT_KEEPALIVE; | 175 opts.keepalive_secs = DEFAULT_KEEPALIVE; |
171 opts.idle_timeout_secs = DEFAULT_IDLE_TIMEOUT; | 176 opts.idle_timeout_secs = DEFAULT_IDLE_TIMEOUT; |
172 | 177 |
173 fill_own_user(); | 178 fill_own_user(); |
174 | 179 |
175 /* Iterate all the arguments */ | 180 for (i = 1; i < (unsigned int)argc && argv[i][0] == '-'; i++) { |
176 for (i = 1; i < (unsigned int)argc; i++) { | 181 opt = OPT_OTHER; |
177 #ifdef ENABLE_CLI_PUBKEY_AUTH | 182 for (j = 1; (c = argv[i][j]) != '\0' && !next && opt == OPT_OTHER; j++) { |
178 if (nextiskey) { | |
179 /* Load a hostkey since the previous argument was "-i" */ | |
180 loadidentityfile(argv[i], 1); | |
181 nextiskey = 0; | |
182 continue; | |
183 } | |
184 #endif | |
185 #ifdef ENABLE_CLI_REMOTETCPFWD | |
186 if (nextisremote) { | |
187 TRACE(("nextisremote true")) | |
188 addforward(argv[i], cli_opts.remotefwds); | |
189 nextisremote = 0; | |
190 continue; | |
191 } | |
192 #endif | |
193 #ifdef ENABLE_CLI_LOCALTCPFWD | |
194 if (nextislocal) { | |
195 TRACE(("nextislocal true")) | |
196 addforward(argv[i], cli_opts.localfwds); | |
197 nextislocal = 0; | |
198 continue; | |
199 } | |
200 #endif | |
201 #ifdef ENABLE_CLI_NETCAT | |
202 if (nextisnetcat) { | |
203 TRACE(("nextisnetcat true")) | |
204 add_netcat(argv[i]); | |
205 nextisnetcat = 0; | |
206 continue; | |
207 } | |
208 #endif | |
209 if (next) { | |
210 /* The previous flag set a value to assign */ | |
211 *next = argv[i]; | |
212 if (*next == NULL) { | |
213 dropbear_exit("Invalid null argument"); | |
214 } | |
215 next = NULL; | |
216 continue; | |
217 } | |
218 | |
219 if (argv[i][0] == '-') { | |
220 /* A flag *waves* */ | |
221 char c = argv[i][1]; | |
222 if (strlen(argv[i]) != 2) { | |
223 /* We only handle one flag per hyphen */ | |
224 fprintf(stderr, "Warning, trailing '%s' of '%s' is ignored.\n", | |
225 &argv[i][2], argv[i]); | |
226 } | |
227 switch (c) { | 183 switch (c) { |
228 case 'y': /* always accept the remote hostkey */ | 184 case 'y': /* always accept the remote hostkey */ |
229 if (cli_opts.always_accept_key) { | 185 if (cli_opts.always_accept_key) { |
230 /* twice means no checking at all */ | 186 /* twice means no checking at all */ |
231 cli_opts.no_hostkey_check = 1; | 187 cli_opts.no_hostkey_check = 1; |
235 case 'p': /* remoteport */ | 191 case 'p': /* remoteport */ |
236 next = &cli_opts.remoteport; | 192 next = &cli_opts.remoteport; |
237 break; | 193 break; |
238 #ifdef ENABLE_CLI_PUBKEY_AUTH | 194 #ifdef ENABLE_CLI_PUBKEY_AUTH |
239 case 'i': /* an identityfile */ | 195 case 'i': /* an identityfile */ |
240 /* Keep scp happy when it changes "-i file" to "-ifile" */ | 196 opt = OPT_AUTHKEY; |
241 if (strlen(argv[i]) > 2) { | |
242 loadidentityfile(&argv[i][2], 1); | |
243 } else { | |
244 nextiskey = 1; | |
245 } | |
246 break; | 197 break; |
247 #endif | 198 #endif |
248 case 't': /* we want a pty */ | 199 case 't': /* we want a pty */ |
249 cli_opts.wantpty = 1; | 200 cli_opts.wantpty = 1; |
250 break; | 201 break; |
260 case 's': | 211 case 's': |
261 cli_opts.is_subsystem = 1; | 212 cli_opts.is_subsystem = 1; |
262 break; | 213 break; |
263 #ifdef ENABLE_CLI_LOCALTCPFWD | 214 #ifdef ENABLE_CLI_LOCALTCPFWD |
264 case 'L': | 215 case 'L': |
265 nextislocal = 1; | 216 opt = OPT_LOCALTCPFWD; |
266 break; | 217 break; |
267 case 'g': | 218 case 'g': |
268 opts.listen_fwd_all = 1; | 219 opts.listen_fwd_all = 1; |
269 break; | 220 break; |
270 #endif | 221 #endif |
271 #ifdef ENABLE_CLI_REMOTETCPFWD | 222 #ifdef ENABLE_CLI_REMOTETCPFWD |
272 case 'R': | 223 case 'R': |
273 nextisremote = 1; | 224 opt = OPT_REMOTETCPFWD; |
274 break; | 225 break; |
275 #endif | 226 #endif |
276 #ifdef ENABLE_CLI_NETCAT | 227 #ifdef ENABLE_CLI_NETCAT |
277 case 'B': | 228 case 'B': |
278 nextisnetcat = 1; | 229 opt = OPT_NETCAT; |
279 break; | 230 break; |
280 #endif | 231 #endif |
281 #ifdef ENABLE_CLI_PROXYCMD | 232 #ifdef ENABLE_CLI_PROXYCMD |
282 case 'J': | 233 case 'J': |
283 next = &cli_opts.proxycmd; | 234 next = &cli_opts.proxycmd; |
339 break; | 290 break; |
340 case 'o': | 291 case 'o': |
341 case 'b': | 292 case 'b': |
342 next = &dummy; | 293 next = &dummy; |
343 default: | 294 default: |
344 fprintf(stderr, | 295 fprintf(stderr, |
345 "WARNING: Ignoring unknown argument '%s'\n", argv[i]); | 296 "WARNING: Ignoring unknown option -%c\n", c); |
346 break; | 297 break; |
347 } /* Switch */ | 298 } /* Switch */ |
348 | 299 } |
349 /* Now we handle args where they might be "-luser" (no spaces)*/ | 300 |
350 if (next && strlen(argv[i]) > 2) { | 301 if (!next && opt == OPT_OTHER) /* got a flag */ |
351 *next = &argv[i][2]; | 302 continue; |
352 next = NULL; | 303 |
353 } | 304 if (c == '\0') { |
354 | 305 i++; |
355 continue; /* next argument */ | 306 j = 0; |
356 | 307 if (!argv[i]) |
357 } else { | 308 dropbear_exit("Missing argument"); |
358 TRACE(("non-flag arg: '%s'", argv[i])) | 309 } |
359 | 310 |
360 /* Either the hostname or commands */ | 311 #ifdef ENABLE_CLI_PUBKEY_AUTH |
361 | 312 if (opt == OPT_AUTHKEY) { |
362 if (host_arg == NULL) { | 313 TRACE(("opt authkey")) |
363 host_arg = argv[i]; | 314 loadidentityfile(&argv[i][j], 1); |
364 } else { | 315 } |
365 | 316 else |
366 /* this is part of the commands to send - after this we | 317 #endif |
367 * don't parse any more options, and flags are sent as the | 318 #ifdef ENABLE_CLI_REMOTETCPFWD |
368 * command */ | 319 if (opt == OPT_REMOTETCPFWD) { |
369 cmdlen = 0; | 320 TRACE(("opt remotetcpfwd")) |
370 for (j = i; j < (unsigned int)argc; j++) { | 321 addforward(&argv[i][j], cli_opts.remotefwds); |
371 cmdlen += strlen(argv[j]) + 1; /* +1 for spaces */ | 322 } |
372 } | 323 else |
373 /* Allocate the space */ | 324 #endif |
374 cli_opts.cmd = (char*)m_malloc(cmdlen); | 325 #ifdef ENABLE_CLI_LOCALTCPFWD |
375 cli_opts.cmd[0] = '\0'; | 326 if (opt == OPT_LOCALTCPFWD) { |
376 | 327 TRACE(("opt localtcpfwd")) |
377 /* Append all the bits */ | 328 addforward(&argv[i][j], cli_opts.localfwds); |
378 for (j = i; j < (unsigned int)argc; j++) { | 329 } |
379 strlcat(cli_opts.cmd, argv[j], cmdlen); | 330 else |
380 strlcat(cli_opts.cmd, " ", cmdlen); | 331 #endif |
381 } | 332 #ifdef ENABLE_CLI_NETCAT |
382 /* It'll be null-terminated here */ | 333 if (opt == OPT_NETCAT) { |
383 | 334 TRACE(("opt netcat")) |
384 /* We've eaten all the options and flags */ | 335 add_netcat(&argv[i][j]); |
385 break; | 336 } |
386 } | 337 else |
387 } | 338 #endif |
339 if (next) { | |
340 /* The previous flag set a value to assign */ | |
341 *next = &argv[i][j]; | |
342 if (*next == NULL) | |
343 dropbear_exit("Invalid null argument"); | |
344 next = NULL; | |
345 } | |
346 } | |
347 | |
348 /* Done with options/flags; now handle the hostname (which may not | |
349 * start with a hyphen) and optional command */ | |
350 | |
351 if (i >= (unsigned int)argc) { /* missing hostname */ | |
352 printhelp(); | |
353 exit(EXIT_FAILURE); | |
354 } | |
355 host_arg = argv[i++]; | |
356 TRACE(("host is: %s", host_arg)) | |
357 | |
358 if (i < (unsigned int)argc) { | |
359 /* Build the command to send */ | |
360 cmdlen = 0; | |
361 for (j = i; j < (unsigned int)argc; j++) | |
362 cmdlen += strlen(argv[j]) + 1; /* +1 for spaces */ | |
363 | |
364 /* Allocate the space */ | |
365 cli_opts.cmd = (char*)m_malloc(cmdlen); | |
366 cli_opts.cmd[0] = '\0'; | |
367 | |
368 /* Append all the bits */ | |
369 for (j = i; j < (unsigned int)argc; j++) { | |
370 strlcat(cli_opts.cmd, argv[j], cmdlen); | |
371 strlcat(cli_opts.cmd, " ", cmdlen); | |
372 } | |
373 /* It'll be null-terminated here */ | |
374 TRACE(("cmd is: %s", cli_opts.cmd)) | |
388 } | 375 } |
389 | 376 |
390 /* And now a few sanity checks and setup */ | 377 /* And now a few sanity checks and setup */ |
391 | 378 |
392 #ifdef ENABLE_USER_ALGO_LIST | 379 #ifdef ENABLE_USER_ALGO_LIST |
393 parse_ciphers_macs(); | 380 parse_ciphers_macs(); |
394 #endif | 381 #endif |
395 | |
396 if (host_arg == NULL) { | |
397 printhelp(); | |
398 exit(EXIT_FAILURE); | |
399 } | |
400 | 382 |
401 #ifdef ENABLE_CLI_PROXYCMD | 383 #ifdef ENABLE_CLI_PROXYCMD |
402 if (cli_opts.proxycmd) { | 384 if (cli_opts.proxycmd) { |
403 /* To match the common path of m_freeing it */ | 385 /* To match the common path of m_freeing it */ |
404 cli_opts.proxycmd = m_strdup(cli_opts.proxycmd); | 386 cli_opts.proxycmd = m_strdup(cli_opts.proxycmd); |