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

📄 install.pl

📁 伯克利做的SFTP安全文件传输协议
💻 PL
📖 第 1 页 / 共 3 页
字号:
#!/usr/bin/perl -w# SafeTP install script# assumptions:#   run as root#   binaries already available#   safetp user already created# version history:#   1.21    made root check not a state, but always performed#           removed partial test#           added -noninter flag for easier testing (and#             *possibly* useful for unattended installs, if the#             defaults are *all* correct)#   1.20    switching to interactive prompting instead of forcing#           the user to edit the script itself, lots of other #           general improvements#   1.11b   working on a check for brace expansion functionality#           fixed troublshooting reference (trouble.txt)#   1.11    added more support for keeping keys across upgrades#             (the intent was never that people would re-run the install#             script for an upgrade, just replace binaries.. maybe should#             have an upgrade script..?)#           fixed some problems with the way the test programs were run,#             specifically, eliminating use of 'su' (since I usually run#             with no shell for the 'safetp' user)#   1.10    rewritten in perl (was in csh), with (at least) these benefits:#             - eliminated need for helper scripts (is self-contained now)#             - improved config-file modification by using Perl's internal#               pattern matching and string substitution mechanisms, and#               ability to do all editing in-memory (eliminating error-prone#               tmp1/tmp2 game)#             - improved error handling#             - easier maintenance, due to language superiority over csh#             - other benefits of being able to define subroutines.. :)#           removed stuff about -3, since it's unnecessary now#           added -9 to the default options list#   1.02    corrected/improved some of the comments below#           updated sftpc syntax for 1.20 sftpc, inc. -X#           removed now-redundant ^D eat-extra stuff#   1.01    added ability to not simply co-opt ftp's port, for krb5 compat.#   1.00    all previous..use strict 'subs';   # disallow barewordsuse English;         # mnemonics for things like EUID# subroutines (all defined & documented at end of file)sub processCommandLineOptions;sub readSavedAnswers;sub appendState;sub forgetLastAnswer;sub firstLine;sub pval;sub runDontDie;sub run;sub complainAndQuit;sub printStackTrace;sub cd;sub beginModifying;sub finishModifying;sub appendUninstall;sub appendToFile;sub prependUninstall;sub hupInetdOrAskUser;sub hupInetd;sub getAllProcesses;sub getAllProcessesInner;sub doUninstall;sub readFile;sub writeFile;sub packageCmd;sub appendUninstallCmd;sub prependUninstallCmd;sub makeSymlink;sub askStringQuestion;sub askQuestionNotSaved;sub askBooleanQuestion;sub startSection;sub endSection;sub dropRoot;sub resumeRoot;sub diagnostic;# ------------------ script-wide globals -------------# directory for storing install state files$work_dir = "/etc/safetp";# file for recording script state$state_file = "$work_dir/safetp_install_state";# name of the uninstall script commands$uninstall_file = "$work_dir/uninstall.cmds";# names of system files to modify$etc_services = "/etc/services";$etc_inetd_conf = "/etc/inetd.conf";$etc_motd = "/etc/motd";# some systems don't have this file$has_etc_motd = (-f "/etc/motd");# assume we will not be doing a dry run$dry_run = 0;# but if we do, we will use this directory to play in$drydir = "/tmp/dry";# and don't start in debug mode$debug_mode = 0;# when true, we avoid anything that would require an# interactive response$noninteractive = 0;# ----------------- preliminaries -----------------------getHostType();# do before acting on $work_dir since we might change itprocessCommandLineOptions();# test for being root (right after cmdline, since it is there# we might set $dry_run)if ($EUID != 0 && !$dry_run) {  # $EUID is effective user id, 0 is user id of root  die "You must be root to install the SafeTP daemon.\n";}mkdirIfNotAlready($work_dir);readSavedAnswers();# ------------------ question and answer ---------------------# now, we ask the user a bunch of questions.  if the user has# already answered some of them, they won't be asked again## first tell the user what's going to happen#$message = <<EOF;Welcome to the SafeTP install script.You should already have done these things:  - compiled the binaries; see compile.txt  - created a user for sftpd to run as, such as "safetp"  - became root to run this scriptIf you have not done these things, stop now, read install.txt,and come back later.First, I will ask you a bunch of questions.  For most of them, if notall, the default answer will be fine; just hit Enter.  Otherwise, entera different value and press Enter.If you make a mistake, use ^C to quit the script.  The answers you havegiven so far, including default answers, are stored in$state_file; delete this file to start over.After the questions I will begin the install itself.  If something goeswrong I will stop.  When you fix whatever is wrong, simply re-start thescript, and it will resume by trying the last thing that failed.EOF$proceed = askBooleanQuestion("$message\nAre you ready to begin? ", 1);if (!$proceed) {  forgetLastAnswer();  exit();}## this is the user on whose behalf the sftpd daemon will run# (and the user that will have ownership of the daemon files)#$daemon_user = askStringQuestion(  "What is the name of the user that\nsftpd should run as? ",  $dry_run? firstLine(`whoami`) : "safetp");if (!getpwnam($daemon_user)) {  print("I don't see user `$daemon_user' in the passwd file; that should\n",        "be fixed first.  Perhaps you should say 'useradd $daemon_user'.\n");  forgetLastAnswer();  exit();}## grab stuff from passwd file#($_, $_, $daemon_uid, $daemon_gid, $_, $_, $_, $daemon_home) =  getpwnam($daemon_user);($daemon_group) = getgrgid($daemon_gid);if (!getgrnam($daemon_group)) {  print("I don't see group `$daemon_group' in the group file; that should\n",        "be fixed first.\n");  forgetLastAnswer();  exit();}## This string will appear in the DSA public key, and ftp users# will see it upon connection.  The name should be something# users will recognize.  Comment this out to get the normal# interactive prompt from 'makekeys'.#$hostname = getFQDN();$branding_string = askStringQuestion(  "Your DSA public key will include a descriptive name, called its\n" .  "\"brand\", that users will see when they connect to your server.\n" .  "This string should be something users will recognize.  What brand\n" .  "would you like? ",  "SafeTP at $hostname");## this is where the pre-built binaries are.  the needed binaries are:#   sftpc        - SafeTP unix client#   sftpd        - SafeTP daemon itself#   makekeys     - program to generate ElGamal (client) and DSA (server) keys#   viewkey      - program to base64 a binary key file#   addent       - entropy-gathering tool#$binary_source = askStringQuestion(  "Where are the SafeTP binaries, such as 'sftpd',\nlocated now? ",  ".");if (! -f "${binary_source}/sftpd") {  print("I don't see 'sftpd' in '$binary_source'.\n");  forgetLastAnswer();  exit();}## this is where the binaries will be placed, where inetd# will find them; ideally, this is on the local machine#$binary_dest = askStringQuestion(  "Where should the SafeTP binaries be placed for ongoing use?  Since\n" .  "many network file system protocols, such as NFS, are insecure, this\n" .  "should be on the local machine which will run the SafeTP daemon.\n",  $dry_run? $drydir : $daemon_home);## this is where symbolic links to binaries that users will# typically run will be placed#$user_binary_dest = askStringQuestion(  "For user convenience, I can put symlinks to the SafeTP binaries in some\n" .  "conventional place.  Where should I put these symlinks?\n",  $dry_run? "$drydir/links" : "/usr/local/bin");## this is where the server keys will be placed (actually, they# will go into a DSA subdirectory of this directory); this# *really must* be on the local machine (otherwise the private# key is vulnerable while being fetched over the network)#$key_dest = askStringQuestion(  "Where should I put the DSA server keys?  It is imperative that the\n" .  "directory specified here be on the local machine, because if the\n" .  "server keys are sniffed then SafeTP is compromised.  (Note also that\n" .  "you need to think carefully about how/whether these keys are part\n" .  "of any automatic backup procedures.)\n",  $dry_run? $drydir : $daemon_home);## raw (unencrypted) FTP service will be installed on this port#$raw_ftp_port = askStringQuestion(  "To which port should I move the existing FTP daemon?  Since SafeTP uses\n" .  "this daemon, you can't just remove it entirely.  ",  351);## this is the port sftpd will listen to# (if it is desired to install sftpd on a port other than 21,# we recommend 353; the Windows client depends on it using 353)#$sftpd_port = askStringQuestion(  "Which port should SafeTP listen to?  Normally you should make SafeTP\n" .  "listen to port 21, the default FTP port.  However, if for some reason\n" .  "you want it to listen to a different port, 353 is the recommended\n" .  "alternative.  ",  21);## command-line switches to sftpd.  common ones are:#    -pN            listen for incoming connections on port N#    -fN            contact ftpd on port N#    -s             use stdin as control connection (for use with inetd)#    -d1            log diagnostic (debugging) messages#    -9             disallow RFC 959 (unencrypted) connections#    -y<directory>  specify working directory (default is cwd)#    -o             send debug output to log file instead of syslog#    -l<filename>   specify logging file (use with -o)#    -3             disable the 3rd-party transfer optimization# (additional options available: "sftpd -h")# (additional docs: http://safetp.cs.berkeley.edu/sftpd.html)#$sftpd_options = "-f${raw_ftp_port} -s -y${key_dest}";if (!askBooleanQuestion(      "Do you want SafeTP to accept unencrypted connections as well as\n" .      "encrypted connections?  It makes the transition path easier for\n" .      "users but also eliminates the forcing function for them to switch\n" .      "to using SafeTP.  Accept unencrypted?  ",      0)) {  $sftpd_options .= " -9";}$extra_options = askStringQuestion(  "The current argument string to sftpd is:\n" .  "  sftpd $sftpd_options\n" .  "You can enter additional arguments here if you want:\n",  "");$sftpd_options .= " " . $extra_options;## amount of entropy to gather; the default (1024) requires# approximately 200 keystrokes; reduce to suit keymashing# tolerance... (setting it to 0 will effectively add only# the current date/time as the entropy, which is insecure)#$bits_of_entropy = 1024;## length of DSA keys (recommended: 1024)#$dsa_key_len = 1024;## controls whether a full test is performed post-install#$do_full_test = askBooleanQuestion(  "After installing, do a full (interactive) test? ",   $noninteractive? 0 : 1);## Additional parameters to sftpc during the full test (if it# is done at all); the one that makes most sense here, if any,# is "-n", which does protocol negotiation only.  This should be# used after the install works right on one machine, with a real# full test, and it is desired to install on other machines# noninteractively.#   -X   accept new key silently#$sftpc_full_extras = "-X";#$sftpc_full_extras = "-X -n";## if this is 1, we edit /etc/motd to tell users that# a secure FTP server has been installed (some systems# overwrite /etc/motd during boot...)#if ($has_etc_motd) {  $do_edit_motd = askBooleanQuestion(    "After install, should I add a blurb to /etc/motd telling users\n" .    "that SafeTP is installed? ", 1);}else {                # don't modify it if it's not there  $do_edit_motd = 0;}## some sites like to have admins put their login name in a# comment next to config changes; the following string will# be appended to comment strings inserted#$comment_extra = askStringQuestion(  "When I modify system files, I will tag the modifications with the name\n" .  "of the admin responsible.  What tag should I use?\n",  $dry_run? "dry_run" : "");## how to retrieve a list of all processes; only set this if# you have reason to believe that getAllProcesses() (at end# of file) isn't working##$allProcsCmd = "ps aux";# ------------ less-used configuration options ----------------## permissions for various files; see install.txt for summary# of minimum and convenient permissions; the defaults here# are the "convenient" permissions#$binary_dir_perm = "755";$key_dir_perm = "755";$binary_perm = "755";$seed_perm = "600";$key_subdir_perm = "711";$privkey_perm = "600";$pubkey_perm = "644";$pubkeytxt_perm = "644";## length of elgamal keys (used for testing only)#$elgamal_key_len = 1024;## grab a datestamp and timestamp#$datestamp = firstLine(`date +%x`);  die "date failed" if $?;$timestamp = firstLine(`date +%Y.%m.%d.%H.%M.%S`);  die "date failed" if $?;  # ------------- other globals ---------------------## grab two temp file names#$tmp1 = "/tmp/safetp.$$.tmp1";#$tmp2 = "/tmp/safetp.$$.tmp2";    # no longer used..# list of binaries to copy@bins = qw(sftpc sftpd makekeys viewkey addent);# (part of) comment to append to modified lines of config files$comment = "by SafeTP install ${datestamp} ${comment_extra}";# directory where server keys, and client test keys, will be created$ENV{SAFETP_CONFIG} = $key_dest;# A quick note to those who maintain this file:#   It's important to keep in mind that restarting the# install script causes different parts to run with# different ${timestamp} values.  This is why, for example,# an atomic section (like modifying /etc/services) must# go all the way to the point where the uninstall info is# written; breaking it in the middle could break the# uninstall script.# --------------- installation proper ---------------------if (startSection()) {  # start an uninstall script commands file  if (-e "$uninstall_file") {    # move the old one first    run("mv $uninstall_file ${uninstall_file}.${timestamp}");  }  appendUninstall("# this is somewhere in $uninstall_file");  # the uninstall script should remove the state file, even if the  # install only partially succeeded, on the presumption that a  # re-install attempt will follow  appendUninstallCmd("removing install state", "rm $state_file");  endSection("started the uninstall file");}if (startSection()) {  # copy the required binaries  foreach $bin (@bins) {    run("cp ${binary_source}/$bin $binary_dest");    # write uninstall info    prependUninstallCmd("removing $bin", "rm ${binary_dest}/$bin");  }  endSection("copied the binaries to $binary_dest");}if (startSection()) {  # set ownership and permissions  run("chmod $binary_dir_perm $binary_dest",      "chown $daemon_user $binary_dest");  foreach $bin (@bins) {    run("chmod $binary_perm ${binary_dest}/$bin",        "chown $daemon_user ${binary_dest}/$bin",        "chgrp $daemon_group ${binary_dest}/$bin");  }  endSection("set the permissions on the binaries");}if (startSection()) {  # as a convenience during debugging of this script, permit  # an existing randomSeed to be used  if (-e "$key_dest/randomSeed") {    print("${key_dest}/randomSeed already exists, skipping entropy-gathering...\n");  }  elsif ($noninteractive && $dry_run) {      # *only* do this for a dry run; a real install must not be    # allowed to proceed without entropy!    #    # makekeys below will generate the randomSeed file, and    # it won't prompt for entropy because of 3rd arg    print("skipping addent because it's noninteractive dry run\n");  }  else {    # gather entropy    cd("$key_dest");    run("${binary_dest}/addent $bits_of_entropy");    # (no longer have to eat keystrokes, because addent takes care of it)  }  # write uninstall info  #prependUninstallCmd("removing seed", "rm ${key_dest}/randomSeed");  # like the keys, leave the seed  endSection("gathered entropy");}if (startSection()) {

⌨️ 快捷键说明

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