From e38959560668bb1111dc70b4be938f4f4c78e036 Mon Sep 17 00:00:00 2001 From: Alexander Golubev Date: Sun, 21 Jan 2024 13:26:40 +0300 Subject: tdeioslave/sftp: split off connection init to a dedicated function Signed-off-by: Alexander Golubev (cherry picked from commit 75349be43e1b4ced52502f98316148a7b55c1352) --- tdeioslave/sftp/tdeio_sftp.cpp | 133 ++++++++++++++++++++++------------------- tdeioslave/sftp/tdeio_sftp.h | 3 + 2 files changed, 75 insertions(+), 61 deletions(-) (limited to 'tdeioslave/sftp') diff --git a/tdeioslave/sftp/tdeio_sftp.cpp b/tdeioslave/sftp/tdeio_sftp.cpp index e3f7494d1..e3efaebff 100644 --- a/tdeioslave/sftp/tdeio_sftp.cpp +++ b/tdeioslave/sftp/tdeio_sftp.cpp @@ -631,43 +631,8 @@ void sftpProtocol::setHost(const TQString& h, int port, const TQString& user, co mPassword = pass; } -void sftpProtocol::openConnection() { - - if (mConnected) { - return; - } - - kdDebug(TDEIO_SFTP_DB) << "username=" << mUsername << ", host=" << mHost << ", port=" << mPort << endl; - - infoMessage(i18n("Opening SFTP connection to host %1:%2").arg(mHost).arg(mPort)); - - if (mHost.isEmpty()) { - kdDebug(TDEIO_SFTP_DB) << "openConnection(): Need hostname..." << endl; - error(TDEIO::ERR_UNKNOWN_HOST, i18n("No hostname specified.")); - return; - } - - // Setup AuthInfo for use with password caching and the - // password dialog box. - AuthInfo info = authInfo(); - info.keepPassword = true; // make the "keep Password" check box visible to the user. - - PasswordPurger pwPurger{mPassword}; - PasswordPurger infoPurger{info.password}; - - // Check for cached authentication info if no password is specified... - if (mPassword.isEmpty()) { - kdDebug(TDEIO_SFTP_DB) << "checking cache: info.username = " << info.username - << ", info.url = " << info.url.prettyURL() << endl; - - if (checkCachedAuthentication(info)) { - kdDebug() << "using cached" << endl; - mUsername = info.username; - mPassword = info.password; - } - } - // Start the ssh connection. +int sftpProtocol::initializeConnection() { TQString msg; // msg for dialog box TQString caption; // dialog box caption unsigned char *hash = NULL; // the server hash @@ -679,7 +644,7 @@ void sftpProtocol::openConnection() { mSession = ssh_new(); if (mSession == NULL) { error(TDEIO::ERR_INTERNAL, i18n("Could not create a new SSH session.")); - return; + return SSH_ERROR; } kdDebug(TDEIO_SFTP_DB) << "Creating the SSH session and setting options" << endl; @@ -709,23 +674,23 @@ void sftpProtocol::openConnection() { rc = ssh_options_set(mSession, SSH_OPTIONS_HOST, mHost.utf8().data()); if (rc < 0) { error(TDEIO::ERR_OUT_OF_MEMORY, i18n("Could not set host.")); - return; + return SSH_ERROR; } if (mPort > 0) { rc = ssh_options_set(mSession, SSH_OPTIONS_PORT, &mPort); if (rc < 0) { error(TDEIO::ERR_OUT_OF_MEMORY, i18n("Could not set port.")); - return; + return SSH_ERROR; } } // Set the username - if (!info.username.isEmpty()) { - rc = ssh_options_set(mSession, SSH_OPTIONS_USER, info.username.utf8().data()); + if (!mUsername.isEmpty()) { + rc = ssh_options_set(mSession, SSH_OPTIONS_USER, mUsername.utf8().data()); if (rc < 0) { error(TDEIO::ERR_OUT_OF_MEMORY, i18n("Could not set username.")); - return; + return rc; } } @@ -734,7 +699,7 @@ void sftpProtocol::openConnection() { rc = ssh_options_set(mSession, SSH_OPTIONS_LOG_VERBOSITY_STR, verbosity); if (rc < 0) { error(TDEIO::ERR_OUT_OF_MEMORY, i18n("Could not set log verbosity.")); - return; + return rc; } } @@ -742,7 +707,7 @@ void sftpProtocol::openConnection() { rc = ssh_options_parse_config(mSession, NULL); if (rc < 0) { error(TDEIO::ERR_INTERNAL, i18n("Could not parse the config file.")); - return; + return rc; } ssh_set_callbacks(mSession, mCallbacks); @@ -754,7 +719,7 @@ void sftpProtocol::openConnection() { if (rc < 0) { error(TDEIO::ERR_COULD_NOT_CONNECT, TQString::fromUtf8(ssh_get_error(mSession))); closeConnection(); - return; + return rc; } kdDebug(TDEIO_SFTP_DB) << "Getting the SSH server hash" << endl; @@ -762,24 +727,26 @@ void sftpProtocol::openConnection() { /* get the hash */ ssh_key serverKey; #if LIBSSH_VERSION_INT < SSH_VERSION_INT(0, 7, 90) - if (ssh_get_publickey(mSession, &serverKey) < 0) { + rc = ssh_get_publickey(mSession, &serverKey); #else - if (ssh_get_server_publickey(mSession, &serverKey) < 0) { + rc = ssh_get_server_publickey(mSession, &serverKey); #endif + if (rc<0) { error(TDEIO::ERR_COULD_NOT_CONNECT, TQString::fromUtf8(ssh_get_error(mSession))); closeConnection(); - return; + return rc; } size_t hlen; #if LIBSSH_VERSION_INT < SSH_VERSION_INT(0, 8, 90) - if (ssh_get_publickey_hash(serverKey, SSH_PUBLICKEY_HASH_MD5, &hash, &hlen) < 0) { + rc = ssh_get_publickey_hash(serverKey, SSH_PUBLICKEY_HASH_MD5, &hash, &hlen); #else - if (ssh_get_publickey_hash(serverKey, SSH_PUBLICKEY_HASH_SHA256, &hash, &hlen) < 0) { + rc = ssh_get_publickey_hash(serverKey, SSH_PUBLICKEY_HASH_SHA256, &hash, &hlen); #endif + if (rc<0) { error(TDEIO::ERR_COULD_NOT_CONNECT, TQString::fromUtf8(ssh_get_error(mSession))); closeConnection(); - return; + return rc; } kdDebug(TDEIO_SFTP_DB) << "Checking if the SSH server is known" << endl; @@ -801,7 +768,7 @@ void sftpProtocol::openConnection() { "client into thinking the key does not exist.\n" "Please contact your system administrator.\n%1").arg(TQString::fromUtf8(ssh_get_error(mSession)))); closeConnection(); - return; + return SSH_ERROR; case TDEIO_SSH_KNOWN_HOSTS_CHANGED: hexa = ssh_get_hexa(hash, hlen); delete hash; @@ -814,7 +781,7 @@ void sftpProtocol::openConnection() { mHost).arg(TQString::fromUtf8(hexa)).arg(TQString::fromUtf8(ssh_get_error(mSession)))); delete hexa; closeConnection(); - return; + return SSH_ERROR; case TDEIO_SSH_KNOWN_HOSTS_NOT_FOUND: case TDEIO_SSH_KNOWN_HOSTS_UNKNOWN: hexa = ssh_get_hexa(hash, hlen); @@ -828,7 +795,7 @@ void sftpProtocol::openConnection() { if (KMessageBox::Yes != messageBox(WarningYesNo, msg, caption)) { closeConnection(); error(TDEIO::ERR_USER_CANCELED, TQString()); - return; + return SSH_ERROR; } /* write the known_hosts file */ @@ -840,13 +807,13 @@ void sftpProtocol::openConnection() { #endif error(TDEIO::ERR_USER_CANCELED, TQString::fromUtf8(ssh_get_error(mSession))); closeConnection(); - return; + return SSH_ERROR; } break; case TDEIO_SSH_KNOWN_HOSTS_ERROR: delete hash; error(TDEIO::ERR_COULD_NOT_CONNECT, TQString::fromUtf8(ssh_get_error(mSession))); - return; + return SSH_ERROR; } kdDebug(TDEIO_SFTP_DB) << "Trying to authenticate with the server" << endl; @@ -858,11 +825,57 @@ void sftpProtocol::openConnection() { rc = ssh_options_get(mSession, SSH_OPTIONS_USER, &ssh_username); if (rc == 0 && ssh_username && ssh_username[0]) { mUsername = ssh_username; - info.username = mUsername; } ssh_string_free_char(ssh_username); } + return SSH_OK; +} + + +void sftpProtocol::openConnection() { + + if (mConnected) { + return; + } + + kdDebug(TDEIO_SFTP_DB) << "username=" << mUsername << ", host=" << mHost << ", port=" << mPort << endl; + + infoMessage(i18n("Opening SFTP connection to host %1:%2").arg(mHost).arg(mPort)); + + if (mHost.isEmpty()) { + kdDebug(TDEIO_SFTP_DB) << "openConnection(): Need hostname..." << endl; + error(TDEIO::ERR_UNKNOWN_HOST, i18n("No hostname specified.")); + return; + } + + // Setup AuthInfo for use with password caching and the + // password dialog box. + AuthInfo info = authInfo(); + info.keepPassword = true; // make the "keep Password" check box visible to the user. + + PasswordPurger pwPurger{mPassword}; + PasswordPurger infoPurger{info.password}; + + // Check for cached authentication info if no password is specified... + if (mPassword.isEmpty()) { + kdDebug(TDEIO_SFTP_DB) << "checking cache: info.username = " << info.username + << ", info.url = " << info.url.prettyURL() << endl; + + if (checkCachedAuthentication(info)) { + kdDebug() << "using cached" << endl; + mUsername = info.username; + mPassword = info.password; + } + } + + int rc; + + // Start the ssh connection. + if (initializeConnection() < 0) { + return; + } + // Try to authenticate rc = ssh_userauth_none(mSession, NULL); if (rc == SSH_AUTH_ERROR) { @@ -873,8 +886,7 @@ void sftpProtocol::openConnection() { } int method = ssh_auth_list(mSession); - if (!method && rc != SSH_AUTH_SUCCESS) - { + if (!method && rc != SSH_AUTH_SUCCESS) { error(TDEIO::ERR_COULD_NOT_LOGIN, i18n("Authentication failed." " The server did not send any authentication methods!")); return; @@ -896,8 +908,7 @@ void sftpProtocol::openConnection() { kdDebug(TDEIO_SFTP_DB) << "Trying to authenticate with public key" << endl; bool keepTryingPasskey=true; - while(keepTryingPasskey) - { + while (keepTryingPasskey) { mPubKeyAuthData.wasCalled = 0; rc = ssh_userauth_publickey_auto(mSession, nullptr, nullptr); diff --git a/tdeioslave/sftp/tdeio_sftp.h b/tdeioslave/sftp/tdeio_sftp.h index 2ad069ea7..68c8a0020 100644 --- a/tdeioslave/sftp/tdeio_sftp.h +++ b/tdeioslave/sftp/tdeio_sftp.h @@ -158,6 +158,9 @@ private: // private methods /** A small helper function to construct auth info skeleton for the protocol */ TDEIO::AuthInfo authInfo(); + /** A helper function encapsulating creation of an ssh connection before authentication */ + int initializeConnection(); + void reportError(const KURL &url, const int err); bool createUDSEntry(const TQString &filename, const TQByteArray &path, -- cgit v1.2.1