2004-05-17
2004-05-17 13:16:09 by Martin Nilsson <mani@lysator.liu.se>
-
1fded7101828eeb010c5b29e4ee5c46c7c6f6e35
(74 lines)
(+68/-6)
[
Show
| Annotate
]
Branch: Aphoto_2.0_beta3
FTPS. [2.89]
Rev: server/plugins/protocols/ftp.pike:2.91
4:
/*
* FTP protocol mk 2
*
- * $Id: ftp.pike,v 2.90 2004/05/17 13:15:07 mani Exp $
+ * $Id: ftp.pike,v 2.91 2004/05/17 13:16:09 mani Exp $
*
* Henrik Grubbström <grubba@roxen.com>
*/
33:
* RFC 775 DIRECTORY ORIENTED FTP COMMANDS
* RFC 949 FTP unique-named store command
* RFC 1639 FTP Operation Over Big Address Records (FOOBAR)
+ * RFC 2228 FTP Security Extensions
* RFC 2428 FTP Extensions for IPv6 and NATs
*
* IETF draft 12 Extended Directory Listing, TVFS,
1358:
"EPRT":"<sp> <d>net-prt<d>net-addr<d>tcp-port<d> (Extended Address Port)",
"EPSV":"[<sp> net-prt|ALL] (Extended Address Passive Mode)",
+ // These are from RFC 2228 (FTP Security Extensions)
+ "AUTH":"security-mechanism (Authentication/Security Mechanism)",
+ "ADAT":"security-data (Authentication/Security Data)",
+ "PBSZ":"<sp> size (Protection Buffer SiZe)",
+ "PROT":"<sp> [ C | S | E | P ] (Data Channel Protection Level)",
+ "CCC":"(Clear Command Channel)",
+ "MIC":"command (Integrity Protected Command)",
+ "CONF":"command (Confidentiality Protected Command)",
+ "ENC":"command (Privacy Protected Command)",
+
// These are in RFC 1639
"LPRT":"<sp> <long-host-port> (Long Port)",
"LPSV":"(Long Passive)",
1624:
void pasv_accept_callback(mixed id)
{
+ DWRITE("FTP: pasv_accept_callback(%O)...\n", id);
touch_me();
if(pasv_port) {
1639: Inside #if defined(FD_DEBUG)
mark_fd(fd->query_fd(),
"ftp communication: -> "+remote[0]+":"+remote[1]);
#endif
+ if (use_ssl) {
+ fd = SSL.sslfile(fd, port_obj->ctx);
+ DWRITE("FTP: Created an sslfile: %O\n", fd);
+ }
if(pasv_callback) {
pasv_callback(fd, "", @pasv_args);
pasv_callback = 0;
1711:
}
privs = 0;
+ Stdio.File raw_connection = f;
+
+ if (use_ssl) {
+ f = (object)SSL.sslfile(f, port_obj->ctx, 1, 0);
+ }
+
f->set_nonblocking(lambda(mixed ignored, string data) {
DWRITE("FTP: async_connect ok. Got data.\n");
f->set_nonblocking(0,0,0);
1728:
});
#ifdef FD_DEBUG
- mark_fd(f->query_fd(), sprintf("ftp communication: %s:%d -> %s:%d",
+ mark_fd(raw_connection->query_fd(),
+ sprintf("ftp communication: %s:%d -> %s:%d",
local_addr, local_port - 1,
dataport_addr, dataport_port));
#endif
- if(catch(f->connect(dataport_addr, dataport_port))) {
+ if(catch(raw_connection->connect(dataport_addr, dataport_port))) {
DWRITE("FTP: Illegal internet address in connect in async comm.\n");
destruct(f);
fun(0, 0, @args);
1751:
if(fd)
{
+ //DWRITE("FTP: fd: %O: %O\n", fd, mkmapping(indices(fd), values(fd)));
if (fd->set_blocking) {
fd->set_blocking(); // Force close() to flush any buffers.
}
- BACKEND_CLOSE(fd);
+ call_out(fd->close, 0);
+ fd = 0;
+ //BACKEND_CLOSE(fd);
}
curr_pipe = 0;
2581:
// Set to 1 by EPSV ALL.
int epsv_only;
+ // Set to 1 by PROT S,E and P, cleared by PROT C.
+ int use_ssl;
void ftp_REIN(string|int args)
{
2872:
ftp_QUIT(args);
}
+ void ftp_PBSZ(string args)
+ {
+ if (!expect_argument("PROT", args)) return;
+
+ send(200, ({ "PBSZ=0" }));
+ }
+
+ void ftp_PROT(string args)
+ {
+ if (!expect_argument("PROT", args)) return;
+
+ args = upper_case(replace(args, ({ " ", "\t" }), ({ "", "" })));
+ switch(args) {
+ case "C": // Clear.
+ use_ssl = 0;
+ break;
+ case "S": // Safe.
+ case "E": // Confidential.
+ case "P": // Private.
+ if (!port_obj->ctx) {
+ send(536, ({ sprintf("Only supported over FTPS") }));
+ return;
+ }
+ use_ssl = 1;
+ break;
+ default:
+ send(504, ({ sprintf("Unknown protection level: %s", args) }));
+ return;
+ }
+ send(200, ({ "OK" }));
+ }
+
void ftp_PORT(string args)
{
if (epsv_only) {
3002:
}
if (pasv_port)
destruct(pasv_port);
+
pasv_port = Stdio.Port(0, pasv_accept_callback, local_addr);
/* FIXME: Hmm, getting the address from an anonymous port seems not
* to work on NT...