|
|
|
/*
|
|
|
|
* Copyright (c) 2001 Lucas Fisher <ljfisher@purdue.edu>
|
|
|
|
* Copyright (c) 2009 Andreas Schneider <mail@cynapses.org>
|
|
|
|
* Copyright (c) 2020 Martin Sandsmark <martin@sandsmark.ninja>
|
|
|
|
* KDE2 port
|
|
|
|
* Copyright (c) 2022 Mavridis Philippe <mavridisf@gmail.com>
|
|
|
|
* Trinity port
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Library General Public
|
|
|
|
* License (LGPL) as published by the Free Software Foundation;
|
|
|
|
* either version 2 of the License, or (at your option) any later
|
|
|
|
* version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Library General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Library General Public License
|
|
|
|
* along with this library; see the file COPYING.LIB. If not, write to
|
|
|
|
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
|
|
* Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef __tdeio_sftp_h__
|
|
|
|
#define __tdeio_sftp_h__
|
|
|
|
|
|
|
|
#include <kurl.h>
|
|
|
|
#include <tdeio/global.h>
|
|
|
|
#include <tdeio/slavebase.h>
|
|
|
|
#include <kdebug.h>
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <memory>
|
|
|
|
|
|
|
|
#include <libssh/libssh.h>
|
|
|
|
#include <libssh/sftp.h>
|
|
|
|
#include <libssh/callbacks.h>
|
|
|
|
|
|
|
|
// How big should each data packet be? Definitely not bigger than 64kb or
|
|
|
|
// you will overflow the 2 byte size variable in a sftp packet.
|
|
|
|
#define MAX_XFER_BUF_SIZE 60 * 1024
|
|
|
|
#define TDEIO_SFTP_DB 7120
|
|
|
|
|
|
|
|
|
|
|
|
#if LIBSSH_VERSION_INT < SSH_VERSION_INT(0, 7, 90)
|
|
|
|
#define TDEIO_SSH_KNOWN_HOSTS_OK SSH_SERVER_KNOWN_OK
|
|
|
|
#define TDEIO_SSH_KNOWN_HOSTS_OTHER SSH_SERVER_FOUND_OTHER
|
|
|
|
#define TDEIO_SSH_KNOWN_HOSTS_CHANGED SSH_SERVER_KNOWN_CHANGED
|
|
|
|
#define TDEIO_SSH_KNOWN_HOSTS_NOT_FOUND SSH_SERVER_FILE_NOT_FOUND
|
|
|
|
#define TDEIO_SSH_KNOWN_HOSTS_UNKNOWN SSH_SERVER_NOT_KNOWN
|
|
|
|
#define TDEIO_SSH_KNOWN_HOSTS_ERROR SSH_SERVER_ERROR
|
|
|
|
|
|
|
|
#else
|
|
|
|
#define TDEIO_SSH_KNOWN_HOSTS_OK SSH_KNOWN_HOSTS_OK
|
|
|
|
#define TDEIO_SSH_KNOWN_HOSTS_OTHER SSH_KNOWN_HOSTS_OTHER
|
|
|
|
#define TDEIO_SSH_KNOWN_HOSTS_CHANGED SSH_KNOWN_HOSTS_CHANGED
|
|
|
|
#define TDEIO_SSH_KNOWN_HOSTS_NOT_FOUND SSH_KNOWN_HOSTS_NOT_FOUND
|
|
|
|
#define TDEIO_SSH_KNOWN_HOSTS_UNKNOWN SSH_KNOWN_HOSTS_UNKNOWN
|
|
|
|
#define TDEIO_SSH_KNOWN_HOSTS_ERROR SSH_KNOWN_HOSTS_ERROR
|
|
|
|
#endif
|
|
|
|
|
|
|
|
namespace TDEIO {
|
|
|
|
class AuthInfo;
|
|
|
|
}
|
|
|
|
|
|
|
|
class sftpProtocol : public TDEIO::SlaveBase
|
|
|
|
{
|
|
|
|
|
|
|
|
public:
|
|
|
|
sftpProtocol(const TQCString &pool_socket, const TQCString &app_socket);
|
|
|
|
virtual ~sftpProtocol();
|
|
|
|
virtual void setHost(const TQString& h, int port, const TQString& user, const TQString& pass) override;
|
|
|
|
virtual void get(const KURL& url) override;
|
|
|
|
virtual void listDir(const KURL& url) override;
|
|
|
|
virtual void mimetype(const KURL& url) override;
|
|
|
|
virtual void stat(const KURL& url) override;
|
|
|
|
virtual void put(const KURL& url, int permissions, bool overwrite, bool resume) override;
|
|
|
|
virtual void copy(const KURL &src, const KURL &dest, int permissions, bool overwrite) override;
|
|
|
|
virtual void closeConnection() override;
|
|
|
|
virtual void slave_status() override;
|
|
|
|
virtual void del(const KURL &url, bool isfile) override;
|
|
|
|
virtual void chmod(const KURL& url, int permissions) override;
|
|
|
|
virtual void symlink(const TQString& target, const KURL& dest, bool overwrite) override;
|
|
|
|
virtual void rename(const KURL& src, const KURL& dest, bool overwrite) override;
|
|
|
|
virtual void mkdir(const KURL& url, int permissions) override;
|
|
|
|
virtual void openConnection() override;
|
|
|
|
|
|
|
|
// libssh authentication callback (note that this is called by the
|
|
|
|
// global ::auth_callback() call.
|
|
|
|
int auth_callback(const char *prompt, char *buf, size_t len,
|
|
|
|
int echo, int verify, void *userdata);
|
|
|
|
|
|
|
|
// libssh logging callback (note that this is called by the
|
|
|
|
// global ::log_callback() call.
|
|
|
|
void log_callback(ssh_session session, int priority, const char *message,
|
|
|
|
void *userdata);
|
|
|
|
|
|
|
|
// Callbacks for SSHAuthMethod-derived strategies
|
|
|
|
int authenticatePublicKey();
|
|
|
|
int authenticateKeyboardInteractive(bool noPaswordQuery = false);
|
|
|
|
int authenticatePassword(bool noPaswordQuery = false);
|
|
|
|
|
|
|
|
/** Some extra authentication failure reasons intended to use alongside was declared in libssh */
|
|
|
|
enum extra_ssh_auth_e {
|
|
|
|
SSH_AUTH_CANCELED=128, //< user canceled password entry dialog
|
|
|
|
SSH_AUTH_NEED_RECONNECT //< it is required to reinitialize connection from scratch
|
|
|
|
};
|
|
|
|
|
|
|
|
private: // Private variables
|
|
|
|
/** True if ioslave is connected to sftp server. */
|
|
|
|
bool mConnected;
|
|
|
|
|
|
|
|
/** Host we are connected to. */
|
|
|
|
TQString mHost;
|
|
|
|
|
|
|
|
/** Port we are connected to. */
|
|
|
|
int mPort;
|
|
|
|
|
|
|
|
/** The ssh session for the connection */
|
|
|
|
ssh_session mSession;
|
|
|
|
|
|
|
|
/** The sftp session for the connection */
|
|
|
|
sftp_session mSftp;
|
|
|
|
|
|
|
|
/** 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
|
|
|
|
*/
|
|
|
|
TQString mPassword;
|
|
|
|
|
|
|
|
/** The open file */
|
|
|
|
sftp_file mOpenFile;
|
|
|
|
|
|
|
|
/** The open URL */
|
|
|
|
KURL mOpenUrl;
|
|
|
|
|
|
|
|
ssh_callbacks mCallbacks;
|
|
|
|
|
|
|
|
/** Version of the sftp protocol we are using. */
|
|
|
|
int sftpVersion;
|
|
|
|
|
|
|
|
//struct Status
|
|
|
|
//{
|
|
|
|
// int code;
|
|
|
|
// TDEIO::filesize_t size;
|
|
|
|
// TQString text;
|
|
|
|
//};
|
|
|
|
|
|
|
|
/** Some data needed to interact with auth_callback() */
|
|
|
|
struct {
|
|
|
|
/** List of keys user was already prompted to enter the passphrase for.
|
|
|
|
* Note: Under most sane circumstances the list shouldn't go beyond size=2,
|
|
|
|
* so no fancy containers here
|
|
|
|
*/
|
|
|
|
TQStringList attemptedKeys;
|
|
|
|
/** A backup for SlaveBase::s_seqNr to pass the same value to prompts for different keys */
|
|
|
|
long current_seqNr;
|
|
|
|
/** true if callback was called */
|
|
|
|
bool wasCalled;
|
|
|
|
/** true if user canceled all passphrase entry dialogues */
|
|
|
|
bool wasCanceled;
|
|
|
|
} mPubKeyAuthData;
|
|
|
|
|
|
|
|
/** true if the password dialog was prompted to the user at leas once */
|
|
|
|
bool mPasswordWasPrompted = false;
|
|
|
|
|
|
|
|
private: // private methods
|
|
|
|
void statMime(const KURL &url);
|
|
|
|
void closeFile();
|
|
|
|
|
|
|
|
/** @returns username used by libssh during the connection */
|
|
|
|
TQString sshUsername();
|
|
|
|
|
|
|
|
/** Adds ssh error (if any) to the given message string */
|
|
|
|
TQString sshError(TQString errMsg=TQString());
|
|
|
|
|
|
|
|
/** 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,
|
|
|
|
TDEIO::UDSEntry &entry, short int details);
|
|
|
|
|
|
|
|
TQString canonicalizePath(const TQString &path);
|
|
|
|
};
|
|
|
|
|
|
|
|
/** A base class for ssh authentication methods. */
|
|
|
|
class SSHAuthMethod {
|
|
|
|
public:
|
|
|
|
/** libssh's flag for he method */
|
|
|
|
virtual unsigned flag() = 0;
|
|
|
|
/** The user-friendly (probably translated) name of the method */
|
|
|
|
virtual TQString name() {return flagToStr(flag());}
|
|
|
|
/** Actually do perform the auth process */
|
|
|
|
virtual int authenticate(sftpProtocol *ioslave) const = 0;
|
|
|
|
/** Creates a copy of derived class */
|
|
|
|
virtual SSHAuthMethod* clone() = 0;
|
|
|
|
|
|
|
|
virtual ~SSHAuthMethod() {};
|
|
|
|
|
|
|
|
/** Returns a name for the given libssh auth method flag */
|
|
|
|
static TQString flagToStr(unsigned method);
|
|
|
|
|
|
|
|
/** Returns a list of names for all the methods set in the given libssh auth method bitset */
|
|
|
|
static TQStringList bitsetToStr(unsigned method);
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|