⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 install.pl

📁 伯克利做的SFTP安全文件传输协议
💻 PL
📖 第 1 页 / 共 3 页
字号:
  # permit use of existing keys to keep keys across upgrades  if (-e "${key_dest}/DSA") {    print "DSA keys already exist, skipping key generation...\n"  }  else {    # generate keys (client also, for testing, to share randomSeed)    cd("$key_dest");    $cmd = "${binary_dest}/makekeys $elgamal_key_len $dsa_key_len 0";    if ($branding_string) {      print "Supplying branding string: $branding_string\n";      run("echo \"$branding_string\" | $cmd");    }    else {      run("$cmd");    }  }  # write uninstall info  #prependUninstallCmd("removing keys", "rm -rf ${key_dest}/DSA ${key_dest}/ElGamal");  #prependUninstallCmd("removing cached host keys", "rm -rf ${key_dest}/keys");  # we don't want to delete keys, esp. server keys, since we want people to use  # the same server keys across an upgrade.. if someone truly wants to delete  # the keys, they'll have to do it themselves  endSection("generated keys");}if (startSection()) {  # create a text file for users to view the public key  cd("$key_dest");  run("${binary_dest}/viewkey DSA/public.key > " .        "${key_dest}/DSA/public.key.txt");  # don't bother with uninstall info because the above  # deletion of ${key_dest}/DSA will get public.key.txt  endSection("created public.key.txt");}if (startSection()) {  # set permissions for key files and directories  run("chmod $key_dir_perm $key_dest",      "chmod $seed_perm ${key_dest}/randomSeed",      "chmod $key_subdir_perm ${key_dest}/DSA",      "chmod $privkey_perm ${key_dest}/DSA/private.key",      "chmod $pubkey_perm ${key_dest}/DSA/public.key",      "chmod $pubkeytxt_perm ${key_dest}/DSA/public.key.txt",      "chmod 700 ${key_dest}/ElGamal",      "chmod 600 ${key_dest}/ElGamal/*",      "chown -R $daemon_user $key_dest",      "chgrp -R $daemon_group $key_dest");  # no explicit uninstall necessary because these files are deleted  # during other stages' uninstalls  endSection("set the permissions on the keys");}# there used to be a "partial" test here, but I decided it wasn't# worth the hassle of making it work reliably, and its diagnostic# value was not very muchif (startSection()) {  # backup, read  beginModifying($etc_services);  # append a block of section break comments  @file = (@file,    "#\n",    "# added $comment\n",    "#\n");  # put a safetp line  if ($sftpd_port == 21) {    # modify existing ftp line    my $numSubsts = 0;      # count number of times we substitute    foreach $line (@file) {      # in this regexp, $1 is the required part (ftp...21/tcp) and      # $2 is the rest of the line (other service names and possibly      # a comment)      $numSubsts +=        $line =~ s[^(ftp\s+21/tcp)(.*)]                  [$1\t\tsafetp$2\t\t# safetp added $comment];    }    if ($numSubsts != 1) {       # too many, or too few, substitutions      print("error: While computing the new $fn, I made $numSubsts\n",            "       changes, instead of the expected 1 change.  Thus, I\n",            "       screwed up, most likely.\n\n");      if (open(TMP1, ">$tmp1")) {        print TMP1 @file;        close(TMP1);        print("       I wrote the botched $fn to $tmp1,\n",              "       so you can inspect it.\n\n");      }      else {        print("       I tried to write the botched $fn to $tmp1,\n",              "       but failed to open $tmp1...?\n\n");      }      print("       See if you can figure out what went wrong, and modify\n",            "       $fn to try to fix it, then re-run $0.\n");      exit(4);    }  }  else {    # add a new line for safetp    @file = (@file,      "safetp\t\t${sftpd_port}/tcp\t\t# added $comment\n");  }  # add the raw-ftp line  @file = (@file,    "raw-ftp\t\t${raw_ftp_port}/tcp\t\t# added $comment\n");  # write computed contents to /etc/services  finishModifying();  endSection("modified /etc/services");}if (startSection()) {  # backup, read  beginModifying($etc_inetd_conf);  # grab the current ftp line  @ftp_lines = grep /^ftp\s/, @file;  if (@ftp_lines > 1) {    # this shouldn't happen unless /etc/inetd.conf has mulitple entries for ftp!    print("error: I am confused as to which of these is the ftp line:\n");    printIndented(@ftp_lines);    print("If you (temporarily) comment-out all but one, I will use that one.\n");    exit(2);  }  # check that there is an ftp line  if (@ftp_lines == 0) {    print("error: I don't see any ftp lines in $fn.  Please add a line for\n",          "       the ftp service so I can move it around.\n");    exit(2);  }  # turn off existing ftp if it would conflict with sftpd  if ($sftpd_port == 21) {    # here, comment is put in front, to emphasize that it must be removed    # completely for this line to be re-activated    my $numSubsts = 0;    foreach $line (@file) {      $numSubsts +=        $line =~ s[(^ftp\s.*)]                  [# (removed ${comment}) $1];    }    if ($numSubsts != 1) {      die "I goofed modifying $fn";    }  }  # going to append, so insert a section break  # this is the only comment that appears for these lines, because inetd.conf  #   doesn't allow comments on the same line as a non-comment line  # append a block of section break comments  @file = (@file,    "#\n",    "# added $comment\n",    "#\n");  # modify existing ftp line (currently in $ftp_lines[0])  @file = (@file,    "raw-${ftp_lines[0]}");  # add the safetp line  @file = (@file,    "safetp\tstream\ttcp\tnowait\t$daemon_user\t" .    "${binary_dest}/sftpd sftpd ${sftpd_options}\n");  # write to /etc/inetd.conf  finishModifying();  endSection("modified /etc/inetd.conf");}if (startSection()) {  # HUP it; this causes it to re-read /etc/inetd.conf  hupInetdOrAskUser();  # write uninstall info; note that, for this, we *append* rather  # than prepend, because hup'ing inetd should wait until everything  # else is back in order  appendUninstall("hupInetdOrAskUser();");  endSection("sent HUP signal to inetd");}if (startSection()) {  if ($do_full_test == 1) {    # temporarily switch to $daemon_user    dropRoot($daemon_uid, $daemon_gid);    # run sftpc    cd("/tmp");    # run from /tmp to avoid cwd=cwd problem    askQuestionNotSaved(      "Instructions:  I'm about to start sftpc so you can test it.\n" .      "You need to give four responses:\n" .      "  username: any valid user name on this system\n" .      "  password: the corresponding password\n" .      "  sftpc> test      (at first sftpc prompt)\n" .      "  sftpc> quit      (at second sftpc prompt)\n" .      "When ready, hit Enter: ",      "");    my $sftpc_cmd = "${binary_dest}/sftpc ${sftpc_full_extras} " .                    "localhost ${sftpd_port}";    if (!runDontDie($sftpc_cmd)) {      print("\n",            "error: The full test failed.  Since the protocol test\n",            "       above already succeeded, the error here is most\n",            "       likely something wrong with inetd.\n",            "\n",            "  sftpc command line used:\n",            "    env SAFETP_CONFIG=" . $ENV{SAFETP_CONFIG} . "\n",            "    ${sftpc_cmd}\n",            "\n",            "       See http://safetp.cs.berkeley.edu/trouble.html\n",            "       for some ideas on how to fix this.\n");      exit(2);    }    # restore uid/gid    resumeRoot();    print "full test: SUCCESS!\n";  }  endSection("did full test");}if (startSection()) {  # link to the unix client  makeSymlink("${binary_dest}/sftpc", "${user_binary_dest}/sftpc");  # links to keys and entropy utilities; I make the symlink name  # include "sftpc-" to avoid executable namespace pollution  makeSymlink("${binary_dest}/makekeys", "${user_binary_dest}/sftpc-makekeys");  makeSymlink("${binary_dest}/addent", "${user_binary_dest}/sftpc-addent");  # uninstall info  prependUninstallCmd("removing client binary symlinks",                      "rm -f ${user_binary_dest}/sftpc " .                            "${user_binary_dest}/sftpc-makekeys " .                            "${user_binary_dest}/sftpc-addent");  endSection("created symlinks");}if (startSection()) {  if ($do_edit_motd) {    # backup, read    beginModifying($etc_motd);    # append banner, including pointer to public key text file    # (syntax:  "foo" x 3  yields  "foofoofoo")    @file = (@file,      "\n",      "  $datestamp  SafeTP installed.  See http://safetp.cs.berkeley.edu\n",      "  " . " " x length($datestamp) .                  "  Public key: ${key_dest}/DSA/public.key.txt\n");    # write changed file to disk    finishModifying();  }  endSection("edited /etc/motd");}if (startSection()) {  print <<EOF;  --------------------------------------------------  -- The SafeTP install has finished!  Excellent! --  --------------------------------------------------  Summary of changes:    - binaries were copied to $binary_dest    - symlinks were created in $user_binary_dest    - keys were created in $key_dest    - $etc_services:      - added 'safetp' as port $sftpd_port      - added 'raw-ftp' as port $raw_ftp_port    - $etc_inetd_conf:      - added 'safetp' -> 'sftpd'      - removed 'ftp' -> 'ftpd' (if safetp port is 21)      - added 'raw-ftp' -> 'ftpd'    - $etc_motd: optionally added a blurb    - put backups and diffs of modified files in $work_dir    - created $uninstall_file  Executing '$0 -u' will un-install SafeTP.EOF  endSection("printed final success message");}else {  # only executed if we skipped final section, which only happens  # if someone re-runs install script after it's finished  print("This is the end of the install script.  If you need to\n",        "re-run this install script, remove the file         ${state_file}.\n");}# end of install script!exit(0);# ----------------- helper subroutines ----------------------# interpret -u to mean uninstall, die on any othersub processCommandLineOptions {  my $op;  while ($op = shift @ARGV) {    if ($op eq "-u") {      doUninstall();      exit();    }    elsif ($op eq "-hostTest") {      print("Here is my guess at a complete process list:\n");      printIndented(getAllProcesses());      hupInetdOrAskUser();      print("I think the host type is: $hostType\n");      printf("I think the fqdn is %s\n", getFQDN());      exit();    }    elsif ($op eq "-debug") {      $debug_mode = 1;      diagnostic("debug mode is on");    }    elsif ($op eq "-test") {      # setup things for dry run      $dry_run = 1;      $work_dir = "$drydir/safetp";      $state_file = "$work_dir/safetp_install_state";      $uninstall_file = "$work_dir/uninstall.cmds";      mkdirIfNotAlready($drydir);      mkdirIfNotAlready("$drydir/links");      $etc_services = dryRunFile($etc_services, "$drydir/services");      $etc_inetd_conf = dryRunFile($etc_inetd_conf, "$drydir/inetd.conf");      if ($has_etc_motd) {        $etc_motd = dryRunFile($etc_motd, "$drydir/motd");      }    }    elsif ($op eq "-noninter") {      $noninteractive = 1;    }    else {      print("Supported options:\n",            "  (no option)   - run the installer\n",            "  -u            - run the uninstaller\n",            "  -hostTest     - test some system-specific stuff\n",            "  -debug        - turn on debugging diagnostics\n",            "  -test         - dry-run test install as non-root\n",            "  -noninter     - use all the defaults, don't do final test\n",           );      exit(1);    }  }}# read in state from a prior run of this script, so we can resume# where we left off; also, arrange to keep appending new statesub readSavedAnswers {  if (!open(STATE, "<$state_file")) {    # this is the first run    @savedAnswers = ();    diagnostic("this is the first run");  }  else {    # grab what we have    @savedAnswers = <STATE>;    # strip newlines from all the answers    for ($i = 0; $i < @savedAnswers; $i++) {      chomp($savedAnswers[$i]);    }    diagnostic("read $i saved answers");    close(STATE) or die;  }}# write a single line of state to the state filesub appendState {  my ($line) = @_;  appendToFile($line, "$state_file");}# remove last saved answersub forgetLastAnswer {  diagnostic("forgetting last answer");  @answers = readFile($state_file);  pop(@answers);  writeFile($state_file, @answers);}# return the first line of a (possibly) multi-line value,# throwing away the newline as wellsub firstLine {  my ($line) = @_;     # grab first line, with \n  $line =~ s/\n//;     # throw away \n  return $line;}# print the value of a variable, given a string containing its namesub pval {  my ($name) = @_;  print "$name = " . $$name . "\n";    # $$name means, map 'name' to its scalar value (a string), then map    # that string to *its* scalar value}# run a command (or list of commands), and if it fails, return false# either way, set global $lastCmdTried to command triedsub runDontDie {  my $cmd;  while ($cmd = shift @_) {    $lastCmdTried = $cmd;    print("executing: $cmd\n");    if (system($cmd) != 0) {    # error      return 0;    }  }  return 1;}# run a command (or list of commands), and if it fails, print a message and exitsub run {  if (!runDontDie(@_)) {    complainAndQuit($lastCmdTried);  }}# print a message about what went wrong, and print the call stack toosub complainAndQuit {  my ($context) = @_;  print("error: ");  printStackTrace(1);  print("this failed:\n",        "  $context\n",        "Try to correct the problem, and re-run $0\n");  exit(4);}# print the stack trace (except the last n frames)sub printStackTrace {  my ($n) = @_;  my @info;  my $outputLine = 1;  while (@info = caller($n++)) {    if ($outputLine++ == 1) {      print("At ");    }    else {      print(", called from\n   ");    }    print("line $info[2] of $info[1]");  }  print(":\n");}# change to a directory; require that it succeedsub cd {  my ($dir) = @_;  chdir("$dir") or complainAndQuit("chdir $dir");}# begin modifying $fn; sets these globals:#   $fn      - file name of current file being modified#   $oldfn   - name of file before modifications#   @file    - array of file's contents, one line per array entrysub beginModifying {  ($fn) = @_;     # fn is global

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -