CGI and Perl

Listing 16.3. A Web-based command shell.

#!/usr/local/bin/perl
 use CGI::Form;
 $q = new CGI::Form;
 print $q->header();
 print $q->start_html(-title=>`A Web-based Command Shell');
 print "<H1>A Web-based Command Shell</H1>\n";
 if ($q->cgi->var(`REQUEST_METHOD') eq `GET') {
    &loginForm($q);
 } else {
    if ($q->param(`Action') eq "Login") {
       $uid=$q->param(`uid');
       $pw=$q->param(`pw');
       if (&validateLogin($uid,$pw)) {
          $history="";
          &shellForm($q,$history);
       } else {
          &unauthorized($q);
       }
    } elsif ($q->param(`Action') eq "Doit") {
       $history=$q->param(`cmdHistory');
       $command=$q->param(`command');
       if ($command ne "") {
          $history.=&doCommand($q,$command);
          }
       $q->param(`cmdHistory',$history);
       &shellForm($q,$history);
    } else {
       &unauthorized($q);
    }
 }
 print $q->end_html();
 sub validateLogin {
    my($userid,$pw)[email protected]_;
    my($retval)=0;
    if (open(PASSWD,"/etc/passwd")) {
       while (<PASSWD>) {
          chop;
          my($login,$passwd,$uid,$gid,$rest)=split(/:/);
          if ($login eq $userid && crypt($pw,$passwd) eq $passwd) {
             $retval=1;
             last;
          }
       }
       close(PASSWD);
    }
    return $retval;
 }
 sub unauthorized {
    my($q)[email protected]_;
    print "<STRONG>Sorry! You are not authorized to enter this area!</STRONG><BR>\n";
    print "<A HREF=/cgi-bin/cmdshell.pl>Try again</A>";
 }
 sub loginForm {
    my($q)[email protected]_;
    print "<P>Please enter your userid and password:<P>\n";
    print $q->start_multipart_form();
    print $q->textfield(-name=>`uid');
    print "<BR>";
    print $q->password_field(-name=>`pw');
    print "<BR>";
    print $q->submit(-name=>`Action',-value=>`Login');
    print $q->reset;
    print $q->endform;
 }
 sub shellForm {
    my($q,$history)[email protected]_;
    print $q->start_multipart_form();
    print $q->hidden(-name=>`cmdHistory',-value=>$history);
    print $q->textfield(-name=>`command');
    print "<BR>";
    print $q->submit(-name=>`Action',-value=>`Doit');
    print " ";
    print $q->reset;
    print $q->endform;
    print "<P>Command History:<P>\n";
    print "<PRE>$history<\PRE>";
 }
 sub doCommand {
    my($q,$cmd)[email protected]_;
    my($hist)="$cmd\n";
    $hist.=`$cmd`;
    return "$hist\n";
 }

You can see how the login form would look in Figure 16.3. Once the user has logged in and issued a few commands, the shell would look as shown in Figure 16.4.

Figure 16.3. The command shell login form.

Figure 16.4. The command shell with history.

You will notice in this example that we keep a running history of command output. When the output exceeds a certain limit, in this case 1,024 characters, it will be truncated. The session is maintained as long as continuous POST requests are made. As soon as the user leaves this CGI session, it will reinitialize on the GET request.

Advertisement:
Advertisement: