mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-07-02 03:52:49 -05:00
Provide Uppity with a built-in old-style scp server.
Like the SFTP server, this is implemented in-process rather than by invoking a separate scp server binary. It also uses the internal SftpServer abstraction for access to the server's filesystem, which means that when (or if) I implement an alternative SftpServer implementing a dummy file system for test suite purposes, this scp server should automatically start using it too. As a bonus, the new scpserver.c contains a large comment documenting my understanding of the SCP protocol, which I previously didn't have even a de-facto or post-hoc spec for. I don't claim it's authoritative - it's all reverse-engineered from my own code and observing other implementations in action - but at least it'll make it easier to refresh my own memory of what's going on the next time I need to do something to either this code or PSCP.
This commit is contained in:
40
sftp.h
40
sftp.h
@ -56,6 +56,8 @@
|
||||
|
||||
#define SFTP_PROTO_VERSION 3
|
||||
|
||||
#define PERMS_DIRECTORY 040000
|
||||
|
||||
/*
|
||||
* External references. The sftp client module sftp.c expects to be
|
||||
* able to get at these functions.
|
||||
@ -477,3 +479,41 @@ struct DefaultSftpReplyBuilder {
|
||||
*/
|
||||
struct sftp_packet *sftp_handle_request(
|
||||
SftpServer *srv, struct sftp_packet *request);
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Not exactly SFTP-related, but here's a system that implements an
|
||||
* old-fashioned SCP server module, given an SftpServer vtable to use
|
||||
* as its underlying filesystem access.
|
||||
*/
|
||||
|
||||
typedef struct ScpServer ScpServer;
|
||||
typedef struct ScpServerVtable ScpServerVtable;
|
||||
struct ScpServer {
|
||||
const struct ScpServerVtable *vt;
|
||||
};
|
||||
struct ScpServerVtable {
|
||||
void (*free)(ScpServer *s);
|
||||
|
||||
int (*send)(ScpServer *s, const void *data, size_t length);
|
||||
void (*throttle)(ScpServer *s, int throttled);
|
||||
void (*eof)(ScpServer *s);
|
||||
};
|
||||
|
||||
#define scp_free(s) ((s)->vt->free(s))
|
||||
#define scp_send(s, data, len) ((s)->vt->send(s, data, len))
|
||||
#define scp_throttle(s, th) ((s)->vt->throttle(s, th))
|
||||
#define scp_eof(s) ((s)->vt->eof(s))
|
||||
|
||||
/*
|
||||
* Create an ScpServer by calling this function, giving it the command
|
||||
* you received from the SSH client to execute. If that command is
|
||||
* recognised as an scp command, it will construct an ScpServer object
|
||||
* and return it; otherwise, it will return NULL, and you should
|
||||
* execute the command in whatever way you normally would.
|
||||
*
|
||||
* The ScpServer will generate output for the client by writing it to
|
||||
* the provided SshChannel using sshfwd_write; you pass it input using
|
||||
* the send method in its own vtable.
|
||||
*/
|
||||
ScpServer *scp_recognise_exec(
|
||||
SshChannel *sc, const SftpServerVtable *sftpserver_vt, ptrlen command);
|
||||
|
Reference in New Issue
Block a user