📄 ftpserver.pl
字号:
"226 File transfer complete\r\n"; logmsg "150+226 in one shot!\n"; for(@data) { my $send = $_; print SOCK $send; } close(SOCK); $retrweirdo=0; # switch off the weirdo again! } else { my $sz = "($size bytes)"; if($retrnosize) { $sz = "size?"; } print "150 Binary data connection for $testno () $sz.\r\n"; logmsg "150 Binary data connection for $testno () $sz.\n"; for(@data) { my $send = $_; print SOCK $send; } close(SOCK); print "226 File transfer complete\r\n"; } } else { print "550 $testno: No such file or directory.\r\n"; logmsg "550 $testno: no such file\n"; } return 0;}sub STOR_command { my $testno=$_[0]; my $filename = "log/upload.$testno"; logmsg "STOR test number $testno in $filename\n"; print "125 Gimme gimme gimme!\r\n"; open(FILE, ">$filename") || return 0; # failed to open output my $line; my $ulsize=0; while (defined($line = <SOCK>)) { $ulsize += length($line); print FILE $line; } close(FILE); close(SOCK); logmsg "received $ulsize bytes upload\n"; print "226 File transfer complete\r\n"; return 0;}my $pasvport=9000;sub PASV_command { my ($arg, $cmd)=@_; socket(Server2, PF_INET, SOCK_STREAM, $proto) || die "socket: $!"; setsockopt(Server2, SOL_SOCKET, SO_REUSEADDR, pack("l", 1)) || die "setsockopt: $!"; my $ok=0; $pasvport++; # don't reuse the previous for(1 .. 10) { if($pasvport > 65535) { $pasvport = 1025; } if(bind(Server2, sockaddr_in($pasvport, INADDR_ANY))) { $ok=1; last; } $pasvport+= 3; # try another port please } if(!$ok) { print "500 no free ports!\r\n"; logmsg "couldn't find free port\n"; return 0; } listen(Server2,SOMAXCONN) || die "listen: $!"; if($cmd ne "EPSV") { # PASV reply logmsg "replying to a $cmd command\n"; printf("227 Entering Passive Mode (127,0,0,1,%d,%d)\n", ($pasvport/256), ($pasvport%256)); } else { # EPSV reply logmsg "replying to a $cmd command\n"; printf("229 Entering Passive Mode (|||%d|)\n", $pasvport); } my $paddr = accept(SOCK, Server2); my($iport,$iaddr) = sockaddr_in($paddr); my $name = gethostbyaddr($iaddr,AF_INET); close(Server2); # close the listener when its served its purpose! logmsg "$$: data connection from $name [", inet_ntoa($iaddr), "] at port $iport\n"; return;}sub PORT_command { my $arg = $_[0]; if($arg !~ /(\d+),(\d+),(\d+),(\d+),(\d+),(\d+)/) { logmsg "bad PORT-line: $arg\n"; print "500 silly you, go away\r\n"; return 0; } my $iaddr = inet_aton("$1.$2.$3.$4"); my $port = ($5<<8)+$6; if(!$port || $port > 65535) { print STDERR "very illegal PORT number: $port\n"; return 1; } my $paddr = sockaddr_in($port, $iaddr); my $proto = getprotobyname('tcp') || 6; socket(SOCK, PF_INET, SOCK_STREAM, $proto) || die "major failure"; connect(SOCK, $paddr) || return 1; return \&SOCK;}$SIG{CHLD} = \&REAPER;my %customreply;my %customcount;my %delayreply;sub customize { undef %customreply; open(CUSTOM, "<log/ftpserver.cmd") || return 1; logmsg "FTPD: Getting commands from log/ftpserver.cmd\n"; while(<CUSTOM>) { if($_ =~ /REPLY ([A-Z]+) (.*)/) { $customreply{$1}=$2; } if($_ =~ /COUNT ([A-Z]+) (.*)/) { # we blank the customreply for this command when having # been used this number of times $customcount{$1}=$2; } elsif($_ =~ /DELAY ([A-Z]+) (\d*)/) { $delayreply{$1}=$2; } elsif($_ =~ /RETRWEIRDO/) { print "instructed to use RETRWEIRDO\n"; $retrweirdo=1; } elsif($_ =~ /RETRNOSIZE/) { print "instructed to use RETRNOSIZE\n"; $retrnosize=1; } } close(CUSTOM);}my @welcome=( '220- _ _ ____ _ '."\r\n", '220- ___| | | | _ \| | '."\r\n", '220- / __| | | | |_) | | '."\r\n", '220- | (__| |_| | _ <| |___ '."\r\n", '220 \___|\___/|_| \_\_____|'."\r\n");for ( $waitedpid = 0; ($paddr = accept(Client,Server)) || $waitedpid; $waitedpid = 0, close Client){ next if $waitedpid and not $paddr; my($port,$iaddr) = sockaddr_in($paddr); my $name = gethostbyaddr($iaddr,AF_INET); # flush data: $| = 1; logmsg "connection from $name [", inet_ntoa($iaddr), "] at port $port\n"; open(STDIN, "<&Client") || die "can't dup client to stdin"; open(STDOUT, ">&Client") || die "can't dup client to stdout"; FTPLOG->autoflush(1); &customize(); # read test control instructions print @welcome; if($verbose) { for(@welcome) { print STDERR "OUT: $_"; } } my $state="fresh"; while(1) { last unless defined ($_ = <STDIN>); ftpmsg $_; # Remove trailing CRLF. s/[\n\r]+$//; unless (m/^([A-Z]{3,4})\s?(.*)/i) { print "500 '$_': command not understood.\r\n"; logmsg "unknown crap received, bailing out hard\n"; last; } my $FTPCMD=$1; my $FTPARG=$2; my $full=$_; logmsg "GOT: ($1) $_\n"; if($verbose) { print STDERR "IN: $full\n"; } my $ok = $commandok{$FTPCMD}; if($ok !~ /$state/) { print "500 $FTPCMD not OK in state: $state!\r\n"; next; } my $newstate=$statechange{$FTPCMD}; if($newstate eq "") { # remain in the same state } else { $state = $newstate; } my $delay = $delayreply{$FTPCMD}; if($delay) { # just go sleep this many seconds! sleep($delay); } my $text; $text = $customreply{$FTPCMD}; my $fake = $text; if($text eq "") { $text = $displaytext{$FTPCMD}; } else { if($customcount{$FTPCMD} && (!--$customcount{$FTPCMD})) { # used enough number of times, now blank the customreply $customreply{$FTPCMD}=""; } logmsg "$FTPCMD made to send '$text'\n"; } if($text) { print "$text\r\n"; } if($fake eq "") { # only perform this if we're not faking a reply # see if the new state is a function caller. my $func = $commandfunc{$FTPCMD}; if($func) { # it is! \&$func($FTPARG, $FTPCMD); } } logmsg "set to state $state\n"; } # while(1) close(Client); close(Client2);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -