Replaced old sftp ioslave with backported version

Source:  https://github.com/sandsmark/kde2-kio-sftp-kde4
Licence: GPLv2 or later

This resolves issue #276.

Signed-off-by: Mavridis Philippe <mavridisf@gmail.com>
(cherry picked from commit fd94618b63)
r14.0.x
Mavridis Philippe 2 years ago
parent 0b10dbcfa9
commit 6b64de55fb
No known key found for this signature in database
GPG Key ID: F8D2D7E2F989A494

@ -1,3 +0,0 @@
Dawit Alemayehu <adawit@kde.org>
Lucas Fisher <ljfisher@iastate.edu>

@ -1,59 +0,0 @@
- add dialog to ask for username
- rename() causes SSH to die
- How to handle overwrite?
- After the user cancels with the stop button, we get ERR_CANNOT_LAUNCH_PROCESS
errors, until we kill the ioslave. Same thing after trying the wrong passwd
too many times.
This is happening because TDEProcess thinks that the ssh process is still running
even though it exited.
- How to handle password and caching?
- Write our own askpass program using kde
- set env SSH_ASKPASS_PROGRAM before launching
-how to do this? TDEProcess doesn't give us access to env variables.
- Our askpass program can probably talk to the tdesu daemon to implement caching.
- chmod() succeeds, but konqueror always puts permissions to 0 afterwards. The properties
dialog is right though.
Nevermind - ftp ioslave does this too! Maybe a bug with konqueror.
- stat does not give us group and owner names, only numbers. We could cache the uid/name and
gid/name so we can give names when doing a stat also.
7-13-2001 - ReadLink stopped working. sftp server always retuns a file not found error
- Need to implement 64 bit file lengths-->write DataStream << for u_int64
Still need to offer 32 bit size since this is what kde wants. ljf
- rename() isn't exactly causing ioslave to die. The stat of the file we are
going to rename is killing the slave. The slave dies in the statEntry() call.
I don't know what I am putting in the UDS entry that is causing this. ljf
7-14-2001 - got put, mimetype working ljf
- fixed readlink problem - I was sending the wrong path. doh! ljf
7-17-2001 - If the user changes the host, the slave doesn't change host! setHost() is not
called, nor is another ioslave spawned. I have not investigated the problem
yet. ljf
7-21-2001 - got slave working with kde 2.2 cvs
7-22-2001 - probable solution to getting password prompt -- open with controlling
but don't connect stdin/out to terminal. duh!
8-9-2001 - Doh! I haven't kept very good logs. Look at the cvs logs for better info.
- At this point tdeio_sftp is using KSshProcess which I wrote in order to make
a standard interface to the various version of ssh out there. So far it is
working fairly well. We also now report host key changes to the user and
allow them to choose whether or not to continue. This is a big improvement.
- Todo: support use of keys and ssh agent
put()'s resume functionality needs some work
1-26-2002 - Rewrote put() following the ftp::put() so it should behave the same way
- increase the size of the data packet we ask for in ::get up to 60k.
Through-put increases nicely.
- Call closeConnection() from construction. Keeps from having unused ssh
processes laying around after failed operations.
2-19-2002 - get() now emits mimetype, fixes problem with konqi not downloading file for
viewing in kpart.
- get port number using getservbyname instead of hard coding it.
2-27-2002 - testing before committing back to cvs, test with openssh 3, ssh 3
6-?-2002 - rewrote openConnection() to using new KSshProcess connect proceedures
7-20-2002 - Don't put up a message box when auth fails because of now or changed key,
the call to error() will put up the dialog.
- Connect fails and no more password are prompted for when we get
ERR_AUTH_FAILED from KSshProcess.
9-15-2002 - stuff
9-29-2002 - the last i18n string updates, fixed problem with uploading files to
openssh server.
5-8-2003 - check whether operation types are supported by the negotiated sftp
protocol version

@ -1,3 +0,0 @@
##### create translation templates ##############
tde_l10n_create_template( "tdeio_sftp" )

@ -1,13 +1,10 @@
#################################################
#
# (C) 2010-2011 Serghei Amelian
# serghei (DOT) amelian (AT) gmail.com
#
# Improvements and feedback are welcome
#
# This file is released under GPL >= 2
#
#################################################
###########################################
# #
# Improvements and feedback are welcome #
# #
# This file is released under GPL >= 2 #
# #
###########################################
include_directories(
${CMAKE_CURRENT_BINARY_DIR}
@ -21,21 +18,21 @@ link_directories(
)
##### other data ################################
##### other data #########################
tde_create_translated_desktop(
SOURCE sftp.protocol
DESTINATION ${SERVICES_INSTALL_DIR}
PO_DIR tdeioslave-desktops
#PO_DIR tdeioslave-desktops
)
##### tdeio_sftp (module) #########################
##### tdeio_sftp (module) ################
set( target tdeio_sftp )
tde_add_kpart( ${target} AUTOMOC
SOURCES process.cpp atomicio.cpp tdeio_sftp.cpp sftpfileattr.cpp ksshprocess.cpp
LINK tdeio-shared tdesu-shared
SOURCES tdeio_sftp.cpp
LINK tdeio-shared
DESTINATION ${PLUGIN_INSTALL_DIR}
)

@ -1,12 +0,0 @@
DEBUGGING
The best way to debug this slave is to send debug info to a
file using 'tdedebugDialog --fullmode'. Then you can 'tail -f' the file to
see debug messages in real-time.
I also suggest getting the openssh source and recompiling sftp-server to
send messages to the auth log. This can be done in sftp-server.c be defining
DEBUG_SFTP_SERVER.
You can do the same with the ssh client by finding the two calls to log_init()
in ssh.c and changing the last argument from 1 to 0 and recompiling.

@ -1,25 +0,0 @@
## Makefile.am of tdebase/tdeioslave/sftp
INCLUDES = $(all_includes)
AM_LDFLAGS = $(all_libraries) $(KDE_RPATH) $(LIB_QT) -lDCOP $(LIB_TDECORE) $(LIB_TDEUI) -ltdefx $(LIB_TDEIO) -ltdetexteditor
METASOURCES = AUTO
####### Files
check_PROGRAMS = ksshprocesstest
ksshprocesstest_SOURCES = ksshprocesstest.cpp
ksshprocesstest_LDADD = $(LIB_TDESYCOCA) ksshprocess.lo process.lo atomicio.lo
kde_module_LTLIBRARIES = tdeio_sftp.la
tdeio_sftp_la_SOURCES = process.cpp atomicio.cpp tdeio_sftp.cpp sftpfileattr.cpp ksshprocess.cpp
tdeio_sftp_la_LIBADD = $(LIB_TDEIO)
tdeio_sftp_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN)
noinst_HEADERS = atomicio.h tdeio_sftp.h ksshprocess.h process.h sftpfileattr.h sftp.h
kdelnk_DATA = sftp.protocol
kdelnkdir = $(kde_servicesdir)
messages:
$(XGETTEXT) *.cpp -o $(podir)/tdeio_sftp.pot

@ -1,5 +0,0 @@
TODO:
=====
- Support for use of public keys, maybe ssh-agent, a key management app, etc.

@ -1,67 +0,0 @@
/*
* Copyright (c) 1995,1999 Theo de Raadt. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
//#include "includes.h"
//RCSID("$OpenBSD: atomicio.c,v 1.9 2001/03/02 18:54:30 deraadt Exp $");
//#include "xmalloc.h"
#include "atomicio.h"
#include <unistd.h>
#include <errno.h>
#include <kdebug.h>
/*
* ensure all of data on socket comes through. f==read || f==write
*/
ssize_t atomicio(int fd, char *_s, size_t n, bool read)
{
char *s = _s;
ssize_t res;
ssize_t pos = 0;
while (n > pos) {
if( read)
res = ::read(fd, s + pos, n - pos);
else
res = ::write(fd, s + pos, n - pos);
switch (res) {
case -1:
kdDebug() << "atomicio(): errno=" << errno << endl;
#ifdef EWOULDBLOCK
if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)
#else
if (errno == EINTR || errno == EAGAIN)
#endif
continue;
case 0:
return (res);
default:
pos += res;
}
}
return (pos);
}

