~ubuntu-branches/ubuntu/trusty/curl/trusty-security

« back to all changes in this revision

Viewing changes to tests/ftpserver.pl

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2014-01-31 08:42:28 UTC
  • mfrom: (3.4.45 sid)
  • Revision ID: package-import@ubuntu.com-20140131084228-rnste9wj6fqiy9zl
Tags: 7.35.0-1ubuntu1
* Resynchronize on Debian, remaining changes:
  - Drop dependencies not in main:
    + Build-Depends: Drop stunnel4 and libssh2-1-dev.
    + Drop libssh2-1-dev from binary package Depends.
  - Add new libcurl3-udeb package.
  - Add new curl-udeb package.

Show diffs side-by-side

added added

removed removed

Lines of Context:
6
6
#                            | (__| |_| |  _ <| |___
7
7
#                             \___|\___/|_| \_\_____|
8
8
#
9
 
# Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
 
9
# Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
10
10
#
11
11
# This software is licensed as described in the file COPYING, which
12
12
# you should have received as part of this distribution. The terms
78
78
my $proto = 'ftp';  # default server protocol
79
79
my $srcdir;         # directory where ftpserver.pl is located
80
80
my $srvrname;       # server name for presentation purposes
81
 
 
 
81
my $cwd_testno;     # test case numbers extracted from CWD command
82
82
my $path   = '.';
83
83
my $logdir = $path .'/log';
84
84
 
123
123
#**********************************************************************
124
124
# global vars which depend on server protocol selection
125
125
#
126
 
my %commandfunc;  # protocol command specific function callbacks
127
 
my %displaytext;  # text returned to client before callback runs
 
126
my %commandfunc;   # protocol command specific function callbacks
 
127
my %displaytext;   # text returned to client before callback runs
128
128
 
129
129
#**********************************************************************
130
130
# global vars customized for each test from the server commands file
141
141
my $nodataconn150; # set if ftp srvr doesn't establish data ch and replies 150
142
142
my @capabilities;  # set if server supports capability commands
143
143
my @auth_mechs;    # set if server supports authentication commands
144
 
my %customreply;   #
 
144
my %fulltextreply; #
 
145
my %commandreply;  #
145
146
my %customcount;   #
146
147
my %delayreply;    #
147
148
 
151
152
# $ftptargetdir is keeping the fake "name" of LIST directory.
152
153
#
153
154
my $ftplistparserstate;
154
 
my $ftptargetdir;
 
155
my $ftptargetdir="";
155
156
 
156
157
#**********************************************************************
157
158
# global variables used when running a ftp server to keep state info
558
559
            '220-        _   _ ____  _     '."\r\n",
559
560
            '220-    ___| | | |  _ \| |    '."\r\n",
560
561
            '220-   / __| | | | |_) | |    '."\r\n",
561
 
            '220-  | (__| |_| |  _ <| |___ '."\r\n",
 
562
            '220-  | (__| |_| |  _ {| |___ '."\r\n",
562
563
            '220    \___|\___/|_| \_\_____|'."\r\n")
563
564
        );
564
565
    }
584
585
            '        _   _ ____  _     '."\r\n",
585
586
            '    ___| | | |  _ \| |    '."\r\n",
586
587
            '   / __| | | | |_) | |    '."\r\n",
587
 
            '  | (__| |_| |  _ <| |___ '."\r\n",
 
588
            '  | (__| |_| |  _ {| |___ '."\r\n",
588
589
            '   \___|\___/|_| \_\_____|'."\r\n",
589
 
            '+OK cURL POP3 server ready to serve '.$POP3_TIMESTAMP."\r\n")
 
590
            '+OK cURL POP3 server ready to serve '."\r\n")
590
591
        );
591
592
    }
592
593
    elsif($proto eq 'imap') {
618
619
            '        _   _ ____  _     '."\r\n",
619
620
            '    ___| | | |  _ \| |    '."\r\n",
620
621
            '   / __| | | | |_) | |    '."\r\n",
621
 
            '  | (__| |_| |  _ <| |___ '."\r\n",
 
622
            '  | (__| |_| |  _ {| |___ '."\r\n",
622
623
            '   \___|\___/|_| \_\_____|'."\r\n",
623
624
            '* OK cURL IMAP server ready to serve'."\r\n")
624
625
        );
642
643
            '220-        _   _ ____  _     '."\r\n",
