diff options
Diffstat (limited to 'tdeioslave/sftp/tdeio_sftp.h')
-rw-r--r-- | tdeioslave/sftp/tdeio_sftp.h | 282 |
1 files changed, 176 insertions, 106 deletions
diff --git a/tdeioslave/sftp/tdeio_sftp.h b/tdeioslave/sftp/tdeio_sftp.h index 30c452f9b..75b295cfd 100644 --- a/tdeioslave/sftp/tdeio_sftp.h +++ b/tdeioslave/sftp/tdeio_sftp.h @@ -1,59 +1,111 @@ -/*************************************************************************** - sftpProtocol.h - description - ------------------- - begin : Sat Jun 30 20:08:47 CDT 2001 - copyright : (C) 2001 by Lucas Fisher - email : ljfisher@purdue.edu -***************************************************************************/ - -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ +/* + * 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 <tqstring.h> -#include <tqcstring.h> -#include <tqobject.h> - #include <kurl.h> #include <tdeio/global.h> #include <tdeio/slavebase.h> #include <kdebug.h> +#include <stdint.h> +#include <memory> -#include "process.h" -#include "sftpfileattr.h" -#include "ksshprocess.h" +#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); - virtual void get(const KURL& url); - virtual void listDir(const KURL& url) ; - virtual void mimetype(const KURL& url); - virtual void stat(const KURL& url); - virtual void copy(const KURL &src, const KURL &dest, int permissions, bool overwrite); - virtual void put(const KURL& url, int permissions, bool overwrite, bool resume); - virtual void closeConnection(); - virtual void slave_status(); - virtual void del(const KURL &url, bool isfile); - virtual void chmod(const KURL& url, int permissions); - virtual void symlink(const TQString& target, const KURL& dest, bool overwrite); - virtual void rename(const KURL& src, const KURL& dest, bool overwrite); - virtual void mkdir(const KURL&url, int permissions); - virtual void openConnection(); + 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. */ @@ -65,85 +117,103 @@ private: // Private variables /** Port we are connected to. */ int mPort; - /** Ssh process to which we send the sftp packets. */ - KSshProcess ssh; + /** The ssh session for the connection */ + ssh_session mSession; - /** Username to use when connecting */ + /** 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; - /** User's password */ + /** 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; - /** Message id of the last sftp packet we sent. */ - unsigned int mMsgId; + /** The open file */ + sftp_file mOpenFile; - /** Type of packet we are expecting to receive next. */ - unsigned char mExpected; + /** 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; - }; + + //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 - bool getPacket(TQByteArray& msg); + void statMime(const KURL &url); + void closeFile(); - /* Type is a sftp packet type found in .sftp.h'. - * Example: SSH2_FXP_READLINK, SSH2_FXP_RENAME, etc. - * - * Returns true if the type is supported by the sftp protocol - * version negotiated by the client and server (sftpVersion). - */ - bool isSupportedOperation(int type); - /** Used to have the server canonicalize any given path name to an absolute path. - This is useful for converting path names containing ".." components or relative - pathnames without a leading slash into absolute paths. - Returns the canonicalized url. */ - int sftpRealPath(const KURL& url, KURL& newUrl); - - /** Send an sftp packet to stdin of the ssh process. */ - bool putPacket(TQByteArray& p); - /** Process SSH_FXP_STATUS packets. */ - void processStatus(TQ_UINT8, const TQString& message = TQString::null); - /** Process SSH_FXP_STATUS packes and return the result. */ - Status doProcessStatus(TQ_UINT8, const TQString& message = TQString::null); - /** Opens a directory handle for url.path. Returns true if succeeds. */ - int sftpOpenDirectory(const KURL& url, TQByteArray& handle); - /** Closes a directory or file handle. */ - int sftpClose(const TQByteArray& handle); - /** Send a sftp command to rename a file or directoy. */ - int sftpRename(const KURL& src, const KURL& dest); - /** Set a files attributes. */ - int sftpSetStat(const KURL& url, const sftpFileAttr& attr); - /** Sends a sftp command to remove a file or directory. */ - int sftpRemove(const KURL& url, bool isfile); - /** Creates a symlink named dest to target. */ - int sftpSymLink(const TQString& target, const KURL& dest); - /** Get directory listings. */ - int sftpReadDir(const TQByteArray& handle, const KURL& url); - /** Retrieves the destination of a link. */ - int sftpReadLink(const KURL& url, TQString& target); - /** Stats a file. */ - int sftpStat(const KURL& url, sftpFileAttr& attr); - /** No descriptions */ - int sftpOpen(const KURL& url, const TQ_UINT32 pflags, const sftpFileAttr& attr, TQByteArray& handle); - /** No descriptions */ - int sftpRead(const TQByteArray& handle, TDEIO::filesize_t offset, TQ_UINT32 len, TQByteArray& data); - /** No descriptions */ - int sftpWrite(const TQByteArray& handle, TDEIO::filesize_t offset, const TQByteArray& data); - - /** Performs faster upload when the source is a local file... */ - void sftpCopyPut(const KURL& src, const KURL& dest, int mode, bool overwrite); - /** Performs faster download when the destination is a local file... */ - void sftpCopyGet(const KURL& dest, const KURL& src, int mode, bool overwrite); - - /** */ - Status sftpGet( const KURL& src, TDEIO::filesize_t offset = 0, int fd = -1); - void sftpPut( const KURL& dest, int permissions, bool resume, bool overwrite, int fd = -1); + /** @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 |