@ -1,39 +0,0 @@
#ifndef atomicio_h
#define atomicio_h
/* $OpenBSD: atomicio.h,v 1.3 2001/03/02 18:54:30 deraadt Exp $ */
/*
* Copyright (c) 1995,1999 Theo de Raadt. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/types.h>
#include <unistd.h>
/*
* Ensure all of data on socket comes through. f==read || f==write
*/
ssize_t atomicio(int fd, char *_s, size_t n, bool read = true);
#endif

File diff suppressed because it is too large Load Diff

@ -1,623 +0,0 @@
/***************************************************************************
ksshprocess.h - description
-------------------
begin : Tue Jul 31 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. *
* *
***************************************************************************/
#ifndef KSSHPROCESS_H
#define KSSHPROCESS_H
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <unistd.h>
#include <tqvaluelist.h>
#include <kdebug.h>
#include "process.h"
#define KSSHPROC 7120
/**
* Provides version independent access to ssh. Currently supported
* versions of SSH are:
* OpenSSH 2.9p1
* OpenSSH 2.9p2
* OpenSSH 3.0
* OpenSSH 3.1
* Commercial SSH 3.0.0
* Other versions of OpenSSH and commerical SSH will probably work also.
*
* To setup a SSH connection first create a list of options to use and tell
* KSshProcess about your options. Then start the ssh connection. Once the
* connection is setup use the stdin, stdout, stderr, and pty file descriptors
* to communicate with ssh. For a detailed example of how to use, see
* ksshprocesstest.cpp.
*
* @author Lucas Fisher
*
* Example: Connect to ssh server on localhost
* KSshProcess::SshOpt opt;
* KSshProcess::SshOptList options;
*
* opt.opt = KSshProcess::SSH_HOST;
* opt.str = "localhost";
* options.append(opt);
*
* opt.opt = KSshProcess::SSH_USERNAME;
* opt.str = "me";
* options.append(opt);
*
* KSshProcess ssh;
* if( !ssh.setOptions(options) ) {
* int err = ssh.error();
* // process error
* return false;
* }
*
* int err;
* TQString errMsg;
* while( !ssh.connect() ) {
* err = ssh.error(errMsg);
*
* switch( err ) {
* case KSshProcess::ERR_NEW_HOST_KEY:
* case KSshProcess::ERR_DIFF_HOST_KEY:
* // ask user to accept key
* if( acceptHostKey ) {
* ssh.acceptKey(true);
* }
* break;
*
* case KSshProcess::ERR_NEED_PASSWORD:
* // ask user for password
* ssh.password(userPassword);
* break;
*
* case KSshProcess::ERR_NEED_KEY_PASSPHRASE:
* // ask user for their key passphrase
* ssh.keyPassphrase(keyPassphrase);
* break;
*
* default:
* // somethings wrong, alert user
* return;
* }
* }
* // We have an open ssh connection to localhost
*
*/
class KSshProcess {
public:
/**
* SSH Option
*
* Stores SSH options for use with KSshProcess.
*
* SSH options are configured much like UDS entries.
* Each option is assigned a constant and a string, bool,
* or number is assigned based on the option.
*
* @author Lucas Fisher (ljfisher@iastate.edu)
*/
class SshOpt {
public:
TQ_UINT32 opt;
TQString str;
TQ_INT32 num;
bool boolean;
};
/**
* List of SshOptions and associated iterators
*/
typedef TQValueList<SshOpt> SshOptList;
typedef TQValueListIterator<SshOpt> SshOptListIterator;
typedef TQValueListConstIterator<SshOpt> SshOptListConstIterator;
/**
* Ssh versions supported by KSshProcess. Subject to change
* at any time.
*/
enum SshVersion {
OPENSSH_3_6,
OPENSSH,
SSH,
SSH_VER_MAX,
UNKNOWN_VER
};
/**
* SSH options supported by KSshProcess. Set SshOpt::opt to one of these
* values.
*/
// we cannot do this like UDSAtomType (ORing the type with the name) because
// we have too many options for ssh and not enough bits.
enum SshOptType {
/**
* Request server to invoke subsystem. (str)
*/
SSH_SUBSYSTEM,
/**
* Connect to port on the server. (num)
*/
SSH_PORT,
/**
* Connect to host. (str)
*/
SSH_HOST,
/**
* connect using this username. (str)
*/
SSH_USERNAME,
/**
* connect using this password. (str)
*/
SSH_PASSWD,
/**
* connect using this version of the SSH protocol. num == 1 or 2
*/
SSH_PROTOCOL,
/**
* whether to forward X11 connections. (boolean)
*/
SSH_FORWARDX11,
/**
* whether to do agent forwarding. (boolean)
*/
SSH_FORWARDAGENT,
/**
* use as escape character. 0 for none (num)
*/
SSH_ESCAPE_CHAR,
/**
* command for ssh to perform once it is connected (str)
*/
SSH_COMMAND,
/**
* Set ssh verbosity. This may be added multiple times. It may also cause KSSHProcess
* to fail since we don't understand all the debug messages.
*/
SSH_VERBOSE,
/**
* Set a ssh option as one would find in the ssh_config file
* The str member should be set to 'optName value'
*/
SSH_OPTION,
/**
* Set some other option not supported by KSSHProcess. The option should
* be specified in the str member of SshOpt. Careful with this since
* not all versions of SSH support the same options.
*/
SSH_OTHER,
SSH_OPT_MAX // always last
}; // that's all for now
/**
* Errors that KSshProcess can encounter. When a member function returns
* false, call error() to retrieve one of these error codes.
*/
enum SshError {
/**
* Don't recognize the ssh version
*/
ERR_UNKNOWN_VERSION,
/**
* Cannot lauch ssh client
*/
ERR_CANNOT_LAUNCH,
/**
* Interaction with the ssh client failed. This happens when we can't
* find the password prompt or something similar
*/
ERR_INTERACT,
/**
* Arguments for both a remotely executed subsystem and command were provide.
* Only one or the other may be used
*/
ERR_CMD_SUBSYS_CONFLICT,
/**
* No password was supplied
*/
ERR_NEED_PASSWD,
/**
* No passphrase was supplied.
*/
ERR_NEED_PASSPHRASE,
/**
* No usename was supplied
*/
ERR_NEED_USERNAME,
/**
* Timed out waiting for a response from ssh or the server
*/
ERR_TIMED_OUT,
/**
* Internal error, probably from a system call
*/
ERR_INTERNAL,
/**
* ssh was disconnect from the host
*/
ERR_DISCONNECTED,
/**
* No ssh options have been set. Call setArgs() before calling connect.
*/
ERR_NO_OPTIONS,
/**
* A host key was received from an unknown host.
* Call connect() with the acceptHostKey argument to accept the key.
*/
ERR_NEW_HOST_KEY,
/**
* A host key different from what is stored in the user's known_hosts file
* has be received. This is an indication of an attack
*/
ERR_DIFF_HOST_KEY,
/**
* A new or different host key was rejected by the caller. The ssh
* connection was terminated and the ssh process killed.
*/
ERR_HOST_KEY_REJECTED,
/**
* An invalid option was found in the SSH option list
*/
ERR_INVALID_OPT,
/**
* SSH accepted host key without prompting user.
*/
ERR_ACCEPTED_KEY,
/**
* Authentication failed
*/
ERR_AUTH_FAILED,
/**
* Authentication failed because a new host key was detected and
* SSH is configured with strict host key checking enabled.
*/
ERR_AUTH_FAILED_NEW_KEY,
/**
* Authentication failed because a changed host key was detected and
* SSH is configured with strict host key checking enabled.
*/
ERR_AUTH_FAILED_DIFF_KEY,
/**
* The remote host closed the connection for unknown reasons.
*/
ERR_CLOSED_BY_REMOTE_HOST,
/**
* We have no idea what happened
*/
ERR_UNKNOWN,
/**
* The connect state machine entered an invalid state.
*/
ERR_INVALID_STATE,
ERR_MAX
};
/**
* Initialize a SSH process using the first SSH binary found in the PATH
*/
KSshProcess();
/**
* Initialize a SSH process using the specified SSH binary.
* @param pathToSsh The fully qualified path name of the ssh binary
* KSshProcess should use to setup a SSH connection.
*/
KSshProcess(TQString pathToSsh);
~KSshProcess();
/**
* Set the ssh binary KSshProcess should use. This will only affect the
* next ssh connection attempt using this instance.
*
* @param pathToSsh Full path to the ssh binary.
*
* @return True if the ssh binary is found and KSshProcess
* recognizes the version.
*
*/
bool setSshPath(TQString pathToSsh);
/**
* Get the ssh version.
*
* @return The ssh version or -1 if KSshProcess does not recognize
* the ssh version. The returned value corresponds to the
* member of the SshVersion enum.
*/
SshVersion version();
/**
* Get a string describing the ssh version
*
* @return A string describing the ssh version recognized by KSshProcess
*/
//TQString versionStr();
/**
* Get the last error encountered by KSshProcess.
*
* @param msg Set to the error message, if any, outputted by ssh when it is run.
*
* @return The error number. See SshError for descriptions.
*/
int error(TQString& msg);
/**
* Get the last error encountered by KSshProcess.
* @return The error number. See SshError for descriptions.
*/
int error() { return mError; }
TQString errorMsg() { return mErrorMsg; }
/**
* Send a signal to the ssh process. Do not use this to end the
* ssh connection as it will not correctly reset the internal
* state of the KSshProcess object. Use KSshProcess::disconnect()
* instead.
*
* @param signal The signal to send to the ssh process. See 'kill -l'
* for a list of possible signals.
* The default signal is SIGKILL which kills ssh.
*
*/
void kill(int signal = SIGKILL);
/**
* The pid of the ssh process started by this instance of KSshProcess.
* Only valid if KSshProcess::running() returns true;
*
* @return The pid of the running ssh process.
*/
int pid() { return ssh.pid(); }
/**
* Whether a ssh connection has been established with a
* remote host. A establish connection means ssh has successfully
* authenticated with the remote host and user data can be transfered
* between the local and remote host. This cannot return
* true unless the most recent call to KSshProccess::connect() returned true.
*
* @return True if a ssh connection has been established with a remote
* host. False otherwise.
*/
bool connected() { return mConnected; }
/**
* Whether a ssh process is currently running. This only indicates
* if a ssh process has been started and is still running. It does not
* tell if authentication has been successful. This may return true
* even if the most recent call to KSshProcess::connect() returned false.
*
* @return True if a ssh process started by this instance of KSshProcess
* is running. False otherwise.
*/
bool running() { return mRunning; }
/**
* Print the command line arguments ssh is run with using kdDebug.
*/
void printArgs();
/**
* Set the SSH options.
* This must be called before connect(). See SshOptType for a list of
* supported ssh options. The required options are SSH_USERNAME
* and SSH_HOST.
*
* To reset the saved options, just recall setOptions() again with
* a different options list.
*
* @param opts A list of SshOpt objects specifying the ssh options.
*
* @return True if all options are valid. False if unrecognized options
* or a required option is missing. Call error()
* for details.
*
*/
bool setOptions(const SshOptList& opts);
/**
* Create a ssh connection based on the options provided by setOptions().
* Sets one of the following error codes on failure:
* <ul>
* <li>ERR_NO_OPTIONS</li>
* <li>ERR_CANNOT_LAUNCH</li>
* <li>ERR_INVALID_STATE</li>
* <li>ERR_NEED_PASSWD</li>
* <li>ERR_AUTH_FAILED</li>
* <li>ERR_NEW_HOST_KEY</li>
* <li>ERR_KEY_ACCEPTED</li>
* <li>ERR_DIFF_HOST_KEY</li>
* <li>ERR_INTERNAL</li>
* <li>ERR_INTERACT</li>
* </ul>
*
* @param acceptHostKey When true KSshProcess will automatically accept
* unrecognized or changed host keys.
*
* @return True if the ssh connection is successful. False if the connection
* fails. Call error() to get the reason for the failure.
*/
bool connect();
/**
* Disconnect ssh from the host. This kills the ssh process and
* resets the internal state of this KSshProcess object. After a
* disconnect, the same KSshProcess can be used to connect to a
* host.
*/
void disconnect();
/**
* Call to respond to a ERR_NEW_HOST_KEY or ERR_DIFF_HOST_KEY error.
*
* @param accept True to accept the host key, false to not accept the
* host key and kill ssh.
*
*/
void acceptHostKey(bool accept);
/**
* Call to respond to a ERR_NEED_PASSWD or ERR_NEED_PASSPHRASE error.
*
* @param password The user password to give ssh.
*/
void setPassword(TQString password);
/**
* Access to standard in and out of the ssh process.
*
* @return The file description for stdin and stdout of the ssh process.
*/
int stdioFd() { return ssh.stdioFd(); }
/**
* Access to standard error of the ssh process.
*
* @return The file descriptior for stderr of the ssh process.
*/
int stderrFd() { return ssh.stderrFd(); }
/**
* Access the pty to which the ssh process is attached.
*
* @return The file descriptor of pty to which ssh is attached.
*/
int pty() { return ssh.fd(); }
private:
/**
* Path the the ssh binary.
*/
TQString mSshPath;
/**
* SSH version. This is an index into the supported SSH
* versions array, and the various messages arrays.
*/
SshVersion mVersion;
/**
* User's password. Zero this out when it is no longer needed.
*/
TQString mPassword;
/**
* User's username.
*/
TQString mUsername;
/**
* Name of host we are connecting to.
*/
TQString mHost;
/**
* Accept new or changed host keys if true.
*/
bool mAcceptHostKey;
/**
* Flag to tell use if we have an open, authenticated ssh
* session going.
*/
bool mConnected;
/**
* Flag to tell us if we have started a ssh process, we use this
* to make sure we kill ssh before going away.
*/
bool mRunning;
/**
* Save any key fingerprint msg from ssh so we can present
* it to the caller.
*/
TQString mKeyFingerprint;
/**
* The location of the known host key file. We grab this from
* any error messages ssh prints out.
*/
TQString mKnownHostsFile;
/**
* The state of our connect state machine.
*/
int mConnectState;
/**
* Port on on which the target ssh server is listening.
*/
int mPort;
/**
* The last error number encountered. This is only valid for the
* last error.
*/
SshError mError;
/**
* An error message that corresponds to the error number set in
* mError. Optional.
*/
TQString mErrorMsg;
/**
* Interface to the SSH process we ceate. Handles communication
* to and from the SSH process using stdin, stdout, stderr, and
* pty.
*/
MyPtyProcess ssh;
/**
* List of arguments we start SSH with.
*/
QCStringList mArgs;
void init();
/**
* Handler to clean up when ssh process terminates.
*/
static void SIGCHLD_handler(int signo);
void installSignalHandlers();
void removeSignalHandlers();
TQString getLine();
static TQRegExp versionStrs[];
static const char * const passwordPrompt[];
static const char * const passphrasePrompt[];
static const char * const authSuccessMsg[];
static const char * const authFailedMsg[];
static TQRegExp hostKeyMissingMsg[];
static const char * const hostKeyChangedMsg[];
static const char * const continuePrompt[];
static const char * const hostKeyAcceptedMsg[];
static const char * const tryAgainMsg[];
static TQRegExp hostKeyVerifyFailedMsg[];
static const char * const connectionClosedMsg[];
static const char * const changeHostKeyOnDiskPrompt[];
static TQRegExp keyFingerprintMsg[];
static TQRegExp knownHostsFileMsg[];
};
#endif

