root/fwknop/tags/fwknop-1.8.2-pre5/install.pl

Revision 725, 53.7 kB (checked in by mbr, 1 year ago)

minor typo fix

  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
Line 
1 #!/usr/bin/perl -w
2 #
3 #############################################################################
4 #
5 # File: install.pl
6 #
7 # URL: http://www.cipherdyne.org/fwknop
8 #
9 # Purpose: Installer for fwknop
10 #
11 # Credits:  (see the CREDITS file)
12 #
13 # Copyright (C) 2004-2007 Michael Rash (mbr@cipherdyne.org)
14 #
15 # License (GNU Public License):
16 #
17 #    This program is distributed in the hope that it will be useful,
18 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
19 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 #    GNU General Public License for more details.
21 #
22 #    You should have received a copy of the GNU General Public License
23 #    along with this program; if not, write to the Free Software
24 #    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
25 #    USA
26 #
27 #############################################################################
28 #
29 # $Id$
30 #
31
32 use Cwd;
33 use File::Copy;
34 use File::Path;
35 use Getopt::Long;
36 use Sys::Hostname;
37 use strict;
38
39 #========================== config ===========================
40 my $INIT_DIR    = '/etc/init.d';
41 my $USRBIN_DIR  = '/usr/bin';
42 my $URRSBIN_DIR = '/usr/sbin';
43
44 my $RUNLEVEL;    ### This should only be set if install.pl
45                  ### cannot determine the correct runlevel
46
47 ### only used it $ENV{'HOME'} is not set for some reason
48 my $config_homedir = '';
49
50 my $fwknop_conf_file = 'fwknop.conf';
51
52 ### system binaries
53 my $chkconfigCmd = '/sbin/chkconfig';
54 my $rcupdateCmd  = '/sbin/rc-update'### Gentoo
55 my $makeCmd      = '/usr/bin/make';
56 my $perlCmd      = '/usr/bin/perl';
57 my $gzipCmd      = '/bin/gzip';
58 my $killallCmd   = '/usr/bin/killall';
59 my $mknodCmd     = '/bin/mknod';
60 my $ifconfigCmd  = '/sbin/ifconfig';
61 #======================== end config =========================
62
63 ### main configuration hash
64 my %config = ();
65
66 my $client_install = 0;
67 my $bsd_install    = 0;
68 my $osx_install    = 0;
69 my $cygwin_install = 0;
70 my $homedir = '';
71 my $distro  = '';
72 my $print_help  = 0;
73 my $uninstall   = 0;
74 my $syslog_conf = '';
75 my $data_method = '';
76 my $runlevel;
77 my $force_install_re  = '';
78 my $force_path_update = 0;
79 my $cmdline_force_install = 0;
80 my $skip_module_install   = 0;
81 my $force_defaults = 0;
82
83 my %exclude_cmds = (
84     'mail'        => '',
85     'fwknop'      => '',
86     'fwknopd'     => '',
87     'fwknop_serv' => '',
88     'knopmd'      => '',
89     'knoptm'      => '',
90     'knopwatchd'  => '',
91 );
92
93 ### perl module directories
94 my @required_perl_modules = (
95     {   'module'              =>'Class::MethodMaker', ### GnuPG::Interface dependency
96         'force-install'       => 0,
97         'client-mode-install' => 1,
98         'mod-dir'             => 'Class-MethodMaker'
99     },
100     {   'module'              => 'GnuPG::Interface',
101         'force-install'       => 0,
102         'client-mode-install' => 1,
103         'mod-dir'             => 'GnuPG-Interface'
104     },
105     {   'module'              => 'Unix::Syslog',
106         'force-install'       => 0,
107         'client-mode-install' => 0,
108         'mod-dir'             => 'Unix-Syslog'
109     },
110     {   'module'              => 'Net::IPv4Addr',
111         'force-install'       => 0,
112         'client-mode-install' => 1,
113         'mod-dir'             => 'Net-IPv4Addr'
114     },
115     {   'module'              => 'Net::Pcap',
116         'force-install'       => 0,
117         'client-mode-install' => 0,
118         'mod-dir'             => 'Net-Pcap'
119     },
120     {   'module'              => 'List::MoreUtils'### Net::RawIP dependency
121         'force-install'       => 0,
122         'client-mode-install' => 1,
123         'mod-dir'             => 'List-MoreUtils'
124     },
125     {   'module'              => 'Net::RawIP',
126         'force-install'       => 0,
127         'client-mode-install' => 1,
128         'mod-dir'             => 'Net-RawIP'
129     },
130     {   'module'              => 'Net::Ping::External',
131         'force-install'       => 0,
132         'client-mode-install' => 1,
133         'mod-dir'             => 'Net-Ping-External'
134     },
135     {   'module'              => 'Crypt::Rijndael',
136         'force-install'       => 0,
137         'client-mode-install' => 1,
138         'mod-dir'             => 'Crypt-Rijndael'
139     },
140     {   'module'              => 'Crypt::CBC',
141         'force-install'       => 0,
142         'client-mode-install' => 1,
143         'mod-dir'             => 'Crypt-CBC'
144     },
145     {   'module'              => 'Term::ReadKey',
146         'force-install'       => 0,
147         'client-mode-install' => 1,
148         'mod-dir'             => 'TermReadKey'
149     },
150     {   'module'              => 'IPTables::Parse',
151         'force-install'       => 1,
152         'client-mode-install' => 0,
153         'mod-dir'             => 'IPTables-Parse'
154     },
155     {   'module'              => 'IPTables::ChainMgr',
156         'force-install'       => 1,
157         'client-mode-install' => 0,
158         'mod-dir'             => 'IPTables-ChainMgr'
159     }
160 );
161
162 my %cmds = (
163     'make'     => $makeCmd,
164     'perl'     => $perlCmd,
165     'gzip'     => $gzipCmd,
166     'killall'  => $killallCmd,
167     'mknod'    => $mknodCmd,
168     'ifconfig' => $ifconfigCmd,
169 );
170
171 my @cmd_search_paths = qw(
172     /bin
173     /sbin
174     /usr/bin
175     /usr/sbin
176     /usr/local/bin
177     /usr/local/sbin
178 );
179
180 ### for user answers
181 my $ACCEPT_YES_DEFAULT = 1;
182 my $ACCEPT_NO_DEFAULT  = 2;
183 my $NO_ANS_DEFAULT     = 0;
184
185 ### make Getopts case sensitive
186 Getopt::Long::Configure('no_ignore_case');
187
188 &usage(1) unless (GetOptions(
189     'force-mod-install' => \$cmdline_force_install,  ### force install of all modules
190     'Force-mod-regex=s' => \$force_install_re, ### force specific mod install with regex
191     'Skip-mod-install'  => \$skip_module_install,
192     'Cygwin-install'    => \$cygwin_install,
193     'BSD-install'   => \$bsd_install,
194     'Defaults'      => \$force_defaults,
195     'client-only'   => \$client_install, # Force client-only installation
196     'path-update'   => \$force_path_update,
197     'uninstall'     => \$uninstall,      # Uninstall fwknop.
198     'syslog-conf=s' => \$syslog_conf,    # Specify path to syslog config file.
199     'help'          => \$print_help      # Display help.
200 ));
201 &usage(0) if $print_help;
202
203 if ($bsd_install and $cygwin_install) {
204     die "[*] Cannot use --BSD-install and --Cygwin-install at the same time.";
205 }
206
207 ### import paths from default fwknopd.conf
208 &import_config();
209
210 ### check to see if we are installing on an ipfw system (freebsd, etc.)
211 if (&is_ipfw()) {
212
213     print
214 "[+] It looks like you are installing fwknop on a *BSD system. Installation\n",
215 "    of iptables perl modules will be skipped.\n";
216     $bsd_install = 1;
217
218 } elsif (&is_cygwin()) { ### check to see if we are installing on Cygwin
219
220     print
221 "[+] It looks like you are installing fwknop in a Cygwin environment, so the\n",
222 "    fwknop client will be installed (the fwknopd server does not yet\n",
223 "    function with a Windows-based firewall).\n\n";
224
225     $client_install = 1;
226
227 }
228
229 ### check to see if we are installing as a non-root user
230 &check_non_root_user() unless $client_install;
231
232 if ($client_install) {
233
234     ### we are installing as a normal user instead of root, so see
235     ### if it is ok to install within the user's home directory
236     $homedir = '';
237     if ($config_homedir) {
238         $homedir = $config_homedir;
239     } else {
240         $homedir = $ENV{'HOME'} or die '[*] Could not get home ',
241             "directory, set the $config_homedir var.";
242     }
243
244     print
245 "    The fwknop client will be installed at $homedir/bin/fwknop, and a few\n",
246 "    perl modules needed by fwknop will be installed in $homedir/lib/fwknop/.\n\n",
247
248     $config{'FWKNOP_MOD_DIR'} = "$homedir/lib/fwknop";
249     $USRBIN_DIR = "$homedir/bin";
250
251 } else {
252
253     unless ($bsd_install) {
254
255         $distro = &get_distro();
256
257         if ($distro eq 'redhat' or $distro eq 'fedora') {
258             ### add chkconfig only if we are runing on a redhat distro
259             $cmds{'chkconfig'} = $chkconfigCmd;
260         } elsif ($distro eq 'gentoo') {
261             ### add rc-update if we are running on a gentoo distro
262             $cmds{'rc-update'} = $rcupdateCmd;
263         }
264     }
265 }
266
267 ### make sure the system binaries are where we expect
268 ### them to be.
269 &check_commands();
270
271 my $hostname = hostname();
272
273 my $src_dir = getcwd() or die "[*] Could not get current working directory.";
274
275 if (not $uninstall) {
276     &install();
277 } else {
278     &uninstall();
279 }
280 exit 0;
281 #======================= end main ==========================
282
283 sub install() {
284     print "[+] Installing fwknop on $hostname\n";
285
286     my $preserve_rv = 0;
287     unless ($client_install) {
288         if (&ask_to_stop_fwknop()) {
289             &stop_fwknop();
290         }
291
292         for my $dir qw| /usr/lib /var/run /var/log /var/lib | {
293             unless (-d $dir) {
294                 mkdir $dir or die "[*] Could not mkdir $dir: $!";
295             }
296         }
297         unless (-d $URRSBIN_DIR) {
298             mkdir $URRSBIN_DIR or die "[*] Could not mkdir $URRSBIN_DIR: $!";
299         }
300         for my $dir qw/FWKNOP_RUN_DIR FWKNOP_LIB_DIR FWKNOP_MOD_DIR/ {
301             unless (-d $config{$dir}) {
302                 mkdir $config{$dir} or
303                     die "[*] Could not mkdir $config{$dir}: $!";
304             }
305         }
306     }
307     unless (-d $USRBIN_DIR) {
308         print "[+] Creating: $USRBIN_DIR\n";
309         mkdir $USRBIN_DIR or die "[*] Could not mkdir $USRBIN_DIR: $!";
310     }
311
312     ### config directory
313     unless ($client_install) {
314         if (-d $config{'FWKNOP_CONF_DIR'}) {
315             print "[-] Config directory ",
316                 "$config{'FWKNOP_CONF_DIR'} already exists.\n";
317         } else {
318             ### Note that root will only be able to view files in
319             ### /etc/fwknop since fwknop only needs to view fwknop.conf
320             ### when being run as a daemon.
321             print "[+] Creating config directory: ",
322                 "$config{'FWKNOP_CONF_DIR'}\n";
323             mkdir $config{'FWKNOP_CONF_DIR'}, 0500
324                 or die "[*] Could not mkdir $config{'FWKNOP_CONF_DIR'}: $!";
325         }
326
327         if (-d $config{'FWKNOP_DIR'}) {
328             print "[-] Cache directory $config{'FWKNOP_DIR'} already exists.\n";
329         } else {
330             print "[+] Creating cache directory: $config{'FWKNOP_DIR'}\n";
331             mkdir $config{'FWKNOP_DIR'}, 0500
332                 or die "[*] Could not mkdir $config{'FWKNOP_DIR'}: $!";
333         }
334
335         ### archive directory for previously installed config files
336         if (-d "$config{'FWKNOP_CONF_DIR'}/archive") {
337             print "[-] Archive directory ",
338                 "$config{'FWKNOP_CONF_DIR'}/archive already exists.\n";
339         } else {
340             print "[+] Creating config{'FWKNOP_CONF_DIR'}/archive ",
341                 "directory: $config{'FWKNOP_CONF_DIR'}/archive\n";
342             mkdir "$config{'FWKNOP_CONF_DIR'}/archive", 0500 or die
343                 "[*] Could not mkdir $config{'FWKNOP_CONF_DIR'}/archive: $!";
344         }
345     }
346
347     print "[+] Several perl modules needed by fwknop will be installed in\n",
348         "    $config{'FWKNOP_MOD_DIR'}. Installing them here will keep the ",
349         "system perl\n    library tree clean.\n";
350
351     ### make our library directory (for perl modules)
352     if ($client_install) {
353         if (-d "$homedir/lib") {
354             print "[-] Directory $homedir/lib already exists.\n";
355         } else {
356             print "[+] Creating directory $homedir/lib\n";
357             mkdir "$homedir/lib", 0755
358                 or die "[*] Could not mkdir $homedir/lib: $!";
359         }
360     }
361     if (-d $config{'FWKNOP_MOD_DIR'}) {
362         print "[-] Lib directory $config{'FWKNOP_MOD_DIR'} already exists.\n";
363     } else {
364         print "[+] Creating directory $config{'FWKNOP_MOD_DIR'}\n";
365         mkdir $config{'FWKNOP_MOD_DIR'}, 0755
366             or die "[*] Could not mkdir $config{'FWKNOP_MOD_DIR'}: $!";
367     }
368
369     ### install perl modules
370     unless ($skip_module_install) {
371         for my $mod_href (@required_perl_modules) {
372             &install_perl_module($mod_href);
373         }
374     }
375
376     ### special case the NetPacket::<proto> modules since the NetPacket
377     ### directory is just for the base class, and we need to make sure
378     ### we have each of the NetPacket::IP, NetPacket::ICMP, NetPacket::UDP,
379     ### and NetPacket::TCP modules.
380     unless ($skip_module_install or $client_install) {
381         chdir 'NetPacket' or die "[*] Could not chdir NetPacket directory: $!";
382         unless (-e 'Makefile.PL') {
383             die "[*] Your NetPacket source directory appears to be incomplete!\n",
384                 "    Download the latest sources from ",
385                 "http://www.cipherdyne.org\n";
386         }
387         system "$cmds{'make'} clean" if -e 'Makefile';
388         system "$cmds{'perl'} Makefile.PL PREFIX=$config{'FWKNOP_MOD_DIR'} " .
389             "LIB=$config{'FWKNOP_MOD_DIR'}";
390         system $cmds{'make'};
391 #        system "$cmds{'make'} test";
392         system "$cmds{'make'} install";
393         chdir $src_dir or die "[*] Could not chdir $src_dir: $!";
394     }
395
396     unless ($client_install) {
397
398         ### install man pages
399         &install_manpage('knopmd.8');
400         &install_manpage('knopwatchd.8');
401         &install_manpage('fwknop.8');
402         &install_manpage('fwknopd.8');
403
404         if (-e "$config{'FWKNOP_CONF_DIR'}/fwknop.conf") {
405             $preserve_rv = &query_preserve_config();
406         }
407
408         print "[+] Compiling knopmd and knopwatchd daemons:\n";
409
410         ### remove any previously compiled knopmd
411         unlink 'knopmd' if -e 'knopmd';
412
413         ### remove any previously compiled knopwatchd
414         unlink 'knopwatchd' if -e 'knopwatchd';
415
416         ### compile the C fwknop daemons
417         system $cmds{'make'};
418
419         unless (-e 'knopmd' and -e 'knopwatchd') {
420             die "[*] Compilation failed.";
421         }
422
423         ### install fwknop server-side daemons/programs
424         for my $daemon qw(fwknopd knopmd knopwatchd knoptm fwknop_serv) {
425             if ($daemon eq 'fwknopd' or $daemon eq 'knoptm') {
426                 unless (((system "$cmds{'perl'} -c $daemon")>>8) == 0) {
427                     die "[*] $daemon does not compile with \"perl -c\".  ",
428                         "Download the latest sources ",
429                         "from:\n\nhttp://www.cipherdyne.org/\n";
430                 }
431             }
432             print "[+] Copying $daemon -> $URRSBIN_DIR\n";
433             copy $daemon, $URRSBIN_DIR or
434                 die "[*] Could not cp $daemon to $URRSBIN_DIR: $!";
435             chmod 0500, "$URRSBIN_DIR/$daemon" or
436                 die "[*] Could not chmod 500 $URRSBIN_DIR/$daemon: $!";
437         }
438     }
439
440     print "[+] Copying fwknop -> $USRBIN_DIR\n";
441     copy 'fwknop', $USRBIN_DIR or
442         die "[*] Could not cp fwknop to $USRBIN_DIR: $!";
443
444     if ($client_install) {
445         open F, "< $USRBIN_DIR/fwknop" or die "[*] Could not open ",
446             "$USRBIN_DIR/fwknop: $!";
447         my @lines = <F>;
448         close F;
449         open P, "> $USRBIN_DIR/fwknop.tmp" or die "[*] Could not open ",
450             "$USRBIN_DIR/fwknop.tmp: $!";
451         for my $line (@lines) {
452             ### change the lib dir to new homedir path
453             if ($line =~ m|^\s*use\s+lib\s+\'/usr/lib/fwknop\';|) {
454                 print P "use lib '", $config{'FWKNOP_MOD_DIR'}, "';\n";
455             } else {
456                 print P $line;
457             }
458         }
459         close P;
460         move "$USRBIN_DIR/fwknop.tmp", "$USRBIN_DIR/fwknop" or die "[*] Could ",
461             "not move $USRBIN_DIR/fwknop.tmp -> $USRBIN_DIR/fwknop: $!";
462         chmod 0700, "$USRBIN_DIR/fwknop" or
463             die "[*] Could not chmod 755 $USRBIN_DIR/fwknop: $!";
464     } else {
465         chmod 0755, "$USRBIN_DIR/fwknop" or
466             die "[*] Could not chmod 755 $USRBIN_DIR/fwknop: $!";
467     }
468
469     unless (((system "$cmds{'perl'} -c $USRBIN_DIR/fwknop")>>8) == 0) {
470         die "[*] $USRBIN_DIR/fwknop does not compile with \"perl -c\".  ",
471             "Download the latest sources ",
472             "from:\n\nhttp://www.cipherdyne.org/\n";
473     }
474
475
476     if ($client_install) {
477         print
478 "\n[+] fwknop has been installed at $USRBIN_DIR/fwknop.  Since this is a\n",
479 "    client-only install, the man pages could not be installed.  For more\n",
480 "    information about how to use fwknop, execute \"$USRBIN_DIR/fwknop -h\" or\n",
481 "    refer to:\n\n",
482 "        http://www.cipherdyne.org/fwknop/docs/manpages/index.html\n\n";
483
484     } else {
485
486         ### install config and access files
487         for my $file qw(fwknop.conf access.conf pf.os) {
488             if (-e "$config{'FWKNOP_CONF_DIR'}/$file") {
489                 &archive("$config{'FWKNOP_CONF_DIR'}/$file");
490                 if ($preserve_rv) {
491                     if ($file eq 'access.conf') {
492                         ### access.conf can have missing fields (i.e.
493                         ### REQUIRE_OS_REGEX and REQUIRE_USERNAME),
494                         ### and also it can have multiple sequences
495                         ### defined.  Hence we just use the old one.
496                         print "[+] Using original access.conf\n";
497                     } elsif ($file ne 'pf.os') {
498                         &preserve_config($file);
499                     }
500                 } else {
501                     print "[+] Copying $file -> $config{'FWKNOP_CONF_DIR'}\n";
502                     copy $file, $config{'FWKNOP_CONF_DIR'} or
503                         die "[*] Could not cp $file to $config{'FWKNOP_CONF_DIR'}";
504                 }
505             } else {
506                 print "[+] Copying $file -> $config{'FWKNOP_CONF_DIR'}\n";
507                 copy $file, $config{'FWKNOP_CONF_DIR'} or
508                     die "[*] Could not cp $file to $config{'FWKNOP_CONF_DIR'}";
509             }
510
511             if ($force_path_update or not $preserve_rv) {
512                 &update_command_paths("$config{'FWKNOP_CONF_DIR'}/$file")
513                     if ($file eq 'fwknop.conf');
514             }
515
516             if ($file eq 'fwknop.conf') {
517                 &set_hostname("$config{'FWKNOP_CONF_DIR'}/$file");
518             }
519             chmod 0600, "$config{'FWKNOP_CONF_DIR'}/$file" or die
520                 "[*] Could not chmod(600, $config{'FWKNOP_CONF_DIR'}/$file: $!";
521             chown 0, 0, "$config{'FWKNOP_CONF_DIR'}/$file" or die
522                 "[*] Could not chown 0,0, $config{'FWKNOP_CONF_DIR'}/$file: $!";
523         }
524
525         ### get data acquisition method (e.g. syslogd, sysylog-ng, ulogd
526         ### or pcap)
527         $data_method = &query_data_method();
528
529         if ($data_method =~ /syslog/) {
530
531             ### create the named pipe
532             unless (-e $config{'KNOPMD_FIFO'} and -p $config{'KNOPMD_FIFO'}) {
533                 unlink $config{'KNOPMD_FIFO'} if -e $config{'KNOPMD_FIFO'};
534                 print "[+] Creating named pipe $config{'KNOPMD_FIFO'}\n";
535                 my $created_pipe = 1;
536                 unless (((system "$cmds{'mknod'} -m 600 $config{'KNOPMD_FIFO'} p")>>8)
537                         == 0) {
538                     $created_pipe = 0;
539                 }
540                 unless (-e $config{'KNOPMD_FIFO'} and -p $config{'KNOPMD_FIFO'}) {
541                     $created_pipe = 0;
542                 }
543                 unless ($created_pipe) {
544                     die
545 "[*] Could not create the named pipe \"$config{'KNOPMD_FIFO'}\"!\n",
546 "[*] fwknop requires this file to exist!  Aborting install.\n";
547                 }
548             }
549
550             unless (-e "$config{'FW_DATA_FILE'}") {
551                 print "[+] Creating $config{'FW_DATA_FILE'} file\n";
552                 open F, "> $config{'FW_DATA_FILE'}" or die "[*] Could not open ",
553                     "$config{'FW_DATA_FILE'}: $!";
554                 close F;
555                 chmod 0600, "$config{'FW_DATA_FILE'}";
556                 &perms_ownership("$config{'FW_DATA_FILE'}", 0600);
557             }
558
559             ### we are acquiring data via syslog
560             &put_string('AUTH_MODE', 'KNOCK',
561                 "$config{'FWKNOP_CONF_DIR'}/fwknop.conf");
562
563             if ($bsd_install) {
564                 ### update to use the ipfw firewall on *BSD systems
565                 &put_string('FIREWALL_TYPE', 'ipfw',
566                     "$config{'FWKNOP_CONF_DIR'}/fwknop.conf");
567             }
568
569             &put_string('SYSLOG_DAEMON', $data_method,
570                 "$config{'FWKNOP_CONF_DIR'}/fwknop.conf");
571
572             my $restarted_syslog = 0;
573             if ($data_method eq 'syslogd') {
574                 if (-e $syslog_conf) {
575                     &append_fifo_syslog($syslog_conf);
576                     if (((system "$cmds{'killall'} -HUP syslogd " .
577                             "2> /dev/null")>>8) == 0) {
578                         print "[+] HUP signal sent to syslogd.\n";
579                         $restarted_syslog = 1;
580                     }
581                 }
582             } elsif ($data_method eq 'syslog-ng') {
583                 if (-e $syslog_conf) {
584                     &append_fifo_syslog_ng($syslog_conf);
585                     if (((system "$cmds{'killall'} -HUP syslog-ng " .
586                             "2> /dev/null")>>8) == 0) {
587                         print "[+] HUP signal sent to syslog-ng.\n";
588                         $restarted_syslog = 1;
589                     }
590                 }
591             }
592
593             unless ($restarted_syslog) {
594                 print "[-] Could not restart any syslog daemons.\n";
595             }
596         } elsif ($data_method =~ /pcap/i or $data_method =~ /ulog/i) {
597
598             if ($bsd_install) {
599                 ### update to use the ipfw firewall on *BSD systems
600                 &put_string('FIREWALL_TYPE', 'ipfw',
601                     "$config{'FWKNOP_CONF_DIR'}/fwknop.conf");
602             }
603
604             ### we are using a pcap method
605             if ($data_method eq 'ulogd' or $data_method eq 'file_pcap') {
606                 print
607 "[+] By default, fwknop uses the file /var/log/sniff.pcap in order to\n",
608 "    acquire packet data logged via a sniffer (or ulogd) to a pcap file,\n",
609 "    but this path may be changed by altering the PCAP_PKT_FILE keyword\n",
610 "    in $config{'FWKNOP_CONF_DIR'}/fwknop.conf.\n\n";
611
612                 if ($data_method eq 'file_pcap') {
613                     &put_string('AUTH_MODE', 'FILE_PCAP',
614                         "$config{'FWKNOP_CONF_DIR'}/fwknop.conf");
615                 } else {
616                     &put_string('AUTH_MODE', 'ULOG_PCAP',
617                         "$config{'FWKNOP_CONF_DIR'}/fwknop.conf");
618                 }
619             } else {
620                 my $intf = &get_pcap_intf();
621                 if ($intf) {
622                     &put_string('PCAP_INTF', $intf,
623                         "$config{'FWKNOP_CONF_DIR'}/fwknop.conf");
624                 } else {
625 print "[-] Could not get sniffing interface, need to set this manually in\n",
626     "    config{'FWKNOP_CONF_DIR'}/fwknop.conf\n";
627                 }
628             }
629         } else {
630             ### it is a client-only install, so don't reconfigure syslog
631             ### or anything.
632         }
633
634         unless ($preserve_rv) {
635             my $email_str = &query_email();
636             if ($email_str) {
637                 for my $file qw(fwknop.conf) {
638                     &put_string('EMAIL_ADDRESSES', $email_str,
639                         "$config{'FWKNOP_CONF_DIR'}/$file");
640                 }
641             }
642         }
643
644         &get_init_dir();
645
646         if (-d $INIT_DIR) {
647             &enable_fwknop_at_boot($distro) unless $data_method =~ /client/i;
648         }
649
650         if ($data_method =~ /client/i) {
651             print "\n[+] fwknop has been installed!\n\n";
652         } else {
653             print
654 "\n[+] fwknop has been installed!  To start in server mode, run\n\n",
655 "    \"/etc/init.d/fwknop start\"\n\n",
656 "    Note: You will need to edit $config{'FWKNOP_CONF_DIR'}/access.conf for fwknop to\n",
657 "    function properly in server mode.  More information can be found in\n",
658 "    the fwknop manpage.\n\n";
659             if ($bsd_install) {
660                 print
661 "    You may need to update your /etc/syslog.conf file to log local info\n",
662 "    messages to a file in the /var/log/ directory in order to see syslog\n",
663 "    messages from the fwknop daemons.\n\n";
664             }
665         }
666
667     }
668     return;
669 }
670
671 sub uninstall() {
672
673     print "[+] Uninstalling fwknop\n";
674
675     ### stop any running fwknop daemons.
676     &stop_fwknop();
677
678     ### get the init directory
679     &get_init_dir();
680
681     unlink "$USRBIN_DIR/fwknop" if -e "$USRBIN_DIR/fwknop";
682     unlink "$URRSBIN_DIR/knopmd" if -e "$URRSBIN_DIR/knopmd";
683     unlink "$URRSBIN_DIR/knopwatchd" if -e "$URRSBIN_DIR/knopwatchd";
684     unlink "$INIT_DIR/fwknop" if -e "$INIT_DIR/fwknop";
685     rmtree $config{'FWKNOP_CONF_DIR'}, 1, 1 if -d $config{'FWKNOP_CONF_DIR'};
686     rmtree $config{'FWKNOP_LIB_DIR'}, 1, 1 if -d $config{'FWKNOP_LIB_DIR'};
687     rmtree $config{'FWKNOP_MOD_DIR'}, 1, 1 if -d $config{'FWKNOP_MOD_DIR'};
688
689     return;
690 }
691
692 sub get_init_dir() {
693     return if $client_install;
694
695     if ($osx_install) {
696         $INIT_DIR = '/Libraries/'### FIXME
697         return;
698     }
699
700     unless (-d $INIT_DIR) {
701         if (-d '/etc/rc.d/init.d') {
702             $INIT_DIR = '/etc/rc.d/init.d';
703         } elsif (-d '/etc/rc.d') {  ### for Slackware
704             $INIT_DIR = '/etc/rc.d';
705         } elsif (-d '/etc/init.d') {
706             $INIT_DIR = '/etc/init.d';
707         } else {
708             die "[*] Cannot find the init script directory, edit ",
709                 "the \$INIT_DIR variable.\n";
710         }
711     }
712     return;
713 }
714
715 ### check paths to commands and attempt to correct if any are wrong.
716 sub check_commands() {
717
718     return if $client_install;
719
720     unless ($bsd_install) {
721         $exclude_cmds{'ipfw'} = '';
722     }
723
724     CMD: for my $cmd (keys %cmds) {
725         if ($bsd_install) {
726             next CMD if $cmd eq 'iptables';
727         }
728         next CMD if defined $exclude_cmds{$cmd};
729         unless (-x $cmds{$cmd}) {
730             my $found = 0;
731             PATH: for my $dir (@cmd_search_paths) {
732                 if (-x "${dir}/${cmd}") {
733                     $cmds{$cmd} = "${dir}/${cmd}";
734                     $found = 1;
735                     last PATH;
736                 }
737             }
738             unless ($found) {
739                 die "[*] Could not find $cmd anywhere!!!  ",
740                     "Please edit the config section to include the path to ",
741                     "$cmd.\n";
742             }
743         }
744         unless (-x $cmds{$cmd}) {
745             die "[*] $cmd is located at ",
746                 "$cmds{$cmd} but is not executable by uid: $<\n";
747         }
748     }
749     return;
750