diff --git a/ssheven-constants.r b/ssheven-constants.r index f1c5c7e..e52254a 100644 --- a/ssheven-constants.r +++ b/ssheven-constants.r @@ -55,6 +55,10 @@ #define DLOG_PASSWORD 134 #define DITL_PASSWORD 134 +/* alert for password authentication failure */ +#define ALRT_PW_FAIL 135 +#define DITL_PW_FAIL 135 + /* menus */ #define MBAR_SSHEVEN 128 #define MENU_APPLE 128 diff --git a/ssheven.c b/ssheven.c index 6b8b7dc..5194c8d 100644 --- a/ssheven.c +++ b/ssheven.c @@ -456,16 +456,6 @@ int init_connection(char* hostname) return 1; } -int ssh_password_auth(char* username, char* password) -{ - int rc = 1; - - SSH_CHECK(libssh2_userauth_password(ssh_con.session, username, password)); - ssh_con.channel = libssh2_channel_open_session(ssh_con.session); - - return 1; -} - int ssh_setup_terminal(void) { int rc = 0; @@ -639,7 +629,9 @@ int intro_dialog(char* hostname, char* username, char* password) void* read_thread(void* arg) { int ok = 1; + int rc = LIBSSH2_ERROR_NONE; + // yield until we're given a command while (read_thread_command == WAIT) YieldToAnyThread(); if (read_thread_command == EXIT) @@ -653,25 +645,41 @@ void* read_thread(void* arg) if (ok) { - printf_i("authenticating... "); YieldToAnyThread(); - ok = ssh_password_auth(username+1, password+1); - printf_i("done.\r\n"); YieldToAnyThread(); + printf_i("Authenticating... "); YieldToAnyThread(); + rc = libssh2_userauth_password(ssh_con.session, username+1, password+1); + + if (rc == LIBSSH2_ERROR_NONE) + { + printf_i("done.\r\n"); + } + else + { + if (rc == LIBSSH2_ERROR_AUTHENTICATION_FAILED) StopAlert(ALRT_PW_FAIL, nil); + printf_i("failure: %s\r\n", libssh2_error_string(rc)); + ok = 0; + } } + // if we logged in, open and set up the tty if (ok) { + ssh_con.channel = libssh2_channel_open_session(ssh_con.session); ok = ssh_setup_terminal(); YieldToAnyThread(); } - // if we failed, exit - if (read_thread_state != OPEN) return 0; + // if we failed, close everything and exit + if (!ok || (read_thread_state != OPEN)) + { + end_connection(); + return 0; + } - // allow pasting + // if we connected, allow pasting void* menu = GetMenuHandle(MENU_EDIT); EnableItem(menu, 5); - // loop as long until we've failed or are asked to EXIT + // process incoming data until we've failed or are asked to EXIT while (read_thread_command == READ && read_thread_state == OPEN) { check_network_events(); @@ -681,6 +689,7 @@ void* read_thread(void* arg) // if we still have a connection, close it if (read_thread_state != DONE) end_connection(); + // disallow pasting after connection is closed DisableItem(menu, 5); return 0; diff --git a/ssheven.r b/ssheven.r index 4221c8e..7031029 100644 --- a/ssheven.r +++ b/ssheven.r @@ -197,6 +197,30 @@ resource 'DITL' (DITL_PASSWORD) { } }; +resource 'DITL' (DITL_PW_FAIL) { + { + { 50, 260, 70, 340 }, + Button { enabled, "OK" }; + + { 10, 70, 30, 340 }, + StaticText { enabled, "Server rejected username/password!" }; + } +}; + +resource 'ALRT' (ALRT_PW_FAIL, purgeable) { + { 50, 100, 50+80, 100+350 }, + DITL_PW_FAIL, + + /* OK means draw default border on first button */ + { + OK, visible, silent, + OK, visible, silent, + OK, visible, silent, + OK, visible, silent + }, + alertPositionMainScreen +}; + #include "Processes.r" resource 'SIZE' (-1) {