@ -1,98 +0,0 @@
#include "ksshprocess.h"
#include <iostream>
using namespace std;
int main(int argc, char *argv[]) {
if( argc < 5 ) {
cout << "Usage: " << argv[0] <<
" <ssh path> <host> <username> <password>" << endl;
return 1;
}
KSshProcess ssh(argv[1]);
cout << ssh.version() << endl;
KSshProcess::SshOptList opts;
KSshProcess::SshOpt opt;
opt.opt = KSshProcess::SSH_PORT;
opt.num = 22;
opts.append(opt);
opt.opt = KSshProcess::SSH_HOST;
opt.str = TQString(argv[2]);
opts.append(opt);
opt.opt = KSshProcess::SSH_USERNAME;
opt.str = TQString(argv[3]);
opts.append(opt);
// opt.opt = KSshProcess::SSH_PASSWD;
// opt.str = TQString(argv[4]);
// opts.append(opt);
if( !ssh.setOptions(opts) ) {
cout << "ksshprocesstest: setOptions failed" << endl;
return -1;
}
ssh.printArgs();
bool stop = false;
bool connected;
char buf[256];
char c;
while( !stop && !(connected = ssh.connect()) ) {
cout << "ksshprocesstest: Error num - " << ssh.error() << endl;
cout << "ksshprocesstest: Error msg - " << ssh.errorMsg().latin1() << endl;
switch( ssh.error() ) {
case KSshProcess::ERR_NEED_PASSWD:
case KSshProcess::ERR_NEED_PASSPHRASE:
cout << "Password: ";
cin >> buf;
cout << "password is " << buf << endl;
ssh.setPassword(TQString(buf));
break;
case KSshProcess::ERR_NEW_HOST_KEY:
case KSshProcess::ERR_DIFF_HOST_KEY:
cout << "Accept host key? (y/n): ";
cin >> c;
cout << "Answered " << c << endl;
ssh.acceptHostKey(c == 'y' ? true : false);
break;
case KSshProcess::ERR_AUTH_FAILED:
cout << "ksshprocesstest: auth failed." << endl;
stop = true;
break;
case KSshProcess::ERR_AUTH_FAILED_NEW_KEY:
cout << "ksshprocesstest: auth failed because of new key." << endl;
stop = true;
break;
case KSshProcess::ERR_AUTH_FAILED_DIFF_KEY:
cout << "ksshprocesstest: auth failed because of changed key." << endl;
stop = true;
break;
case KSshProcess::ERR_INTERACT:
case KSshProcess::ERR_INTERNAL:
case KSshProcess::ERR_UNKNOWN:
case KSshProcess::ERR_INVALID_STATE:
case KSshProcess::ERR_CANNOT_LAUNCH:
case KSshProcess::ERR_HOST_KEY_REJECTED:
cout << "ksshprocesstest: FATAL ERROR" << endl;
stop = true;
break;
}
}
if( connected ) {
cout << "ksshprocesstest: Successfully connected to " << argv[2] << endl;
}
else {
cout << "ksshprocesstest: Connect to " << argv[2] << " failed." << endl;
}
}

