From 581d266ae6f085317b4247b2d1ddbc12c8fa09fb Mon Sep 17 00:00:00 2001 From: Alexander Golubev Date: Sat, 27 Jan 2024 20:10:29 +0300 Subject: [PATCH] tdeioslave/sftp: pass correct username to openPassDlg() We should always pass to the openPassDlg() exactly the same username otherwise it may result in incorrect caching of passwords especially in case if the username is changed by the user. Also don't allow username change in case it was passed to setHost() (i.e. it was specified in the URL like e.g. sftp://username@host/). In such a case after changing it'd be impossible to properly cache it. Signed-off-by: Alexander Golubev --- tdeioslave/sftp/tdeio_sftp.cpp | 36 +++++++++++++++++++++++----------- tdeioslave/sftp/tdeio_sftp.h | 6 +++++- 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/tdeioslave/sftp/tdeio_sftp.cpp b/tdeioslave/sftp/tdeio_sftp.cpp index 71c69f76d..1664725a5 100644 --- a/tdeioslave/sftp/tdeio_sftp.cpp +++ b/tdeioslave/sftp/tdeio_sftp.cpp @@ -230,9 +230,10 @@ int sftpProtocol::auth_callback(const char *prompt, char *buf, size_t len, AuthInfo pubKeyInfo = authInfo(); - pubKeyInfo.readOnly = false; pubKeyInfo.keepPassword = false; // don't save passwords for public key, // that's the task of ssh-agent. + pubKeyInfo.readOnly = true; // We don't want to handle user name change when authing with a key + TQString errMsg; TQString keyFile; #if LIBSSH_VERSION_INT < SSH_VERSION_INT(0, 10, 0) @@ -467,7 +468,6 @@ int sftpProtocol::authenticatePassword(bool noPaswordQuery) { kdDebug(TDEIO_SFTP_DB) << "Trying to authenticate with password" << endl; AuthInfo info = authInfo(); - info.readOnly = false; info.keepPassword = true; info.prompt = i18n("Please enter your username and password."); @@ -496,10 +496,11 @@ int sftpProtocol::authenticatePassword(bool noPaswordQuery) { password = info.password; - if (info.username != sshUsername()) { - kdDebug(TDEIO_SFTP_DB) << "Username changed from " << mUsername + TQString sshUser=sshUsername(); + if (info.username != sshUser) { + kdDebug(TDEIO_SFTP_DB) << "Username changed from " << sshUser << " to " << info.username << endl; - mUsername = info.username; + mCachedUsername = info.username; mPassword = info.password; // libssh doc says that most servers don't permit changing the username during // authentication, so we should reinitialize the session here @@ -507,8 +508,7 @@ int sftpProtocol::authenticatePassword(bool noPaswordQuery) { } } - rc = ssh_userauth_password(mSession, info.username.utf8().data(), - password.utf8().data()); + rc = ssh_userauth_password(mSession, NULL, password.utf8().data()); } while (rc == SSH_AUTH_DENIED && !noPaswordQuery); return rc; @@ -541,7 +541,19 @@ TDEIO::AuthInfo sftpProtocol::authInfo() { rv.caption = i18n("SFTP Login"); rv.comment = "sftp://" + mHost + ':' + TQString::number(mPort); rv.commentLabel = i18n("site:"); - rv.username = mUsername; + + if(!mUsername.isEmpty()) { + rv.username = mUsername; + } if(!mCachedUsername.isEmpty()) { + rv.username = mCachedUsername; + } else if (mSession) { + rv.username = sshUsername(); + } + + // if username was specified in the address string it shouldn't be changed + if (!mUsername.isEmpty()) { + rv.readOnly = true; + } return rv; } @@ -790,6 +802,7 @@ void sftpProtocol::setHost(const TQString& h, int port, const TQString& user, co mUsername = user; mPassword = pass; + mCachedUsername = TQString::null; } @@ -845,8 +858,9 @@ int sftpProtocol::initializeConnection() { } // Set the username - if (!mUsername.isEmpty()) { - rc = ssh_options_set(mSession, SSH_OPTIONS_USER, mUsername.utf8().data()); + if (!mCachedUsername.isEmpty() || !mUsername.isEmpty()) { + TQString username = !mCachedUsername.isEmpty() ? mCachedUsername : mUsername; + rc = ssh_options_set(mSession, SSH_OPTIONS_USER, username.utf8().data()); if (rc < 0) { error(TDEIO::ERR_OUT_OF_MEMORY, i18n("Could not set username.")); return rc; @@ -1006,7 +1020,7 @@ void sftpProtocol::openConnection() { if (checkCachedAuthentication(info)) { kdDebug() << "using cached" << endl; - mUsername = info.username; + mCachedUsername = info.username; mPassword = info.password; purgeString(info.password); //< not really necessary because of Qt's implicit data sharing diff --git a/tdeioslave/sftp/tdeio_sftp.h b/tdeioslave/sftp/tdeio_sftp.h index 66a348e68..747294782 100644 --- a/tdeioslave/sftp/tdeio_sftp.h +++ b/tdeioslave/sftp/tdeio_sftp.h @@ -123,9 +123,13 @@ private: // Private variables /** The sftp session for the connection */ sftp_session mSftp; - /** Username to use when connecting */ + /** Username to use when connecting, Note: it's the one passed in the URL */ TQString mUsername; + /** Username to use with the next connection attempt: it's either from the cached data or from + * the password dialog that was prompted to the user. */ + TQString mCachedUsername; + /** User's password. Note: the password would be set only if it was somehow cached: passed to * setHost(), received from passwdserver's cache or was entered by user before reconnection */