From 1ca6ed7b75cad03ca47fc28453e0f28123579e05 Mon Sep 17 00:00:00 2001 From: Steve Holme Date: Sat, 31 Aug 2013 10:41:25 +0100 Subject: [PATCH] ftpserver.pl: Added argument check to IMAP command handlers Added BAD argument check to the following IMAP command handlers: APPEND, STORE, LIST, EXAMINE, STATUS and SEARCH --- tests/ftpserver.pl | 176 ++++++++++++++++++++++++++------------------- 1 file changed, 101 insertions(+), 75 deletions(-) diff --git a/tests/ftpserver.pl b/tests/ftpserver.pl index 21d3c1770d..7a52f962f3 100755 --- a/tests/ftpserver.pl +++ b/tests/ftpserver.pl @@ -877,66 +877,71 @@ sub APPEND_imap { my ($mailbox, $size) = ($1, $2); fix_imap_params($mailbox); - sendcontrol "+ Ready for literal data\r\n"; + if($mailbox eq "") { + sendcontrol "$cmdid BAD Command Argument\r\n"; + } + else { + sendcontrol "+ Ready for literal data\r\n"; - my $testno = $mailbox; - my $filename = "log/upload.$testno"; + my $testno = $mailbox; + my $filename = "log/upload.$testno"; - logmsg "Store test number $testno in $filename\n"; + logmsg "Store test number $testno in $filename\n"; - open(FILE, ">$filename") || - return 0; # failed to open output + open(FILE, ">$filename") || + return 0; # failed to open output - my $received = 0; - my $line; - while(5 == (sysread \*SFREAD, $line, 5)) { - if($line eq "DATA\n") { - sysread \*SFREAD, $line, 5; + my $received = 0; + my $line; + while(5 == (sysread \*SFREAD, $line, 5)) { + if($line eq "DATA\n") { + sysread \*SFREAD, $line, 5; - my $chunksize = 0; - if($line =~ /^([0-9a-fA-F]{4})\n/) { - $chunksize = hex($1); - } + my $chunksize = 0; + if($line =~ /^([0-9a-fA-F]{4})\n/) { + $chunksize = hex($1); + } - read_mainsockf(\$line, $chunksize); + read_mainsockf(\$line, $chunksize); - my $left = $size - $received; - my $datasize = ($left > $chunksize) ? $chunksize : $left; + my $left = $size - $received; + my $datasize = ($left > $chunksize) ? $chunksize : $left; - if($datasize > 0) { - logmsg "> Appending $datasize bytes to file\n"; - print FILE substr($line, 0, $datasize) if(!$nosave); - $line = substr($line, $datasize); + if($datasize > 0) { + logmsg "> Appending $datasize bytes to file\n"; + print FILE substr($line, 0, $datasize) if(!$nosave); + $line = substr($line, $datasize); - $received += $datasize; - if($received == $size) { - logmsg "Received all data, waiting for final CRLF.\n"; + $received += $datasize; + if($received == $size) { + logmsg "Received all data, waiting for final CRLF.\n"; + } + } + + if($received == $size && $line eq "\r\n") { + last; } } - - if($received == $size && $line eq "\r\n") { + elsif($line eq "DISC\n") { + logmsg "Unexpected disconnect!\n"; + last; + } + else { + logmsg "No support for: $line"; last; } } - elsif($line eq "DISC\n") { - logmsg "Unexpected disconnect!\n"; - last; - } - else { - logmsg "No support for: $line"; - last; + + if($nosave) { + print FILE "$size bytes would've been stored here\n"; } + close(FILE); + + logmsg "received $size bytes upload\n"; + + sendcontrol "$cmdid OK APPEND completed\r\n"; } - if($nosave) { - print FILE "$size bytes would've been stored here\n"; - } - close(FILE); - - logmsg "received $size bytes upload\n"; - - sendcontrol "$cmdid OK APPEND completed\r\n"; - return 0; } @@ -950,6 +955,9 @@ sub STORE_imap { if ($selected eq "") { sendcontrol "$cmdid BAD Command received in Invalid state\r\n"; } + elsif (($uid eq "") || ($what eq "")) { + sendcontrol "$cmdid BAD Command Argument\r\n"; + } else { sendcontrol "* $uid FETCH (FLAGS (\\Seen \\Deleted))\r\n"; sendcontrol "$cmdid OK STORE completed\r\n"; @@ -961,7 +969,6 @@ sub STORE_imap { sub LIST_imap { my ($args) = @_; my ($reference, $mailbox) = split(/ /, $args, 2); - my @data; fix_imap_params($reference, $mailbox); logmsg "LIST_imap got $args\n"; @@ -969,12 +976,18 @@ sub LIST_imap { if ($reference eq "verifiedserver") { # this is the secret command that verifies that this actually is # the curl test server - @data = ("* LIST () \"/\" \"WE ROOLZ: $$\"\r\n"); + sendcontrol "* LIST () \"/\" \"WE ROOLZ: $$\"\r\n"; + sendcontrol "$cmdid OK LIST Completed\r\n"; + if($verbose) { print STDERR "FTPD: We returned proof we are the test server\n"; } + logmsg "return proof we are we\n"; } + elsif ($reference eq "") { + sendcontrol "$cmdid BAD Command Argument\r\n"; + } else { my $testno = $reference; @@ -987,14 +1000,14 @@ sub LIST_imap { loadtest("$srcdir/data/test$testno"); - @data = getpart("reply", "data$testpart"); - } + my @data = getpart("reply", "data$testpart"); - for my $d (@data) { - sendcontrol $d; - } + for my $d (@data) { + sendcontrol $d; + } - sendcontrol "$cmdid OK LIST Completed\r\n"; + sendcontrol "$cmdid OK LIST Completed\r\n"; + } return 0; } @@ -1003,25 +1016,30 @@ sub EXAMINE_imap { my ($testno) = @_; fix_imap_params($testno); - logmsg "EXAMINE_imap got test $testno\n"; + logmsg "EXAMINE_imap got $testno\n"; - $testno =~ s/[^0-9]//g; - my $testpart = ""; - if ($testno > 10000) { - $testpart = $testno % 10000; - $testno = int($testno / 10000); + if ($testno eq "") { + sendcontrol "$cmdid BAD Command Argument\r\n"; } + else { + $testno =~ s/[^0-9]//g; + my $testpart = ""; + if ($testno > 10000) { + $testpart = $testno % 10000; + $testno = int($testno / 10000); + } - loadtest("$srcdir/data/test$testno"); + loadtest("$srcdir/data/test$testno"); - my @data = getpart("reply", "data$testpart"); + my @data = getpart("reply", "data$testpart"); - for my $d (@data) { - sendcontrol $d; + for my $d (@data) { + sendcontrol $d; + } + + sendcontrol "$cmdid OK [READ-ONLY] EXAMINE completed\r\n"; } - sendcontrol "$cmdid OK [READ-ONLY] EXAMINE completed\r\n"; - return 0; } @@ -1029,25 +1047,30 @@ sub STATUS_imap { my ($testno) = @_; fix_imap_params($testno); - logmsg "STATUS_imap got test $testno\n"; + logmsg "STATUS_imap got $testno\n"; - $testno =~ s/[^0-9]//g; - my $testpart = ""; - if ($testno > 10000) { - $testpart = $testno % 10000; - $testno = int($testno / 10000); + if ($testno eq "") { + sendcontrol "$cmdid BAD Command Argument\r\n"; } + else { + $testno =~ s/[^0-9]//g; + my $testpart = ""; + if ($testno > 10000) { + $testpart = $testno % 10000; + $testno = int($testno / 10000); + } - loadtest("$srcdir/data/test$testno"); + loadtest("$srcdir/data/test$testno"); - my @data = getpart("reply", "data$testpart"); + my @data = getpart("reply", "data$testpart"); - for my $d (@data) { - sendcontrol $d; + for my $d (@data) { + sendcontrol $d; + } + + sendcontrol "$cmdid OK STATUS completed\r\n"; } - sendcontrol "$cmdid OK STATUS completed\r\n"; - return 0; } @@ -1060,6 +1083,9 @@ sub SEARCH_imap { if ($selected eq "") { sendcontrol "$cmdid BAD Command received in Invalid state\r\n"; } + elsif ($what eq "") { + sendcontrol "$cmdid BAD Command Argument\r\n"; + } else { my $testno = $selected;