|
|
|
@ -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);
|
|
|
|
|
|
|
|
|
|