1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-04-22 13:35:03 -05:00

Improve Uppity's online help and command-line errors.

We now show the --help output if invoked with no arguments, and the
help text also includes a big safety warning in the hope of stopping
anyone from mistaking this for a _secure_ SSH server implementation.

While I'm here, the errors now all use appname[] in place of
constantly repeating the program name. (Not because I anticipate a
change right now, but if nothing else, it makes things easier moving
errors out into shared source files or between applications.)
This commit is contained in:
Simon Tatham 2018-10-22 20:17:47 +01:00
parent 1806b71241
commit 5f03613614

View File

@ -201,21 +201,32 @@ int auth_successful(AuthPolicy *ap, ptrlen username, unsigned method)
return TRUE; return TRUE;
} }
static void show_help_and_exit(void) static void safety_warning(FILE *fp)
{ {
printf("usage: uppity [options]\n"); fputs(" =================================================\n"
printf("options: --hostkey KEY SSH host key (need at least one)\n"); " THIS SSH SERVER IS NOT WRITTEN TO BE SECURE!\n"
printf(" --userkey KEY public key" " DO NOT DEPLOY IT IN A HOSTILE-FACING ENVIRONMENT!\n"
" acceptable for user authentication\n"); " =================================================\n", fp);
printf("also: uppity --help show this text\n"); }
printf(" uppity --version show version information\n");
exit(0); static void show_help(FILE *fp)
{
safety_warning(fp);
fputs("\n"
"usage: uppity [options]\n"
"options: --hostkey KEY SSH host key (need at least one)\n"
" --userkey KEY public key"
" acceptable for user authentication\n"
"also: uppity --help show this text\n"
" uppity --version show version information\n"
"\n", fp);
safety_warning(fp);
} }
static void show_version_and_exit(void) static void show_version_and_exit(void)
{ {
char *buildinfo_text = buildinfo("\n"); char *buildinfo_text = buildinfo("\n");
printf("uppity: %s\n%s\n", ver, buildinfo_text); printf("%s: %s\n%s\n", appname, ver, buildinfo_text);
sfree(buildinfo_text); sfree(buildinfo_text);
exit(0); exit(0);
} }
@ -243,8 +254,8 @@ static int longoptarg(const char *arg, const char *expected,
*val = *++*argvp; *val = *++*argvp;
return TRUE; return TRUE;
} else { } else {
fprintf(stderr, "uppity: option %s expects an argument\n", fprintf(stderr, "%s: option %s expects an argument\n",
expected); appname, expected);
exit(1); exit(1);
} }
} }
@ -272,12 +283,24 @@ int main(int argc, char **argv)
ap.ssh1keys = NULL; ap.ssh1keys = NULL;
ap.ssh2keys = NULL; ap.ssh2keys = NULL;
if (argc <= 1) {
/*
* We're going to terminate with an error message below,
* because there are no host keys. But we'll display the help
* as additional standard-error output, if nothing else so
* that people see the giant safety warning.
*/
show_help(stderr);
fputc('\n', stderr);
}
while (--argc > 0) { while (--argc > 0) {
const char *arg = *++argv; const char *arg = *++argv;
const char *val; const char *val;
if (!strcmp(arg, "--help")) { if (!strcmp(arg, "--help")) {
show_help_and_exit(); show_help(stdout);
exit(0);
} else if (!strcmp(arg, "--version")) { } else if (!strcmp(arg, "--version")) {
show_version_and_exit(); show_version_and_exit();
} else if (!strcmp(arg, "--verbose") || !strcmp(arg, "-v")) { } else if (!strcmp(arg, "--verbose") || !strcmp(arg, "-v")) {
@ -296,8 +319,8 @@ int main(int argc, char **argv)
uk = ssh2_load_userkey(keyfile, NULL, &error); uk = ssh2_load_userkey(keyfile, NULL, &error);
filename_free(keyfile); filename_free(keyfile);
if (!uk || !uk->key) { if (!uk || !uk->key) {
fprintf(stderr, "uppity: unable to load host key '%s': " fprintf(stderr, "%s: unable to load host key '%s': "
"%s\n", val, error); "%s\n", appname, val, error);
exit(1); exit(1);
} }
key = uk->key; key = uk->key;
@ -306,8 +329,9 @@ int main(int argc, char **argv)
for (i = 0; i < nhostkeys; i++) for (i = 0; i < nhostkeys; i++)
if (ssh_key_alg(hostkeys[i]) == ssh_key_alg(key)) { if (ssh_key_alg(hostkeys[i]) == ssh_key_alg(key)) {
fprintf(stderr, "uppity: host key '%s' duplicates key " fprintf(stderr, "%s: host key '%s' duplicates key "
"type %s\n", val, ssh_key_alg(key)->ssh_id); "type %s\n", appname, val,
ssh_key_alg(key)->ssh_id);
exit(1); exit(1);
} }
@ -318,19 +342,20 @@ int main(int argc, char **argv)
hostkeys[nhostkeys++] = key; hostkeys[nhostkeys++] = key;
} else if (keytype == SSH_KEYTYPE_SSH1) { } else if (keytype == SSH_KEYTYPE_SSH1) {
if (hostkey1) { if (hostkey1) {
fprintf(stderr, "uppity: host key '%s' is a redundant " fprintf(stderr, "%s: host key '%s' is a redundant "
"SSH-1 host key\n", val); "SSH-1 host key\n", appname, val);
exit(1); exit(1);
} }
hostkey1 = snew(struct RSAKey); hostkey1 = snew(struct RSAKey);
if (!rsa_ssh1_loadkey(keyfile, hostkey1, NULL, &error)) { if (!rsa_ssh1_loadkey(keyfile, hostkey1, NULL, &error)) {
fprintf(stderr, "uppity: unable to load host key '%s': " fprintf(stderr, "%s: unable to load host key '%s': "
"%s\n", val, error); "%s\n", appname, val, error);
exit(1); exit(1);
} }
} else { } else {
fprintf(stderr, "uppity: '%s' is not loadable as a " fprintf(stderr, "%s: '%s' is not loadable as a "
"private key (%s)", val, key_type_to_str(keytype)); "private key (%s)", appname, val,
key_type_to_str(keytype));
exit(1); exit(1);
} }
} else if (longoptarg(arg, "--userkey", &val, &argc, &argv)) { } else if (longoptarg(arg, "--userkey", &val, &argc, &argv)) {
@ -349,8 +374,8 @@ int main(int argc, char **argv)
if (!ssh2_userkey_loadpub(keyfile, NULL, BinarySink_UPCAST(sb), if (!ssh2_userkey_loadpub(keyfile, NULL, BinarySink_UPCAST(sb),
NULL, &error)) { NULL, &error)) {
fprintf(stderr, "uppity: unable to load user key '%s': " fprintf(stderr, "%s: unable to load user key '%s': "
"%s\n", val, error); "%s\n", appname, val, error);
exit(1); exit(1);
} }
@ -370,8 +395,8 @@ int main(int argc, char **argv)
if (!rsa_ssh1_loadpub(keyfile, BinarySink_UPCAST(sb), if (!rsa_ssh1_loadpub(keyfile, BinarySink_UPCAST(sb),
NULL, &error)) { NULL, &error)) {
fprintf(stderr, "uppity: unable to load user key '%s': " fprintf(stderr, "%s: unable to load user key '%s': "
"%s\n", val, error); "%s\n", appname, val, error);
exit(1); exit(1);
} }
@ -384,8 +409,8 @@ int main(int argc, char **argv)
strbuf_free(sb); strbuf_free(sb);
} else { } else {
fprintf(stderr, "uppity: '%s' is not loadable as a public key " fprintf(stderr, "%s: '%s' is not loadable as a public key "
"(%s)\n", val, key_type_to_str(keytype)); "(%s)\n", appname, val, key_type_to_str(keytype));
exit(1); exit(1);
} }
} else if (longoptarg(arg, "--sshlog", &val, &argc, &argv) || } else if (longoptarg(arg, "--sshlog", &val, &argc, &argv) ||
@ -403,13 +428,13 @@ int main(int argc, char **argv)
conf_set_int(conf, CONF_logtype, LGTYP_SSHRAW); conf_set_int(conf, CONF_logtype, LGTYP_SSHRAW);
conf_set_int(conf, CONF_logxfovr, LGXF_OVR); conf_set_int(conf, CONF_logxfovr, LGXF_OVR);
} else { } else {
fprintf(stderr, "uppity: unrecognised option '%s'\n", arg); fprintf(stderr, "%s: unrecognised option '%s'\n", appname, arg);
exit(1); exit(1);
} }
} }
if (nhostkeys == 0 && !hostkey1) { if (nhostkeys == 0 && !hostkey1) {
fprintf(stderr, "uppity: specify at least one host key\n"); fprintf(stderr, "%s: specify at least one host key\n", appname);
exit(1); exit(1);
} }