@ -1,493 +0,0 @@
/*
*
*
* This file is part of the KDE project, module tdesu.
* Copyright (C) 1999,2000 Geert Jansen <jansen@kde.org>
*
* This file contains code from TEShell.C of the KDE konsole.
* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
*
* This is free software; you can use this library under the GNU Library
* General Public License, version 2. See the file "COPYING.LIB" for the
* exact licensing terms.
*
* process.cpp: Functionality to build a front end to password asking
* terminal programs.
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <errno.h>
#include <string.h>
#include <termios.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/socket.h>
#if defined(__SVR4) && defined(sun)
#include <stropts.h>
#include <sys/stream.h>
#endif
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h> // Needed on some systems.
#endif
#include <tqglobal.h>
#include <tqcstring.h>
#include <tqfile.h>
#include <kdebug.h>
#include <kstandarddirs.h>
#include "process.h"
#include <tdesu/tdesu_pty.h>
#include <tdesu/kcookie.h>
MyPtyProcess::MyPtyProcess()
{
m_bTerminal = false;
m_bErase = false;
m_pPTY = 0L;
m_Pid = -1;
m_Fd = -1;
}
int MyPtyProcess::init()
{
delete m_pPTY;
m_pPTY = new PTY();
m_Fd = m_pPTY->getpt();
if (m_Fd < 0)
return -1;
if ((m_pPTY->grantpt() < 0) || (m_pPTY->unlockpt() < 0))
{
kdError(PTYPROC) << k_lineinfo << "Master setup failed.\n" << endl;
m_Fd = -1;
return -1;
}
m_TTY = m_pPTY->ptsname();
m_stdoutBuf.resize(0);
m_stderrBuf.resize(0);
m_ptyBuf.resize(0);
return 0;
}
MyPtyProcess::~MyPtyProcess()
{
delete m_pPTY;
}
/*
* Read one line of input. The terminal is in canonical mode, so you always
* read a line at at time, but it's possible to receive multiple lines in
* one time.
*/
TQCString MyPtyProcess::readLineFrom(int fd, TQCString& inbuf, bool block)
{
int pos;
TQCString ret;
if (!inbuf.isEmpty())
{
pos = inbuf.find('\n');
if (pos == -1)
{
ret = inbuf;
inbuf.resize(0);
} else
{
ret = inbuf.left(pos);
inbuf = inbuf.mid(pos+1);
}
return ret;
}
int flags = fcntl(fd, F_GETFL);
if (flags < 0)
{
kdError(PTYPROC) << k_lineinfo << "fcntl(F_GETFL): " << perror << "\n";
return ret;
}
if (block)
flags &= ~O_NONBLOCK;
else
flags |= O_NONBLOCK;
if (fcntl(fd, F_SETFL, flags) < 0)
{
kdError(PTYPROC) << k_lineinfo << "fcntl(F_SETFL): " << perror << "\n";
return ret;
}
int nbytes;
char buf[256];
while (1)
{
nbytes = read(fd, buf, 255);
if (nbytes == -1)
{
if (errno == EINTR)
continue;
else break;
}
if (nbytes == 0)
break; // eof
buf[nbytes] = '\000';
inbuf += buf;
pos = inbuf.find('\n');
if (pos == -1)
{
ret = inbuf;
inbuf.resize(0);
} else
{
ret = inbuf.left(pos);
inbuf = inbuf.mid(pos+1);
}
break;
}
return ret;
}
void MyPtyProcess::writeLine(TQCString line, bool addnl)
{
if (!line.isEmpty())
write(m_Fd, line, line.length());
if (addnl)
write(m_Fd, "\n", 1);
}
void MyPtyProcess::unreadLineFrom(TQCString inbuf, TQCString line, bool addnl)
{
if (addnl)
line += '\n';
if (!line.isEmpty())
inbuf.prepend(line);
}
/*
* Fork and execute the command. This returns in the parent.
*/
int MyPtyProcess::exec(TQCString command, QCStringList args)
{
kdDebug(PTYPROC) << "MyPtyProcess::exec(): " << command << endl;// << ", args = " << args << endl;
if (init() < 0)
return -1;
// Open the pty slave before forking. See SetupTTY()
int slave = open(m_TTY, O_RDWR);
if (slave < 0)
{
kdError(PTYPROC) << k_lineinfo << "Could not open slave pty.\n";
return -1;
}
// Also create a socket pair to connect to standard in/out.
// This will allow use to bypass the terminal.
int inout[2];
int err[2];
int ok = 1;
ok &= socketpair(AF_UNIX, SOCK_STREAM, 0, inout) >= 0;
ok &= socketpair(AF_UNIX, SOCK_STREAM, 0, err ) >= 0;
if( !ok ) {
kdDebug(PTYPROC) << "Could not create socket" << endl;
return -1;
}
m_stdinout = inout[0];
m_err = err[0];
if ((m_Pid = fork()) == -1)
{
kdError(PTYPROC) << k_lineinfo << "fork(): " << perror << "\n";
return -1;
}
// Parent
if (m_Pid)
{
close(slave);
close(inout[1]);
close(err[1]);
return 0;
}
// Child
ok = 1;
ok &= dup2(inout[1], STDIN_FILENO) >= 0;
ok &= dup2(inout[1], STDOUT_FILENO) >= 0;
ok &= dup2(err[1], STDERR_FILENO) >= 0;
if( !ok )
{
kdError(PTYPROC) << "dup of socket descriptor failed" << endl;
_exit(1);
}
close(inout[1]);
close(inout[0]);
close(err[1]);
close(err[0]);
if (SetupTTY(slave) < 0)
_exit(1);
// From now on, terminal output goes through the tty.
TQCString path;
if (command.contains('/'))
path = command;
else
{
TQString file = TDEStandardDirs::findExe(command);
if (file.isEmpty())
{
kdError(PTYPROC) << k_lineinfo << command << " not found\n";
_exit(1);
}
path = TQFile::encodeName(file);
}
int i;
const char * argp[32];
argp[0] = path;
QCStringList::Iterator it;
for (i=1, it=args.begin(); it!=args.end() && i<31; it++) {
argp[i++] = *it;
kdDebug(PTYPROC) << *it << endl;
}
argp[i] = 0L;
execv(path, (char * const *)argp);
kdError(PTYPROC) << k_lineinfo << "execv(\"" << path << "\"): " << perror << "\n";
_exit(1);
return -1; // Shut up compiler. Never reached.
}
/*
* Wait until the terminal is set into no echo mode. At least one su
* (RH6 w/ Linux-PAM patches) sets noecho mode AFTER writing the Password:
* prompt, using TCSAFLUSH. This flushes the terminal I/O queues, possibly
* taking the password with it. So we wait until no echo mode is set
* before writing the password.
* Note that this is done on the slave fd. While Linux allows tcgetattr() on
* the master side, Solaris doesn't.
*/
int MyPtyProcess::WaitSlave()
{
int slave = open(m_TTY, O_RDWR);
if (slave < 0)
{
kdError(PTYPROC) << k_lineinfo << "Could not open slave tty.\n";
return -1;
}
struct termios tio;
struct timeval tv;
while (1)
{
if (tcgetattr(slave, &tio) < 0)
{
kdError(PTYPROC) << k_lineinfo << "tcgetattr(): " << perror << "\n";
close(slave);
return -1;
}
if (tio.c_lflag & ECHO)
{
kdDebug(PTYPROC) << k_lineinfo << "Echo mode still on." << endl;
// sleep 1/10 sec
tv.tv_sec = 0; tv.tv_usec = 100000;
select(slave, 0L, 0L, 0L, &tv);
continue;
}
break;
}
close(slave);
return 0;
}
int MyPtyProcess::enableLocalEcho(bool enable)
{
int slave = open(m_TTY, O_RDWR);
if (slave < 0)
{
kdError(PTYPROC) << k_lineinfo << "Could not open slave tty.\n";
return -1;
}
struct termios tio;
if (tcgetattr(slave, &tio) < 0)
{
kdError(PTYPROC) << k_lineinfo << "tcgetattr(): " << perror << "\n";
close(slave); return -1;
}
if (enable)
tio.c_lflag |= ECHO;
else
tio.c_lflag &= ~ECHO;
if (tcsetattr(slave, TCSANOW, &tio) < 0)
{
kdError(PTYPROC) << k_lineinfo << "tcsetattr(): " << perror << "\n";
close(slave); return -1;
}
close(slave);
return 0;
}
/*
* Copy output to stdout until the child process exists, or a line of output
* matches `m_Exit'.
* We have to use waitpid() to test for exit. Merely waiting for EOF on the
* pty does not work, because the target process may have children still
* attached to the terminal.
*/
int MyPtyProcess::waitForChild()
{
int ret, state, retval = 1;
struct timeval tv;
fd_set fds;
FD_ZERO(&fds);
while (1)
{
tv.tv_sec = 1; tv.tv_usec = 0;
FD_SET(m_Fd, &fds);
ret = select(m_Fd+1, &fds, 0L, 0L, &tv);
if (ret == -1)
{
if (errno == EINTR) continue;
else
{
kdError(PTYPROC) << k_lineinfo << "select(): " << perror << "\n";
return -1;
}
}
if (ret)
{
TQCString line = readLine(false);
while (!line.isNull())
{
if (!m_Exit.isEmpty() && !tqstrnicmp(line, m_Exit, m_Exit.length()))
kill(m_Pid, SIGTERM);
if (m_bTerminal)
{
fputs(line, stdout);
fputc('\n', stdout);
}
line = readLine(false);
}
}
// Check if the process is still alive
ret = waitpid(m_Pid, &state, WNOHANG);
if (ret < 0)
{
if (errno == ECHILD)
retval = 0;
else
kdError(PTYPROC) << k_lineinfo << "waitpid(): " << perror << "\n";
break;
}
if (ret == m_Pid)
{
if (WIFEXITED(state))
retval = WEXITSTATUS(state);
break;
}
}
return -retval;
}
/*
* SetupTTY: Creates a new session. The filedescriptor "fd" should be
* connected to the tty. It is closed after the tty is reopened to make it
* our controlling terminal. This way the tty is always opened at least once
* so we'll never get EIO when reading from it.
*/
int MyPtyProcess::SetupTTY(int fd)
{
// Reset signal handlers
for (int sig = 1; sig < NSIG; sig++)
signal(sig, SIG_DFL);
signal(SIGHUP, SIG_IGN);
// Close all file handles
// struct rlimit rlp;
// getrlimit(RLIMIT_NOFILE, &rlp);
// for (int i = 0; i < (int)rlp.rlim_cur; i++)
// if (i != fd) close(i);
// Create a new session.
setsid();
// Open slave. This will make it our controlling terminal
int slave = open(m_TTY, O_RDWR);
if (slave < 0)
{
kdError(PTYPROC) << k_lineinfo << "Could not open slave side: " << perror << "\n";
return -1;
}
close(fd);
#if defined(__SVR4) && defined(sun)
// Solaris STREAMS environment.
// Push these modules to make the stream look like a terminal.
ioctl(slave, I_PUSH, "ptem");
ioctl(slave, I_PUSH, "ldterm");
#endif
// Connect stdin, stdout and stderr
// dup2(slave, 0); dup2(slave, 1); dup2(slave, 2);
// if (slave > 2)
// close(slave);
// Disable OPOST processing. Otherwise, '\n' are (on Linux at least)
// translated to '\r\n'.
struct termios tio;
if (tcgetattr(slave, &tio) < 0)
{
kdError(PTYPROC) << k_lineinfo << "tcgetattr(): " << perror << "\n";
return -1;
}
tio.c_oflag &= ~OPOST;
if (tcsetattr(slave, TCSANOW, &tio) < 0)
{
kdError(PTYPROC) << k_lineinfo << "tcsetattr(): " << perror << "\n";
return -1;
}
return 0;
}

