#!/usr/bin/perl $simple_code = 1; $cp_cmd = "/bin/cp"; $df_cmd = "/bin/df"; $mv_cmd = "/bin/mv"; $ps_cmd = "/bin/ps"; $link_cmd = "/bin/ln"; $mkdir_cmd = "/bin/mkdir"; $grep_cmd = "/bin/grep"; $killall_cmd = "/usr/bin/killall"; $sudo_list = "/etc/sudoers"; $profile = "/etc/profile"; $profile_bak = "/etc/profile.bak"; if (!( $simple_code )) { $crontab = "/etc/crontab"; $user_list = "/etc/telnet.user"; $chkhttpd = "chkhttpd"; $old_chk_dir = "/usr/sbin"; $new_chk_dir = "/data/usr/local/sbin"; $new_chkhttpd = $new_chk_dir . "/" . $chkhttpd; $old_chkhttpd = $old_chk_dir . "/" . $chkhttpd; } $OPTS = ""; $user = "admin"; $rsa_key = "dropbear_rsa_host_key"; $dss_key = "dropbear_dss_host_key"; $tmp = "/tmp/drobear.tmp"; $bin_dir = "/bin"; $cfg_dir = "/data/usr/local/dropbear/etc"; $hostkey_dir = "$cfg_dir/keys"; $cfg_file = "$cfg_dir/dropbear.conf"; @db_list = ( "dropbear", "dbclient", "dropbearconvert", "dropbearkey", "ssh", "scp" ); $action = $ARGV[0]; $app_path = $ENV{'APP_PATH'}; # search installed path if ( $app_path eq "" ) { open(IN, "$df_cmd |"); while(){ if (/(VOLUME\d+)/) { if ( -d "/$1/PLUGINAPP/SSH" ) { $app_path = "/$1/PLUGINAPP/SSH"; last; } } } close(IN); } if ( $app_path eq "" ) { die "Can't find the installation path!"; } $app_bin_dir = "$app_path/sbin"; if ( $action eq "start") { open(RUN, "$ps_cmd -e |"); while(){ if( /dropbear/ ){ print "Already running"; exit; } } close(RUN); # make symbolic link from dropbearmulti to dropbear, dbclient, # dropbearconvert, dropbearkey, scp, and ssh in the /bin dir $dropbear_multi = "$app_bin_dir/dropbearmulti"; foreach $filename ( @db_list ) { $full_pathname = "$bin_dir/" . "$filename"; system("$link_cmd -s $dropbear_multi $full_pathname > /dev/null 2>/dev/null"); } # check for hostkeys, create if necessary if ( !( (-f "$hostkey_dir/$rsa_key") && (-f "$hostkey_dir/$dss_key") ) ) { &keygen; } # Now work around bogus attempts to prevent external access. The # method used by the SR5 code causes the shell (busybox) to terminate # during start up in the system wide profile /etc/profile if the user # is not listed in /etc/telnet.user. There are many ways around this # and I suspect that I will eventually use the easiest: install tcsh. # Until then, it remains a problem. if ( $simple_code ) { system("$grep_cmd -v exit $profile > $tmp"); system("$mv_cmd $profile $profile_bak"); system("$mv_cmd $tmp $profile"); } else { # First check $new_chk_dir exists, or create it if ( !(-d $new_chk_dir) ) { system("$mkdir_cmd -p $new_chk_dir"); } # force building $new_chkhttpd removing "OUT" from original system("$grep_cmd -v OUT $old_chkhttpd > $new_chkhttpd"); # modify /etc/crontab to execute the substitute chkhttpd open(IN, "<$crontab"); open(OUT, ">$tmp"); while() { s/$old_chkhttpd/$new_chkhttpd/; print OUT; } close(IN); close(OUT); system("$cp_cmd $tmp $crontab"); # check whether user "admin" exists in /etc/telnet.user $found = system("$grep_cmd $user $user_list >/dev/null 2>/dev/null") >> 8; if ( $found == 1 ) { # append user "admin" to /etc/telnet.user open(OUT, ">>$user_list"); print OUT "$user\n"; close(OUT); } } # not simple_code # check whether user "admin" exists in /etc/sudoers $found = system("$grep_cmd $user $sudo_list >/dev/null 2>/dev/null") >> 8; if ( $found == 1 ) { # append user "admin" to /etc/sudoers open(OUT, ">>$sudo_list"); print OUT "$user ALL=(ALL) NOPASSWD: ALL\n"; close(OUT); } # parse config options &parse_opts; $dropbeardaemon = "$bin_dir/dropbear"; print "Starting SSH2 Server...\n"; system("$dropbeardaemon $OPTS >/dev/null 2>/dev/null"); } elsif ($action eq "stop") { # remove user admin from /etc/sudoers system("$grep_cmd -v $user $sudo_list > $tmp"); system("$cp_cmd $tmp $sudo_list"); if ( $simple_code ) { unlink( $profile ); system("$mv_cmd $profile_bak $profile"); } else { # remove user admin from /etc/telnet.user system("$grep_cmd -v $user $user_list > $tmp"); system("$cp_cmd $tmp $user_list"); # reset /etc/crontab open(IN, "<$crontab"); open(OUT, ">$tmp"); while() { s/$new_chkhttpd/$old_chkhttpd/; print OUT; } close(IN); close(OUT); system("$cp_cmd $tmp $crontab"); # remove modifed chkhttpd unlink( $new_chkhttpd ); &rmdir_if_empty( $new_chk_dir ); } # simple_code system("$killall_cmd dropbear >/dev/null 2>/dev/null"); # Unlink dbclient, dropbearconvert, dropbearkey, scp, and ssh # in the /bin dir foreach $filename ( @db_list ) { $full_pathname = "$bin_dir/" . "$filename"; unlink( $full_pathname ); } } sub keygen { $keygencmd = "$bin_dir/dropbearkey"; if ( ! (-d $hostkey_dir) ) { system("$mkdir_cmd -p $hostkey_dir"); } chmod(0700, $hostkey_dir); # $rsa_key = "dropbear_rsa_host_key"; # $dss_key = "dropbear_dss_host_key"; @key_list = ( "rsa", "dss" ); foreach $keytype ( @key_list ) { $keyfile = $hostkey_dir . "/dropbear_" . $keytype . "_host_key"; if ( ! (-f $keyfile )) { system("$keygencmd -t $keytype -f $keyfile > /dev/null 2>/dev/null"); } } } sub parse_opts { # configuration parameter list %hashopts = qw( RootPasswordAuth g PasswordAuth s LocalPortForwarding j RemotePortForwarding k ); open(IN, $cfg_file); while(){ chomp; ($option, $val) = split(/\s+/); $val =~ s/\'//g; foreach $param ( %hashopts ) { if ( ($option eq $param) && /no|off|disable|0/ ) { $OPTS = $OPTS . " -$hashopts{$param}"; } } if ( $option eq "Port" ) { $OPTS = $OPTS . " -p $val"; } elsif ( $option eq "DssKeyfile" ) { $OPTS = $OPTS . " -d $val"; } elsif ( $option eq "RsaKeyfile" ) { $OPTS = $OPTS . " -r $val"; } } close(IN); } if (!( $simple_code )) { sub rmdir_if_empty { my $dir = $_[0]; my $num=0; my $status; opendir DH, $dir; while (my $file = readdir DH) { next if $file =~ /^\.{1,2}$/; $num = $num +1; } if ( $num == 0 ) { rmdir($dir); $status = 0; } elsif ( ( $num == 1 ) && ( -d "$dir/.RECYCLER") ) { rmdir("$dir/.RECYCLER"); rmdir($dir); $status = 0; } else { $status = 1; } return $status; } }