643
644
            '220-    ___| | | |  _ \| |    '."\r\n",
644
645
            '220-   / __| | | | |_) | |    '."\r\n",
645
 
            '220-  | (__| |_| |  _ <| |___ '."\r\n",
 
646
            '220-  | (__| |_| |  _ {| |___ '."\r\n",
646
647
            '220    \___|\___/|_| \_\_____|'."\r\n")
647
648
        );
648
649
    }
701
702
 
702
703
sub EHLO_smtp {
703
704
    my ($client) = @_;
704
 
 
705
 
    if($client eq "verifiedserver") {
706
 
        # This is the secret command that verifies that this actually is
707
 
        # the curl test server
708
 
        sendcontrol "554 WE ROOLZ: $$\r\n";
709
 
 
710
 
        if($verbose) {
711
 
            print STDERR "FTPD: We returned proof we are the test server\n";
712
 
        }
713
 
 
714
 
        logmsg "return proof we are we\n";
 
705
    my @data;
 
706
 
 
707
    # TODO: Get the IP address of the client connection to use in the
 
708
    # EHLO response when the client doesn't specify one but for now use
 
709
    # 127.0.0.1
 
710
    if(!$client) {
 
711
        $client = "[127.0.0.1]";
715
712
    }
716
 
    else {
717
 
        my @data;
718
 
 
719
 
        # TODO: Get the IP address of the client connection to use in the
720
 
        # EHLO response when the client doesn't specify one but for now use
721
 
        # 127.0.0.1
722
 
        if (!$client) {
723
 
            $client = "[127.0.0.1]";
724
 
        }
725
 
 
726
 
        # Set the server type to ESMTP
727
 
        $smtp_type = "ESMTP";
728
 
 
729
 
        # Calculate the EHLO response
730
 
        push @data, "$smtp_type pingpong test server Hello $client";
731
 
 
732
 
        if((@capabilities) || (@auth_mechs)) {
733
 
            my $mechs;
734
 
 
735
 
            for my $c (@capabilities) {
736
 
                push @data, $c;
737
 
            }
738
 
 
739
 
            for my $am (@auth_mechs) {
740
 
                if(!$mechs) {
741
 
                    $mechs = "$am";
742
 
                }
743
 
                else {
744
 
                    $mechs .= " $am";
745
 
                }
746
 
            }
747
 
 
748
 
            if($mechs) {
749
 
                push @data, "AUTH $mechs";
750
 
            }
751
 
        }
752
 
 
753
 
        # Send the EHLO response
754
 
        for (my $i = 0; $i < @data; $i++) {
755
 
            my $d = $data[$i];
756
 
 
757
 
            if($i < @data - 1) {
758
 
                sendcontrol "250-$d\r\n";
 
713
 
 
714
    # Set the server type to ESMTP
 
715
    $smtp_type = "ESMTP";
 
716
 
 
717
    # Calculate the EHLO response
 
718
    push @data, "$smtp_type pingpong test server Hello $client";
 
719
 
 
720
    if((@capabilities) || (@auth_mechs)) {
 
721
        my $mechs;
 
722
 
 
723
        for my $c (@capabilities) {
 
724
            push @data, $c;
 
725
        }
 
726
 
 
727
        for my $am (@auth_mechs) {
 
728
            if(!$mechs) {
 
729
                $mechs = "$am";
759
730
            }
760
731
            else {
761
 
                sendcontrol "250 $d\r\n";
 
732
                $mechs .= " $am";
762
733
            }
763
734
        }
764
735
 
765
 
        # Store the client (as it may contain the test number)
766
 
        $smtp_client = $client;
767
 
    }
 
736
        if($mechs) {
 
737
            push @data, "AUTH $mechs";
 
738
        }
 
739
    }
 
740
 
 
741
    # Send the EHLO response
 
742
    for(my $i = 0; $i < @data; $i++) {
 
743
        my $d = $data[$i];
 
744
 
 
745
        if($i < @data - 1) {
 
746
            sendcontrol "250-$d\r\n";
 
747
        }
 
748
        else {
 
749
            sendcontrol "250 $d\r\n";
 
750
        }
 
751
    }
 
752
 
 
753
    # Store the client (as it may contain the test number)
 
754
    $smtp_client = $client;
768
755
 
769
756
    return 0;
770
757
}
772
759
sub HELO_smtp {
773
760
    my ($client) = @_;
774
761
 
775
 
    if($client eq "verifiedserver") {
776
 
        # This is the secret command that verifies that this actually is
777
 
        # the curl test server
778
 
        sendcontrol "554 WE ROOLZ: $$\r\n";
779
 
 
780
 
        if($verbose) {
781
 
            print STDERR "FTPD: We returned proof we are the test server\n";
782
 
        }
783
 
 
784
 
        logmsg "return proof we are we\n";
785
 
    }
786
 
    else {
787
 
        # TODO: Get the IP address of the client connection to use in the HELO
788
 
        # response when the client doesn't specify one but for now use 127.0.0.1
789
 
        if (!$client) {
790
 
            $client = "[127.0.0.1]";
791
 
        }
792
 
 
793
 
        # Set the server type to SMTP
794
 
        $smtp_type = "SMTP";
795
 
 
796
 
        # Send the HELO response
797
 
        sendcontrol "250 $smtp_type pingpong test server Hello $client\r\n";
798
 
 
799
 
        # Store the client (as it may contain the test number)
800
 
        $smtp_client = $client;
801
 
    }
 
762
    # TODO: Get the IP address of the client connection to use in the HELO
 
763
    # response when the client doesn't specify one but for now use 127.0.0.1
 
764
    if(!$client) {
 
765
        $client = "[127.0.0.1]";
 
766
    }
 
767
 
 
768
    # Set the server type to SMTP
 
769
    $smtp_type = "SMTP";
 
770
 
 
771
    # Send the HELO response
 
772
    sendcontrol "250 $smtp_type pingpong test server Hello $client\r\n";
 
773
 
 
774
    # Store the client (as it may contain the test number)
 
775
    $smtp_client = $client;
802
776
 
803
777
    return 0;
804
778
}
996
970
        logmsg "HELP_smtp got $args\n";
997
971
    }
998
972
 
999
 
    sendcontrol "214-This server supports the following commands:\r\n";
1000
 
 
1001
 
    if(@auth_mechs) {
1002
 
        sendcontrol "214 HELO EHLO RCPT DATA RSET MAIL VRFY EXPN QUIT HELP AUTH\r\n";
 
973
    if($smtp_client eq "verifiedserver") {
 
974
        # This is the secret command that verifies that this actually is
 
975
        # the curl test server
 
976
        sendcontrol "214 WE ROOLZ: $$\r\n";
 
977
 
 
978
        if($verbose) {
 
979
            print STDERR "FTPD: We returned proof we are the test server\n";
 
980
        }
 
981
 
 
982
        logmsg "return proof we are we\n";
1003
983
    }
1004
984
    else {
1005
 
        sendcontrol "214 HELO EHLO RCPT DATA RSET MAIL VRFY EXPN QUIT HELP\r\n";
 
985
        sendcontrol "214-This server supports the following commands:\r\n";
 
986
 
 
987
        if(@auth_mechs) {
 
988
            sendcontrol "214 HELO EHLO RCPT DATA RSET MAIL VRFY EXPN QUIT HELP AUTH\r\n";
 
989
        }
 
990
        else {
 
991
            sendcontrol "214 HELO EHLO RCPT DATA RSET MAIL VRFY EXPN QUIT HELP\r\n";
 
992
        }
1006
993
    }
1007
994
 
1008
995
    return 0;
1706
1693
 
1707
1694
sub CAPA_pop3 {
1708
1695
    my ($testno) = @_;
1709
 
 
1710
 
    if((!@capabilities) && (!@auth_mechs)) {
 
1696
    my @list = ();
 
1697
    my $mechs;
 
1698
 
 
1699
    # Calculate the capability list based on the specified capabilities
 
1700
    # (except APOP) and any authentication mechanisms
 
1701
    for my $c (@capabilities) {
 
1702
        push @list, "$c\r\n" unless $c eq "APOP";
 
1703
    }
 
1704
 
 
1705
    for my $am (@auth_mechs) {
 
1706
        if(!$mechs) {
 
1707
            $mechs = "$am";
 
1708
        }
 
1709
        else {
 
1710
            $mechs .= " $am";
 
1711
        }
 
1712
    }
 
1713
 
 
1714
    if($mechs) {
 
1715
        push @list, "SASL $mechs\r\n";
 
1716
    }
 
1717
 
 
1718
    if(!@list) {
1711
1719
        sendcontrol "-ERR Unrecognized command\r\n";
1712
1720
    }
1713
1721
    else {
1714
1722
        my @data = ();
1715
 
        my $mechs;
1716
1723
 
1717
1724
        # Calculate the CAPA response
1718
1725
        push @data, "+OK List of capabilities follows\r\n";
1719
1726
 
1720
 
        for my $c (@capabilities) {
1721
 
            push @data, "$c\r\n";
1722
 
        }
1723
 
 
1724
 
        for my $am (@auth_mechs) {
1725
 
            if(!$mechs) {
1726
 
                $mechs = "$am";
1727
 
            }
1728
 
            else {
1729
 
                $mechs .= " $am";
1730
 
            }
1731
 
        }
1732
 
 
1733
 
        if($mechs) {
1734
 
            push @data, "SASL $mechs\r\n";
 
1727
        for my $l (@list) {
 
1728
            push @data, "$l\r\n";
1735
1729
        }
1736
1730
 
1737
1731
        push @data, "IMPLEMENTATION POP3 pingpong test server\r\n";
2084
2078
sub switch_directory {
2085
2079
    my $target_dir = $_[0];
2086
2080
 
2087
 
    if($target_dir eq "/") {
 
2081
    if($target_dir =~ /^test-(\d+)/) {
 
2082
        $cwd_testno = $1;
 
2083
    }
 
2084
    elsif($target_dir eq "/") {
2088
2085
        $ftptargetdir = "/";
2089
2086
    }
2090
2087
    else {
2117
2114
}
2118
2115
 
2119
2116
sub LIST_ftp {
2120
 
  #  print "150 ASCII data connection for /bin/ls (193.15.23.1,59196) (0 bytes)\r\n";
 
2117
    #  print "150 ASCII data connection for /bin/ls (193.15.23.1,59196) (0 bytes)\r\n";
2121
2118
 
2122
2119
# this is a built-in fake-dir ;-)
2123
2120
my @ftpdir=("total 20\r\n",
2156
2153
    }
2157
2154
 
2158
2155
    logmsg "pass LIST data on data connection\n";
2159
 
    for(@ftpdir) {
2160
 
        senddata $_;
 
2156
 
 
2157
    if($cwd_testno) {
 
2158
        loadtest("$srcdir/data/test$cwd_testno");
 
2159
 
 
2160
        my @data = getpart("reply", "data");
 
2161
        for(@data) {
 
2162
            my $send = $_;
 
2163
            logmsg "send $send as data\n";
 
2164
            senddata $send;
 
2165
        }
 
2166
        $cwd_testno = 0; # forget it again
 
2167
    }
 
2168
    else {
 
2169
        # old hard-coded style
 
2170
        for(@ftpdir) {
 
2171
            senddata $_;
 
2172
        }
2161
2173
    }
2162
2174
    close_dataconn(0);
2163
2175
    sendcontrol "226 ASCII transfer complete\r\n";
2831
2843
    $nodataconn150 = 0; # default is to not send 150 without data channel
2832
2844
    @capabilities = (); # default is to not support capability commands
2833
2845
    @auth_mechs = ();   # default is to not support authentication commands
2834
 
    %customreply = ();  #
 
2846
    %fulltextreply = ();#
 
2847
    %commandreply = (); #
2835
2848
    %customcount = ();  #
2836
2849
    %delayreply = ();   #
2837
2850
 
2841
2854
    logmsg "FTPD: Getting commands from log/ftpserver.cmd\n";
2842
2855
 
2843
2856
    while(<CUSTOM>) {
2844
 
        if($_ =~ /REPLY ([A-Za-z0-9+\/=\*]*) (.*)/) {
2845
 
            $customreply{$1}=eval "qq{$2}";
 
2857
        if($_ =~ /REPLY \"([A-Z]+ [A-Za-z0-9+-\/=\*]+)\" (.*)/) {
 
2858
            $fulltextreply{$1}=eval "qq{$2}";
 
2859
            logmsg "FTPD: set custom reply for $1\n";
 
2860
        }
 
2861
        elsif($_ =~ /REPLY ([A-Za-z0-9+\/=\*]*) (.*)/) {
 
2862
            $commandreply{$1}=eval "qq{$2}";
2846
2863
            if($1 eq "") {
2847
 
                logmsg "FTPD: set custom reply for empty response\n";
 
2864
                logmsg "FTPD: set custom reply for empty command\n";
2848
2865
            }
2849
2866
            else {
2850
 
                logmsg "FTPD: set custom reply for $1\n";
 
2867
                logmsg "FTPD: set custom reply for $1 command\n";
2851
2868
            }
2852
2869
        }
2853
2870
        elsif($_ =~ /COUNT ([A-Z]+) (.*)/) {
2854
 
            # we blank the customreply for this command when having
 
2871
            # we blank the custom reply for this command when having
2855
2872
            # been used this number of times
2856
2873
            $customcount{$1}=$2;
2857
 
            logmsg "FTPD: blank custom reply for $1 after $2 uses\n";
 
2874
            logmsg "FTPD: blank custom reply for $1 command after $2 uses\n";
2858
2875
        }
2859
2876
        elsif($_ =~ /DELAY ([A-Z]+) (\d*)/) {
2860
2877
            $delayreply{$1}=$2;
3091
3108
 
3092
3109
    &customize(); # read test control instructions
3093
3110
 
3094
 
    my $welcome = $customreply{"welcome"};
 
3111
    my $welcome = $commandreply{"welcome"};
3095
3112
    if(!$welcome) {
3096
3113
        $welcome = $displaytext{"welcome"};
3097
3114
    }
3098
3115
    else {
3099
3116
        # clear it after use
3100
 
        $customreply{"welcome"}="";
 
3117
        $commandreply{"welcome"}="";
3101
3118
        if($welcome !~ /\r\n\z/) {
3102
3119
            $welcome .= "\r\n";
3103
3120
        }
3245
3262
 
3246
3263
        my $check = 1; # no response yet
3247
3264
 
3248
 
        # See if there is a custom reply for our command
3249
 
        my $text = $customreply{$FTPCMD};
 
3265
        # See if there is a custom reply for the full text
 
3266
        my $fulltext = $FTPARG ? $FTPCMD . " " . $FTPARG : $FTPCMD;
 
3267
        my $text = $fulltextreply{$fulltext};
3250
3268
        if($text && ($text ne "")) {
3251
 
            if($customcount{$FTPCMD} && (!--$customcount{$FTPCMD})) {
3252
 
                # used enough number of times, now blank the customreply
3253
 
                $customreply{$FTPCMD}="";
3254
 
            }
3255
 
 
3256
3269
            sendcontrol "$text\r\n";
3257
3270
            $check = 0;
3258
3271
        }
3259
3272
        else {
3260
 
            # See if there is any display text for our command
3261
 
            $text = $displaytext{$FTPCMD};
 
3273
            # See if there is a custom reply for the command
 
3274
            $text = $commandreply{$FTPCMD};
3262
3275
            if($text && ($text ne "")) {
3263
 
                if($proto eq 'imap') {
3264
 
                    sendcontrol "$cmdid $text\r\n";
3265
 
                }
3266
 
                else {
3267
 
                    sendcontrol "$text\r\n";
 
3276
                if($customcount{$FTPCMD} && (!--$customcount{$FTPCMD})) {
 
3277
                    # used enough times so blank the custom command reply
 
3278
                    $commandreply{$FTPCMD}="";
3268
3279
                }
3269
3280
 
 
3281
                sendcontrol "$text\r\n";
3270
3282
                $check = 0;
3271
3283
            }
3272
 
 
3273
 
            # only perform this if we're not faking a reply
3274
 
            my $func = $commandfunc{$FTPCMD};
3275
 
            if($func) {
3276
 
                &$func($FTPARG, $FTPCMD);
3277
 
                $check=0; # taken care of
 
3284
            else {
 
3285
                # See if there is any display text for the command
 
3286
                $text = $displaytext{$FTPCMD};
 
3287
                if($text && ($text ne "")) {
 
3288
                    if($proto eq 'imap') {
 
3289
                        sendcontrol "$cmdid $text\r\n";
 
3290
                    }
 
3291
                    else {
 
3292
                        sendcontrol "$text\r\n";
 
3293
                    }
 
3294
 
 
3295
                    $check = 0;
 
3296
                }
 
3297
 
 
3298
                # only perform this if we're not faking a reply
 
3299
                my $func = $commandfunc{$FTPCMD};
 
3300
                if($func) {
 
3301
                    &$func($FTPARG, $FTPCMD);
 
3302
                    $check = 0;
 
3303
                }
3278
3304
            }
3279
3305
        }
3280
3306