@ -1,148 +0,0 @@
/*
*
*
* This file is part of the KDE project, module tdesu.
* Copyright (C) 1999,2000 Geert Jansen <jansen@kde.org>
*
* This is free software; you can use this library under the GNU Library
* General Public License, version 2. See the file "COPYING.LIB" for the
* exact licensing terms.
*/
#ifndef __Process_h_Included__
#define __Process_h_Included__
#include <tqcstring.h>
#include <tqstring.h>
#include <tqstringlist.h>
#include <tqvaluelist.h>
#define PTYPROC 7120
class PTY;
typedef TQValueList<TQCString> QCStringList;
/**
* Synchronous communication with tty programs.
*
* PtyProcess provides synchronous communication with tty based programs.
* The communications channel used is a pseudo tty (as opposed to a pipe)
* This means that programs which require a terminal will work.
*/
class MyPtyProcess
{
public:
MyPtyProcess();
virtual ~MyPtyProcess();
/**
* Fork off and execute a command. The command's standard in and output
* are connected to the pseudo tty. They are accessible with @ref #readLine
* and @ref #writeLine.
* @param command The command to execute.
* @param args The arguments to the command.
*/
int exec(TQCString command, QCStringList args);
/**
* Read a line from the program's standard out. Depending on the @em block
* parameter, this call blocks until a single, full line is read.
* @param block Block until a full line is read?
* @return The output string.
*/
TQCString readLine(bool block = true)
{ return readLineFrom(m_Fd, m_ptyBuf, block); }
TQCString readLineFromPty(bool block = true)
{ return readLineFrom(m_Fd, m_ptyBuf, block); }
TQCString readLineFromStdout(bool block = true)
{ return readLineFrom(m_stdinout, m_stdoutBuf, block); }
TQCString readLineFromStderr(bool block = true)
{ return readLineFrom(m_err, m_stderrBuf, block); }
/**
* Write a line of text to the program's standard in.
* @param line The text to write.
* @param addNewline Adds a '\n' to the line.
*/
void writeLine(TQCString line, bool addNewline=true);
/**
* Put back a line of input.
* @param line The line to put back.
* @param addNewline Adds a '\n' to the line.
*/
void unreadLine(TQCString line, bool addNewline = true)
{ unreadLineFrom(m_ptyBuf, line, addNewline); }
void unreadLineFromPty(TQCString line, bool addNewline = true)
{ unreadLineFrom(m_ptyBuf, line, addNewline); }
void unreadLineFromStderr(TQCString line, bool addNewline = true)
{ unreadLineFrom(m_stderrBuf, line, addNewline); }
void unreadLineFromStdout(TQCString line, bool addNewline = true)
{ unreadLineFrom(m_stdoutBuf, line, addNewline); }
/**
* Set exit string. If a line of program output matches this,
* @ref #waitForChild() will terminate the program and return.
*/
void setExitString(TQCString exit) { m_Exit = exit; }
/**
* Wait for the child to exit. See also @ref #setExitString.
*/
int waitForChild();
/**
* Wait until the pty has cleared the ECHO flag. This is useful
* when programs write a password prompt before they disable ECHO.
* Disabling it might flush any input that was written.
*/
int WaitSlave();
/** Enables/disables local echo on the pseudo tty. */
int enableLocalEcho(bool enable=true);
/** Enable/disable terminal output. Relevant only to some subclasses. */
void setTerminal(bool terminal) { m_bTerminal = terminal; }
/** Overwritte the password as soon as it is used. Relevant only to
* some subclasses. */
void setErase(bool erase) { m_bErase = erase; }
/** Return the filedescriptor of the process. */
int fd() {return m_Fd;}
/** Return the pid of the process. */
int pid() {return m_Pid;}
int stdioFd() {return m_stdinout;}
int stderrFd() {return m_err;}
protected:
bool m_bErase, m_bTerminal;
int m_Pid, m_Fd, m_stdinout, m_err;
TQCString m_Command, m_Exit;
private:
int init();
int SetupTTY(int fd);
PTY *m_pPTY;
TQCString m_TTY;
TQCString m_ptyBuf, m_stderrBuf, m_stdoutBuf;
TQCString readLineFrom(int fd, TQCString& inbuf, bool block);
void unreadLineFrom(TQCString inbuf, TQCString line, bool addnl);
class PtyProcessPrivate;
PtyProcessPrivate *d;
};
#endif

