📄 sftpd.h
字号:
// sftpd.h// declarations for sftpd.cc// copyright SafeTP Development Group, Inc., 2000 Terms of use are as specified in license.txt#ifndef __SFTPD_H#define __SFTPD_H#include <stdio.h> // FILE#include "sockutil.h" // SOCKET, PortRange#include "sftp.h" // common declarations#include "socksrc.h" // SocketInputSource#include "digt.h" // DigestComputer#include "datablok.h" // DataBlock#include "warn.h" // WarnLevelclass SecurityProvider;// an SFTPD session object, responsible for the relay logic, including// intercepting and redirecting PORT commands, etc.class SFTPD {private: // types // states for me, sftpd enum State { // no encryption STATE_UNCONNECTED, // no connection (probably unused) STATE_UNAUTHENTICATED, // we have connections, and have relayed 220 STATE_ADAT, // exchanging security data // encrypted data channel STATE_AUTHENTICATED, // we have successfully negotiated a security mechanism STATE_GOT_PBSZ, // saw PBSZ // no encryption STATE_959_INTEROP, // interoperating with RFC 959 (insecure) client }; // some constants enum Constants { MIN_BUFFER_SIZE = 1, // minimum allowed PBSZ MAX_BUFFER_SIZE = 128*1024, // maximum allowed PBSZ NONPASV_PORT = 0, // code to mean we're not in PASV mode }; // helper class class RandomSeedSaver { SFTPD *sftpd; public: RandomSeedSaver(SFTPD *s) : sftpd(s) {} ~RandomSeedSaver(); }; friend class RandomSeedSaver; // so it can call writeToLogprivate: // data // ------ socket state ------ // control connection to the client bool useStdinStream; // true if client_control is stdin SOCKET client_control; // send, select SocketLineReader *clientControlStream; // recv // control connection to the server SOCKET server_control; // send, select SocketLineReader *serverControlStream; // recv // data connections SOCKET client_data; SOCKET server_data; // listen sockets, for when we're waiting for either client or server // to connect to us (for a data channel transmission) SOCKET client_listen; SOCKET server_listen; // ------ protocol state ------ // tracks monotonic progression of 2228 security negotiation commands State state; // destination for next data-channel connect-to-client IPAddress relayClientAddress; int relayClientPort; // port where ftpd is PASV-ly awaiting a connect // (value is NONPASV_PORT when we're not in PASV mode) int serverPassivePort; // DIGT implementation DigestComputer digt; // running SHA of certain requests and replies // ------ data channel state ------ // data channel encryption buffer DataBlock dataBuffer; // data itself unsigned long maxBlockSize; // max size of encrypted block unsigned long maxCleartextBlockSize; // max size of data to en/decrypt // data channel options bool forceDataRelay; // relay data even if data encryption is off DataSecurityLevel dataSecLevel; // level of protection applied to data channel // ------ configuration options ------ // policy options bool allowRfc959; // permit 959 dropdown bool allowRfc959_anon; // permit 959 dropdown for anonymous bool allowNonReflexivePorts; // permit PORT addr != client_control addr bool allowReservedPorts; // permit PORT port < 1024 bool allowCleartext; // true if we let user specify X-Cleartext{2,} bool requireDataEncryption; // require all data channel traffic to be encrypted // -i: option to supply a different IP address in protocol stream // than the IP address assinged to the network interface (for use // when the server is behind a firewall) bool useFakeIPAddress; // if true, use fake ip address IPAddress fakeIPAddress; // fake ip address to use // optionally restrict the range of local data ports bound; // one range is for PASV and another for active PORT transfers PortRange pasvRange; PortRange activeRange; // kerberos interoperability string kerberosFtpdBinary; // where to find Kerberos' ftpd binary (length is 0 // if we're not permitting GSSAPI) // see possiblyDoAnonExecDropdown() bool anonExecDropdown; // true if this is enabled string anonFtpdBinary; // name of ftpd to exec(2) for anon dropdown // debugging options bool printAdats; // print ADAT exchage to console bool printDataChannel; // print all data channel traffic to stdout int artificialDelay; // if nonzero, sleep() this many seconds between data blocks // logging configuration enum LogLevel { LL_LOG = 0x01, // ongoing security monitoring LL_DIAGNOSTIC = 0x02, // debugging LL_SOCKET_DIAG = 0x04, // detailed socket info LL_NO_LF = 0x80, // don't append a linefeed to the logged message }; LogLevel logLevelMask; // things to actually print bool stdoutLogAnyway; // don't use syslog even if looks like we should // list of kinds of events we might be interested in logging enum LoggableEvent { LE_ERROR = 0x01, // exceptions, usage errors, etc. LE_WARNING = 0x02, // things that suggest there is a problem LE_CONTROL_CHANNEL = 0x04, // control channel socket open and close LE_HANDOFF = 0x08, // events related to handoff or dropdown LE_DEBUG = 0x10, // debugging messages, if enabled in the logLevelMask LE_USER = 0x20, // log USER commands with usernames LE_PRINT_TIMESTAMP = 0x80, // not an event; is whether timestamps are printed // things enabled by default LE_DEFAULTS = LE_ERROR | LE_WARNING | LE_CONTROL_CHANNEL | LE_HANDOFF | LE_DEBUG | LE_USER | LE_PRINT_TIMESTAMP }; LoggableEvent logEventMask; // which events to log // log output file, when syslog is not used FILE *logFile; // ------ helper object pointers ------ // security provider; responsible for encrypting and decrypting data SecurityProvider *security; // for access by warnHandler, which is a static fn static SFTPD *instance;private: // funcs // see code for comments about purpose, usage void handleOriginalRequest(Request const &req); void handleDecryptedRequest(Request const &req); void encryptedClientReply(Reply const &reply); void unencryptedClientReply(Reply const &reply); bool failsRequireEncTest(); // automatically determine whether to encrypt the reply or not void clientReply(Reply const &reply); void clientReply(ReplyCode code, char const *msg); void composeAdatReply(bool justAuthed); void handleReply(Reply const &reply); void unexpected(xBase &x); void closeConnections(); void closeDataSockets(); void closeIf(SOCKET &s); void closeSocket(SOCKET &s); // close and set to INVALID_SOCKET Reply serverRequestAndGetReply(Request const &req); bool getClientPort(char const *values); IPAddress getMyIPAsClientSeesIt() const; void decryptDataBlock(); void encryptDataBlock(); void doArtificialDelay(); // true if control channel is currently encrypted bool controlChannelEncrypted() const; // true if data channel is currently subject to security // transformations that provide e.g. integrity or confidentiality bool dataChannelProtected() const; // true if we (and ftpd) are in PASV mode bool pasvMode() const; // true while we are exchanging AUTH/ADATs bool amAuthenticating() const; // true if we must do data relay bool doingDataRelay() const; // write some information to an administrator-accessible log // (a newline will be added after 'msg') void writeToLog(LogLevel level, LoggableEvent event, char const *msg); // 'warn' module handler static void warnHandler(WarnLevel level, char const *message); // write socket info to 'log()' (local and remote addr/ports) void logSocketInfo(LoggableEvent event, SOCKET s); // bind a socket and tell ftpd about it, via a PORT command void listenServerDataPort(); // given a recent attempt to connect by one peer, turn around // and connect to the other bool relayDataConnection( SOCKET &peerA_listen, SOCKET &peerA_data, IPAddress addrB, int portB, SOCKET &peerB_data, PortRange const *range); // copy data from one socket to another, until no more is waiting void relaySocketData(SOCKET &dest, SOCKET &src); // these call addEntropy after the network activity, to get // the entropy in the latency void send(Request const &req, SOCKET s); void send(Reply const &reply, SOCKET s); // handle the PASV command void handlePassiveMode(); // called by run, wrapped in a try-catch void innerRun(int argc, char *argv[]); // request/reply handlers; they may close the control sockets // (which doesn't necessarily mean we should exit!) void handleClientRequest(); void handleServerReply(); // relay a port command, first substituting my port for the client's void portCommandRelay(Request const &request); // relay a port command without intervention, but if an error occurs, // switch to indirect mode void portCommandStraightRelay(Request const &request); // choose which of the above to do void handlePortCommand(Request const &request); // anon exec dropdown void possiblyDoAnonExecDropdown(SOCKET whereToSendGreeting); bool checkLoginName(char const *name); static bool isAnonLogin(char const *name);public: // funcs // variable initialization SFTPD(); // cleanup ~SFTPD(); // main loop, returns when the session is closed void run(int argc, char *argv[]);};#endif // __SFTPD_H
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -