]> git.saurik.com Git - apple/security.git/blob - Network/ftp-protocol.h
Security-28.tar.gz
[apple/security.git] / Network / ftp-protocol.h
1 /*
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
3 *
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
8 * using this file.
9 *
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
16 */
17
18
19 //
20 // ftp-protocol - FTP protocol objects
21 //
22 #ifndef _H_FTP_PROTOCOL
23 #define _H_FTP_PROTOCOL
24
25 #include "xfercore.h"
26 #include "protocol.h"
27 #include "transfer.h"
28 #include "netconnection.h"
29 #include "neterror.h"
30 #include <Security/ip++.h>
31 #include <Security/inetreply.h>
32
33
34 namespace Security {
35 namespace Network {
36
37
38 //
39 // The Protocol object for the FTP protocol
40 //
41 class FTPProtocol : public Protocol {
42 class FTPTransfer;
43 class FTPConnection;
44 public:
45 static const IPPort defaultFtpPort = 21;
46
47 FTPProtocol(Manager &mgr);
48
49 public:
50 FTPTransfer *makeTransfer(const Target &target, Operation operation);
51
52 public:
53 // FTP-specific operation codes
54 enum {
55 downloadDirectory = protocolSpecific, // get filename list (NLST)
56 downloadListing, // get host-specific listing (LIST)
57 makeDirectory, // make a directory (MKD)
58 removeDirectory, // remove a directory (RMD)
59 genericCommand // issue generic FTP command
60 };
61
62 private:
63 //
64 // The data connection object manages a data pipe (for one upload/download)
65 //
66 class FTPDataConnection : public TransferEngine::Client, public TCPClientSocket {
67 public:
68 FTPDataConnection(FTPConnection &conn) : connection(conn) { }
69
70 FTPConnection &connection; // the main Connection we belong to
71
72 void start(Sink &sink); // start download
73 void start(Source &source); // start upload
74 void close(); // unconditional close
75 void connectionDone(); // Connection is done
76
77 OSStatus status() const { return mFailureStatus; }
78
79 int fileDesc() const;
80
81 protected:
82 void transit(Event event, char *input, size_t inputLength);
83 void transitError(const CssmCommonError &error);
84 void setup();
85 void finish();
86
87 private:
88 OSStatus mFailureStatus; // noErr unless something went wrong
89 bool mTransferDone; // our transfer is all done
90 bool mConnectionDone; // our Connection is ready to finish()
91 };
92
93 //
94 // This is the persistent connection object.
95 //
96 class FTPConnection : public TCPConnection {
97 friend class FTPDataConnection;
98 public:
99 FTPConnection(Protocol &proto, const HostTarget &tgt);
100
101 // state machine master state
102 enum State {
103 errorState, // invalid state marker (reset or fail)
104
105 // login sub-engine
106 loginInitial, // just connected [want hello or need-login]
107 loginUserSent, // USER command sent [want hello or need-pass]
108 loginPassSent, // PASS command sent [want dispatch command]
109
110 // idle state
111 idle, // at command prompt, idle [nothing pending]
112
113 // data transfer states
114 typeCommandSent, // sent TYPE command [want ok]
115 passiveSent, // sent PASV [want contact address]
116 portSent, // sent PORT [want port ok]
117 restartSent, // sent REST [want 350 Restarting...]
118 transferSent, // sent RETR et al [want transfer starting]
119 transferInProgress, // download in progress [want transfer complete]
120
121 // misc. states
122 directCommandSent, // sent non-transfer command, want success
123
124 START = loginInitial
125 };
126
127 FTPTransfer &transfer() { return transferAs<FTPTransfer>(); }
128
129 void request(const char *path);
130 void abort();
131
132 protected:
133 void transit(Event event, char *input, size_t inputLength);
134 void transitError(const CssmCommonError &error);
135 bool validate();
136
137 void startCommand(); // initiate mOperation, if any
138 void startTransfer(bool restarted = false);
139
140 bool imageMode() const { return mImageMode; }
141 void imageMode(bool mode);
142
143 void fail(const char *reply, OSStatus error = Transfer::defaultOSStatusError)
144 { setError(reply, error); Error::throwMe(error); }
145 void fail() { retain(false); Connection::fail(); }
146
147 protected:
148 State state; // state engine state
149 InetReply::Continuation replyContinuation; // cotinued-reply marker
150
151 // state describing the ongoing connection
152 bool mImageMode; // in image (vs. ascii) mode
153 bool mPassive; // current transfer is in passive mode
154
155 string mOperationPath; // remote path for operation
156
157 FTPDataConnection mDataPath; // subsidiary (data transfer) connection
158 TCPServerSocket mReceiver; // incoming listen socket for active mode transfers
159 };
160
161 //
162 // The official Transfer object (for all kinds of transfers)
163 //
164 class FTPTransfer : public Transfer {
165 public:
166 FTPTransfer(Protocol &proto, const Target &target, Operation operation);
167
168 ResultClass resultClass() const;
169
170 protected:
171 void start(); // start me up
172 void abort(); // abort this Transfer
173
174 string mFailedReply; // reply string that triggered failure
175 };
176
177 private:
178 struct FTPAddress {
179 unsigned int h1, h2, h3, h4, p1, p2;
180
181 FTPAddress() { }
182 FTPAddress(const IPSockAddress &addr);
183 operator IPSockAddress () const;
184 };
185 };
186
187
188 } // end namespace Network
189 } // end namespace Security
190
191
192 #endif //_H_FTP_PROTOCOL