@ -1,91 +0,0 @@
/* $OpenBSD: sftp.h,v 1.3 2001/03/07 10:11:23 djm Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* draft-ietf-secsh-filexfer-01.txt
*/
/* version */
#define SSH2_FILEXFER_VERSION 3
/* client to server */
#define SSH2_FXP_INIT 1
#define SSH2_FXP_OPEN 3
#define SSH2_FXP_CLOSE 4
#define SSH2_FXP_READ 5
#define SSH2_FXP_WRITE 6
#define SSH2_FXP_LSTAT 7
#define SSH2_FXP_FSTAT 8
#define SSH2_FXP_SETSTAT 9
#define SSH2_FXP_FSETSTAT 10
#define SSH2_FXP_OPENDIR 11
#define SSH2_FXP_READDIR 12
#define SSH2_FXP_REMOVE 13
#define SSH2_FXP_MKDIR 14
#define SSH2_FXP_RMDIR 15
#define SSH2_FXP_REALPATH 16
#define SSH2_FXP_STAT 17
#define SSH2_FXP_RENAME 18
#define SSH2_FXP_READLINK 19
#define SSH2_FXP_SYMLINK 20
/* server to client */
#define SSH2_FXP_VERSION 2
#define SSH2_FXP_STATUS 101
#define SSH2_FXP_HANDLE 102
#define SSH2_FXP_DATA 103
#define SSH2_FXP_NAME 104
#define SSH2_FXP_ATTRS 105
#define SSH2_FXP_EXTENDED 200
#define SSH2_FXP_EXTENDED_REPLY 201
/* attributes */
#define SSH2_FILEXFER_ATTR_SIZE 0x00000001
#define SSH2_FILEXFER_ATTR_UIDGID 0x00000002
#define SSH2_FILEXFER_ATTR_PERMISSIONS 0x00000004
#define SSH2_FILEXFER_ATTR_ACMODTIME 0x00000008
#define SSH2_FILEXFER_ATTR_EXTENDED 0x80000000
/* portable open modes */
#define SSH2_FXF_READ 0x00000001
#define SSH2_FXF_WRITE 0x00000002
#define SSH2_FXF_APPEND 0x00000004
#define SSH2_FXF_CREAT 0x00000008
#define SSH2_FXF_TRUNC 0x00000010
#define SSH2_FXF_EXCL 0x00000020
/* status messages */
#define SSH2_FX_OK 0
#define SSH2_FX_EOF 1
#define SSH2_FX_NO_SUCH_FILE 2
#define SSH2_FX_PERMISSION_DENIED 3
#define SSH2_FX_FAILURE 4
#define SSH2_FX_BAD_MESSAGE 5
#define SSH2_FX_NO_CONNECTION 6
#define SSH2_FX_CONNECTION_LOST 7
#define SSH2_FX_OP_UNSUPPORTED 8
#define SSH2_FX_MAX 8

@ -2,7 +2,7 @@
exec=tdeio_sftp
protocol=sftp
input=none
listing=Name,Type,Size,Date,Access,Owner,Group,Link
listing=Name,Type,Size,Date,Access,Owner,Group,Link,MimeType
output=filesystem
copyToFile=true
copyFromFile=true
@ -12,7 +12,7 @@ makedir=true
deleting=true
moving=true
Icon=ftp
Description=A tdeioslave for sftp
Description=A new tdeioslave for sftp
X-DocPath=tdeioslave/sftp/index.html
Icon=ftp
Class=:internet

