You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdebase/tdeioslave/sftp/tdeio_sftp.h

220 lines
7.7 KiB

/*
* 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