@ -1,345 +0,0 @@
/***************************************************************************
sftpfileattr.cpp - description
-------------------
begin : Sat Jun 30 2001
copyright : (C) 2001 by Lucas Fisher
email : ljfisher@iastate.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. *
* *
***************************************************************************/
#include "sftpfileattr.h"
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <tqstring.h>
#include <tqdatastream.h>
#include <tdeio/global.h>
#include <kremoteencoding.h>
using namespace TDEIO;
sftpFileAttr::sftpFileAttr(){
clear();
mDirAttrs = false;
}
sftpFileAttr::sftpFileAttr(KRemoteEncoding* encoding){
clear();
mDirAttrs = false;
mEncoding = encoding;
}
/** Constructor to initialize the file attributes on declaration. */
sftpFileAttr::sftpFileAttr(TQ_ULLONG size, uid_t uid, gid_t gid,
mode_t permissions, time_t atime,
time_t mtime, TQ_UINT32 extendedCount) {
clear();
mDirAttrs = false;
mSize = size;
mUid = uid;
mGid = gid;
mAtime = atime;
mMtime = mtime;
mPermissions = permissions;
mExtendedCount = extendedCount;
}
sftpFileAttr::~sftpFileAttr(){
}
/** Returns a UDSEntry describing the file.
The UDSEntry is generated from the sftp file attributes. */
UDSEntry sftpFileAttr::entry() {
UDSEntry entry;
UDSAtom atom;
atom.m_uds = UDS_NAME;
atom.m_str = mFilename;
entry.append(atom);
if( mFlags & SSH2_FILEXFER_ATTR_SIZE ) {
atom.m_uds = UDS_SIZE;
atom.m_long = mSize;
entry.append(atom);
}
if( mFlags & SSH2_FILEXFER_ATTR_ACMODTIME ) {
atom.m_uds = UDS_ACCESS_TIME;
atom.m_long = mAtime;
entry.append(atom);
atom.m_uds = UDS_MODIFICATION_TIME;
atom.m_long = mMtime;
entry.append(atom);
}
if( mFlags & SSH2_FILEXFER_ATTR_UIDGID ) {
if( mUserName.isEmpty() || mGroupName.isEmpty() )
getUserGroupNames();
atom.m_uds = UDS_USER;
atom.m_str = mUserName;
entry.append(atom);
atom.m_uds = UDS_GROUP;
atom.m_str = mGroupName;
entry.append(atom);
}
if( mFlags & SSH2_FILEXFER_ATTR_PERMISSIONS ) {
atom.m_uds = UDS_ACCESS;
atom.m_long = mPermissions;
entry.append(atom);
mode_t type = fileType();
// Set the type if we know what it is
if( type != 0 ) {
atom.m_uds = UDS_FILE_TYPE;
atom.m_long = (mLinkType ? mLinkType:type);
entry.append(atom);
}
if( S_ISLNK(type) ) {
atom.m_uds = UDS_LINK_DEST;
atom.m_str = mLinkDestination;
entry.append(atom);
}
}
return entry;
}
/** Use to output the file attributes to a sftp packet */
TQDataStream& operator<< (TQDataStream& s, const sftpFileAttr& fa) {
s << (TQ_UINT32)fa.mFlags;
if( fa.mFlags & SSH2_FILEXFER_ATTR_SIZE )
{ s << (TQ_ULLONG)fa.mSize; }
if( fa.mFlags & SSH2_FILEXFER_ATTR_UIDGID )
{ s << (TQ_UINT32)fa.mUid << (TQ_UINT32)fa.mGid; }
if( fa.mFlags & SSH2_FILEXFER_ATTR_PERMISSIONS )
{ s << (TQ_UINT32)fa.mPermissions; }
if( fa.mFlags & SSH2_FILEXFER_ATTR_ACMODTIME )
{ s << (TQ_UINT32)fa.mAtime << (TQ_UINT32)fa.mMtime; }
if( fa.mFlags & SSH2_FILEXFER_ATTR_EXTENDED ) {
s << (TQ_UINT32)fa.mExtendedCount;
// XXX: Write extensions to data stream here
// s.writeBytes(extendedtype).writeBytes(extendeddata);
}
return s;
}
/** Use to read a file attribute from a sftp packet */
TQDataStream& operator>> (TQDataStream& s, sftpFileAttr& fa) {
// XXX Add some error checking in here in case
// we get a bad sftp packet.
fa.clear();
if( fa.mDirAttrs ) {
TQCString fn;
s >> fn;
fn.truncate( fn.size() );
fa.mFilename = fa.mEncoding->decode( fn );
s >> fa.mLongname;
fa.mLongname.truncate( fa.mLongname.size() );
//kdDebug() << ">>: ftpfileattr long filename (" << fa.mLongname.size() << ")= " << fa.mLongname << endl;
}
s >> fa.mFlags; // get flags
if( fa.mFlags & SSH2_FILEXFER_ATTR_SIZE ) {
TQ_ULLONG fileSize;
s >> fileSize;
fa.setFileSize(fileSize);
}
TQ_UINT32 x;
if( fa.mFlags & SSH2_FILEXFER_ATTR_UIDGID ) {
s >> x; fa.setUid(x);
s >> x; fa.setGid(x);
}
if( fa.mFlags & SSH2_FILEXFER_ATTR_PERMISSIONS ) {
s >> x; fa.setPermissions(x);
}
if( fa.mFlags & SSH2_FILEXFER_ATTR_ACMODTIME ) {
s >> x; fa.setAtime(x);
s >> x; fa.setMtime(x);
}
if( fa.mFlags & SSH2_FILEXFER_ATTR_EXTENDED ) {
s >> x; fa.setExtendedCount(x);
// XXX: Read in extensions from data stream here
// s.readBytes(extendedtype).readBytes(extendeddata);
}
fa.getUserGroupNames();
return s;
}
/** Parse longname for the owner and group names. */
void sftpFileAttr::getUserGroupNames(){
// Get the name of the owner and group of the file from longname.
TQString user, group;
if( mLongname.isEmpty() ) {
// do not have the user name so use the user id instead
user.setNum(mUid);
group.setNum(mGid);
}
else {
int field = 0;
int i = 0;
int l = mLongname.length();
TQString longName = mEncoding->decode( mLongname );
kdDebug(7120) << "Decoded: " << longName << endl;
// Find the beginning of the third field which contains the user name.
while( field != 2 ) {
if( longName[i].isSpace() ) {
field++; i++;
while( i < l && longName[i].isSpace() ) { i++; }
}
else { i++; }
}
// i is the index of the first character of the third field.
while( i < l && !longName[i].isSpace() ) {
user.append(longName[i]);
i++;
}
// i is the first character of the space between fields 3 and 4
// user contains the owner's user name
while( i < l && longName[i].isSpace() ) {
i++;
}
// i is the first character of the fourth field
while( i < l && !longName[i].isSpace() ) {
group.append(longName[i]);
i++;
}
// group contains the name of the group.
}
mUserName = user;
mGroupName = group;
}
/** No descriptions */
kdbgstream& operator<< (kdbgstream& s, sftpFileAttr& a) {
s << "Filename: " << a.mFilename
<< ", Uid: " << a.mUid
<< ", Gid: " << a.mGid
<< ", Username: " << a.mUserName
<< ", GroupName: " << a.mGroupName
<< ", Permissions: " << a.mPermissions
<< ", size: " << a.mSize
<< ", atime: " << a.mAtime
<< ", mtime: " << a.mMtime
<< ", extended cnt: " << a.mExtendedCount;
if (S_ISLNK(a.mLinkType)) {
s << ", Link Type: " << a.mLinkType;
s << ", Link Destination: " << a.mLinkDestination;
}
return s;
}
/** Make sure it builds with NDEBUG */
kndbgstream& operator<< (kndbgstream& s, sftpFileAttr& ) {
return s;
}
/** Clear all attributes and flags. */
void sftpFileAttr::clear(){
clearAtime();
clearMtime();
clearGid();
clearUid();
clearFileSize();
clearPermissions();
clearExtensions();
mFilename = TQString::null;
mGroupName = TQString::null;
mUserName = TQString::null;
mLinkDestination = TQString::null;
mFlags = 0;
mLongname = "\0";
mLinkType = 0;
}
/** Return the size of the sftp attribute. */
TQ_UINT32 sftpFileAttr::size() const{
TQ_UINT32 size = 4; // for the attr flag
if( mFlags & SSH2_FILEXFER_ATTR_SIZE )
size += 8;
if( mFlags & SSH2_FILEXFER_ATTR_UIDGID )
size += 8;
if( mFlags & SSH2_FILEXFER_ATTR_PERMISSIONS )
size += 4;
if( mFlags & SSH2_FILEXFER_ATTR_ACMODTIME )
size += 8;
if( mFlags & SSH2_FILEXFER_ATTR_EXTENDED ) {
size += 4;
// add size of extensions
}
return size;
}
/** Returns the file type as determined from the file permissions */
mode_t sftpFileAttr::fileType() const{
mode_t type = 0;
if( S_ISLNK(mPermissions) )
type |= S_IFLNK;
if( S_ISREG(mPermissions) )
type |= S_IFREG;
else if( S_ISDIR(mPermissions) )
type |= S_IFDIR;
else if( S_ISCHR(mPermissions) )
type |= S_IFCHR;
else if( S_ISBLK(mPermissions) )
type |= S_IFBLK;
else if( S_ISFIFO(mPermissions) )
type |= S_IFIFO;
else if( S_ISSOCK(mPermissions) )
type |= S_IFSOCK;
return type;
}
void sftpFileAttr::setEncoding( KRemoteEncoding* encoding )
{
mEncoding = encoding;
}

@ -1,261 +0,0 @@
/***************************************************************************
sftpfileattr.h - description
-------------------
begin : Sat Jun 30 2001
copyright : (C) 2001 by Lucas Fisher
email : ljfisher@iastate.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. *
* *
***************************************************************************/
#ifndef SFTPFILEATTR_H
#define SFTPFILEATTR_H
#include <sys/types.h>
#include <tqglobal.h>
#include <tqstring.h>
#include <tqdatastream.h>
#include <tdeio/global.h>
#include <kdebug.h>
#include "sftp.h"
/**
*@author Lucas Fisher
*/
class KRemoteEncoding;
class sftpFileAttr {
private: // Private attributes
/** Name of file. */
TQString mFilename;
/** Specifies which fields of the file attribute are available. */
TQ_UINT32 mFlags;
/** Size of the file in bytes. Should be 64 bit safe. */
TQ_ULLONG mSize;
/** User id of the owner of the file. */
uid_t mUid;
/** Group id of the group to which the file belongs. */
gid_t mGid;
/** POSIX permissions of the file. */
mode_t mPermissions;
/** Last access time of the file in seconds from Jan 1, 1970. */
time_t mAtime;
/** Last modification time of file in seconds since Jan. 1, 1970. */
time_t mMtime;
/** Number of file attribute extensions.
Not currently implemented */
TQ_UINT32 mExtendedCount;
/** Longname of the file as found in a SSH_FXP_NAME sftp packet.
These contents are parse to return the file's owner name and
gr oup name. */
TQCString mLongname;
TQString mUserName;
TQString mGroupName;
/** If file is a link, contains the destination of the link */
TQString mLinkDestination;
/** If resource is a link, contains the type the link,e.g. file,dir... */
mode_t mLinkType;
/** Whether >> operator should read filename and longname from the stream. */
bool mDirAttrs;
/** Holds the encoding of the remote host */
KRemoteEncoding* mEncoding;
public:
sftpFileAttr();
sftpFileAttr(KRemoteEncoding* encoding);
~sftpFileAttr();
/** Constructor to initialize the file attributes on declaration. */
sftpFileAttr(TQ_ULLONG size_, uid_t uid_, gid_t gid_, mode_t permissions_,
time_t atime_, time_t mtime_, TQ_UINT32 extendedCount_ = 0);
/** Return the size of the sftp attribute not including filename or longname*/
TQ_UINT32 size() const;
/** Clear all attributes and flags. */
void clear();
/** Set the size of the file. */
void setFileSize(TQ_ULLONG s)
{ mSize = s; mFlags |= SSH2_FILEXFER_ATTR_SIZE; }
/** The size file attribute will not be included in the UDSEntry
or when the file attribute is written to the sftp packet. */
void clearFileSize()
{ mSize = 0; mFlags &= ~SSH2_FILEXFER_ATTR_SIZE; }
/** Returns the size of the file. */
TQ_ULLONG fileSize() const { return mSize; }
/** Sets the POSIX permissions of the file. */
void setPermissions(mode_t p)
{ mPermissions = p; mFlags |= SSH2_FILEXFER_ATTR_PERMISSIONS; }
/** The permissions file attribute will not be included in the UDSEntry
or when the file attribute is written to the sftp packet. */
void clearPermissions()
{ mPermissions = 0; mFlags &= ~SSH2_FILEXFER_ATTR_PERMISSIONS; }
/** Returns the POSIX permissons of the file. */
mode_t permissions() const { return mPermissions; }
/** Sets the group id of the file. */
void setGid(gid_t id)
{ mGid = id; mFlags |= SSH2_FILEXFER_ATTR_UIDGID; }
/** Neither the gid or uid file attributes will not be included in the UDSEntry
or when the file attribute is written to the sftp packet. This is
equivalent to clearUid() */
void clearGid()
{ mGid = 0; mFlags &= SSH2_FILEXFER_ATTR_UIDGID; }
/** Returns the group id of the file. */
gid_t gid() const { return mGid; }
/** Sets the uid of the file. */
void setUid(uid_t id)
{ mUid = id; mFlags |= SSH2_FILEXFER_ATTR_UIDGID; }
/** Neither the gid or uid file attributes will not be included in the UDSEntry
or when the file attribute is written to the sftp packet. This is
equivalent to clearGid() */
void clearUid()
{ mUid = 0; mFlags &= SSH2_FILEXFER_ATTR_UIDGID; }
/** Returns the user id of the file. */
gid_t uid() const { return mUid; }
/** Set the modificatoin time of the file in seconds since Jan. 1, 1970. */
void setMtime(time_t t)
{ mMtime = t; mFlags |= SSH2_FILEXFER_ATTR_ACMODTIME; }
/** Neither the mtime or atime file attributes will not be included in the UDSEntry
or when the file attribute is written to the sftp packet. This is
equivalent to clearAtime() */
void clearMtime()
{ mMtime = 0; mFlags &= SSH2_FILEXFER_ATTR_ACMODTIME; }
/** Returns the modification time of the file in seconds since Jan. 1, 1970. */
time_t mtime() const { return mMtime; }
/** Sets the access time of the file in seconds since Jan. 1, 1970. */
void setAtime(time_t t)
{ mAtime = t; mFlags |= SSH2_FILEXFER_ATTR_ACMODTIME; }
/** Neither the atime or mtime file attributes will not be included in the UDSEntry
or when the file attribute is written to the sftp packet. This is
equivalent to clearMtime() */
void clearAtime()
{ mAtime = 0; mFlags &= SSH2_FILEXFER_ATTR_ACMODTIME; }
/** Returns the last access time of the file in seconds since Jan. 1, 1970. */
time_t atime() const { return mAtime; }
/** Sets the number of file attribute extensions. */
void setExtendedCount(unsigned int c)
{ mExtendedCount = c; mFlags |= SSH2_FILEXFER_ATTR_EXTENDED; }
/** No extensions will be included when the file attribute is written
to a sftp packet. */
void clearExtensions()
{ mExtendedCount = 0; mFlags &= ~SSH2_FILEXFER_ATTR_EXTENDED; }
/** Returns the number of file attribute extentsions. */
unsigned int extendedCount() const { return mExtendedCount; }
/** Returns the flags for the sftp file attributes. */
unsigned int flags() const { return mFlags; }
/** Sets file's longname. See sftpFileAttr::longname. */
void setLongname(TQString l) { mLongname = l.latin1(); }
/** Returns a string describing the file attributes. The format is specific
to the implementation of the sftp server. In most cases (ie OpenSSH)
this is similar to the long output of 'ls'. */
TQString longname() const { return mLongname; }
void setLinkDestination(const TQString& target)
{ mLinkDestination = target; }
TQString linkDestination()
{ return mLinkDestination; }
/** Sets the actual type a symbolic link points to. */
void setLinkType (mode_t type) { mLinkType = type; }
mode_t linkType() const { return mLinkType; }
/** No descriptions */
void setFilename(const TQString& fn)
{ mFilename = fn; }
TQString filename() const
{ return mFilename; }
/** Returns a UDSEntry describing the file.
The UDSEntry is generated from the sftp file attributes. */
TDEIO::UDSEntry entry();
/** Use to output the file attributes to a sftp packet
This will only write the sftp ATTR structure to the stream.
It will never write the filename and longname because the client
never sends those to the server. */
friend TQDataStream& operator<< (TQDataStream&, const sftpFileAttr&);
/** Use to read a file attribute from a sftp packet.
Read this carefully! If the DirAttrs flag is true, this will
read the filename, longname, and file attributes from the stream.
This is for use with listing directories.
If the DirAttrs flag is false, this will only read file attributes
from the stream.
BY DEFAULT, A NEW INSTANCE HAS DirAttrs == false */
friend TQDataStream& operator>> (TQDataStream&, sftpFileAttr&);
/** Parse longname for the owner and group names. */
void getUserGroupNames();
/** Sets the DirAttrs flag. This flag affects how the >> operator works on data streams. */
void setDirAttrsFlag(bool flag){ mDirAttrs = flag; }
/** Gets the DirAttrs flag. */
bool getDirAttrsFlag() const { return mDirAttrs; }
friend kdbgstream& operator<< (kdbgstream& s, sftpFileAttr& a);
friend kndbgstream& operator<< (kndbgstream& s, sftpFileAttr& a);
/** Returns the file type as determined from the file permissions */
mode_t fileType() const;
/** Set the encoding of the remote file system */
void setEncoding( KRemoteEncoding* encoding );
};
#endif

File diff suppressed because it is too large Load Diff

@ -1,37 +1,49 @@
/***************************************************************************
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 "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
namespace TDEIO {
class AuthInfo;
}
class sftpProtocol : public TDEIO::SlaveBase
{
@ -39,23 +51,35 @@ 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);
private: // Private variables
void statMime(const KURL &url);
void closeFile();
/** True if ioslave is connected to sftp server. */
bool mConnected;
@ -65,8 +89,11 @@ 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;
/** The sftp session for the connection */
sftp_session mSftp;
/** Username to use when connecting */
TQString mUsername;
@ -74,76 +101,34 @@ private: // Private variables
/** User's password */
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;
//};
private: // private methods
bool getPacket(TQByteArray& msg);
/* 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);
int authenticateKeyboardInteractive(TDEIO::AuthInfo &info);
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);
};
#endif

Loading…
Cancel
Save