#! /opt/CSCOpx/bin/perl # Copyright (c) 2001, 2002, 2003, 2004 Cisco Systems, Inc. # All rights reserved use CRM; use POSIX; BEGIN { require lib; import lib "$ENV{'NMSROOT'}/lib/perl/install/"; } use InstallUtility; # Check Command Line Arguments chomp($ARGV[0]); if ( @ARGV != 1 ) { print "Usage: ConfigSSL.pl -enable | -disable\n"; exit(1); } if ($ARGV[0] ne "-enable" && $ARGV[0] ne "-disable"){ print "Usage: ConfigSSL.pl -enable | -disable\n"; exit(1); } # Setup platform specific variables Initialize(); $infile="$ENV{NMSROOT}/lib/classpath/ssl.properties"; %value=&GetValues($infile); $temp = $value{"PX_PROTOCOL"}; $proto = $temp; # added for md.properties.tmp manipulation # Date : 12-12-2001 $temp_ssl_port = $value{"PX_SSL_PORT"}; $temp_non_ssl_port = $value{"PX_NON_SSL_PORT"}; $infile1="$ENV{NMSROOT}/lib/classpath/md.properties"; %values1=&GetValues($infile1); $px_md_protocol = $values1{"PX_PROTOCOL"}; #$time = localtime(); $time = POSIX::strftime( "%a %b %d %H:%M:%S %Z %Y", localtime(time)); if ( ($temp =~ /https/) && ($ARGV[0] eq "-enable" ) ) { # if ssl is already enabled #system($SSL_EN); $ret = exec_java ('com.cisco.nm.cmf.ssl.ErrorLoggerAPI', "\"*** $time SSL is already enabled ***\""); change_owner($SSL_LOG); change_perms($SSL_LOG); if ( $px_md_protocol =~ /https/ ) { print "SSL is already enabled\n"; } else { print "SSL is already enabled but Daemon Manager has not been restarted"; } exit(0); } elsif ( ($temp =~ /https/) && ($ARGV[0] eq "-disable") ) { # Check if any other app is ssl mandatory, if so, # terminate with a message. This prevents us from disbling SSL system($SSL_DIS); $exit_value = $? >> 8; if ( $exit_value ){ $str1 = " SSL can not be disabled. Some of the Applications installed are SSL Mandatory.Uninstall those Applications and try again"; $ret = exec_java ('com.cisco.nm.cmf.ssl.ErrorLoggerAPI', "\"*** $time $str1 ***\""); change_owner($SSL_LOG); change_perms($SSL_LOG); exit(1);} else { # disable ssl #system($SSL_DIS); $proto = "http"; $ret = exec_java ('com.cisco.nm.cmf.ssl.ErrorLoggerAPI', "\"*** $time SSL is disabled from CLI ***\""); print "SSL is disabled. Restart Daemon Manager to reflect the changes.\n"; } } elsif ( ($temp eq "http") && ($ARGV[0] eq "-enable") ) { # Chech if any other app is not ssl compliant, if so, # terminate with a message. This prevents us from enabling SSL system($SSL_COM); $exit_value = $? >> 8; if ( $exit_value ){ $str = " SSL can not be enabled. Some of the Applications installed are not SSL compliant. Uninstall those Applications and try again."; $ret = exec_java ('com.cisco.nm.cmf.ssl.ErrorLoggerAPI', "\"*** $time $str ***\""); change_owner($SSL_LOG); change_perms($SSL_LOG); exit(1); } # if ssl not already enabled $ch = check_cert(); if ( $ch == 2 ) { if ( get_option() ) { exit(1); } } elsif ( $ch == 1 ) { $str = "ERROR : Invalid Certificate. SSL cannot be Enabled "; exec_java ('com.cisco.nm.cmf.ssl.ErrorLoggerAPI', "\"*** $time $str ***\""); change_owner($SSL_LOG); change_perms($SSL_LOG); print "$str\n"; exit(1); } $proto = "https"; #$ret = &exec_java ('com.cisco.nm.cmf.ssl.CheckValidity', "cli"); $ret = &exec_java ('com.cisco.nm.cmf.ssl.ErrorLoggerAPI', "\"*** $time SSL is enabled from CLI ***\""); if ( $ch == 2 ) { # New certificate print "The following files have been created for SSL Communication\n\n"; print "1. Server Private Key\n$KEYFILE\n\n"; print "2. Server Certificate (Self Signed)\n$CERTFILE\n\n"; print "3. Certificate Signing Request file\n$CSRFILE\n\n"; print "4. Server Private Key(PKCS#8)\n$PK8FILE\n\n"; print "\nIMPORTANT: Please backup the above files in a secured location\n\n"; print "If you plan to get Certificates from third party CAs,\n"; print "Please refer the Uploading Certificates section in User Guide or Online help.\n\n"; print "It is important that you follow the steps mentioned in the documentation for uploading third party Certificates into CiscoWorks' KeyStore.\n\n"; } print "SSL is enabled. Restart Daemon Manager to reflect the changes.\n"; } elsif ( ($temp eq "http") && ($ARGV[0] eq "-disable") ) { # if ssl is already disabled #system($SSL_DIS); $ret = exec_java ('com.cisco.nm.cmf.ssl.ErrorLoggerAPI', "\"*** $time SSL is already disabled ***\""); change_owner($SSL_LOG); change_perms($SSL_LOG); if ( $px_md_protocol =~ /https/ ) { print "SSL is already disabled but Daemon Manager has not been restarted"; } else { print "SSL is already disabled\n"; } exit(0); } else { print "Usage: ConfigSSL.pl -enable | -disable\n"; exit(1); } # update ssl.properties write_ssl_file( $proto ); # added for md.properties.tmp manipulation # Date : 12-12-2001 # create md.properties.tmp and copy md.properties to md.properties.tmp #fcreate_write($MDPROP, $MDPROP_TMP); #change_owner($MDPROP_TMP); change_owner($SSL_LOG); change_perms($SSL_LOG); #write_md_tmp_file ( $proto, $temp_ssl_port, $temp_non_ssl_port); # For NT, Update md.properties and Registry values for PX_PROTOCOL # PX_PORT, PX_WEB_PORT #if ($CRM::CRM_OS ne "UNIX") #{ #system("$ENV{'NMSROOT'}/bin/perl $ENV{'NMSROOT'}/lib/web/sslnt.pl"); #} # Validate input from stdin, returns 1 if succeeded, else 0; sub validate { # Fix for CSCin16312. Changed validation to allow more chars # and disallow *only* spaces. if ($_[0] !~ /^[A-Za-z0-9\-\._ @\(\):&]+$/) { print "Invalid Entry. Please Enter again.\n"; return 0; } if ($_[0] =~ / +$/) { print "Invalid Entry. Please Enter again.\n"; return 0; } return 1; } # Check file existence in the file system sub isfExists { if ( -e "$_[0]" ) { return 1; } return 0; } # Copy files from one directory to other sub fcreate_write { open ( wSSLFILE, ">$_[1]" ) or die "ERROR: Can not create file ($_[1]) "; open ( rSSLFILE, "<$_[0]" ) or die "ERROR: Can not open file ($_[0]) "; $size = 1024; while ( ($n = sysread (rSSLFILE, $buf, $size)) ) { print wSSLFILE $buf; } close wSSLFILE; close rSSLFILE; } # Validates the existence of server.* files, loop around if any error # in the filename else return the path of the file sub validate_file { while ( 1 ) { print "Enter the directory name for file, $_[0]: "; $scrt = ; chop($scrt); $chopch = chop($scrt); if ( $chopch =~ /\// ) { $scrt = $scrt . '/' . $_[0]; } else { $scrt = $scrt . $chopch . '/' . $_[0]; } if ( ($temp = isfExists( $scrt )) ) { print "\n"; last; } print "ERROR: File $_[0] not found in the directory specified\n($scrt)\n"; } return $scrt; } # GetValues(filename with full path) # Returns hash of Properties and values as key-value pairs sub GetValues { my ($file)= @_; my %props; open(FILE,$file) or die "ERROR: Cannot Open $file"; while() { @val=split("=",$_); chomp($val[0]);chomp($val[1]); $props{$val[0]}=$val[1]; } close(FILE); return %props; } # Update ssl.properties file sub write_ssl_file { my %newPropVals = ( 'PX_PROTOCOL' => $_[0] ); my $propFile = InstallUtility::MakePXFileName('lib/classpath/ssl.properties'); @l = InstallUtility::UpdatePropertyFile($propFile, !0, \%newPropVals); } # added for md.properties.tmp manipulation # Update md.properties.tmp file # Date : 12-12-2001 sub write_md_tmp_file { $temp = $value{"PX_SSL_PORT"}; if ( $_[0] =~ 'https' ) { $temp = $_[1]; } else { $temp = $_[2]; } my %newPropVals = ( 'PX_PROTOCOL' => $_[0], 'PX_PORT' => $temp, 'PX_WEB_PORT' => $temp ); my $propFile = InstallUtility::MakePXFileName('lib/classpath/md.properties.tmp'); @l = InstallUtility::UpdatePropertyFile($propFile, !0, \%newPropVals); } # # Check for the existance of certificates, return value (success : 0, # invalid certificate : 1, no certificate : 2) # sub check_cert { $FileName = $KEYFILE; $temp = isfExists( $FileName ); $FileName = $CERTFILE; $temp_crt = isfExists( $FileName ); $FileName = $PK8FILE; $temp_pk8 = isfExists( $FileName ); if ( $temp && $temp_crt && $temp_pk8 ) { $ret = exec_java ('com.cisco.nm.cmf.ssl.CheckValidity', "$CERTFILE"); $exit_value = $? >> 8; if ( !$ret ) { # valid certificate #system( $SSL_EN ); return 0; } # invalid certificate return 1; } # No certificate found return 2; } # Generate new certificate # sub new_cert { my $i; print "\n*** Running key and certifcate generation utility ***\n"; print "\nPlease enter the following information. It is needed to generate your\n"; print "temporary certificate\n"; while ( 1 ) { print "\nCountry (2 letter code) : "; $country = ; chop($country); if ( length($country) == 2 ) { @temp = split("",$country); for($i=0;$i<@temp;$i++) { if($temp[$i]!~/[A-Za-z]/) { print "Invalid Entry. Please Enter again.\n"; last; } } } elsif ( length($country) == 0 ) { last; } else { print "Invalid Entry. Please Enter again.\n"; } if ( $i==2) { last; } } while ( 1 ) { print "\nState or Province (full name) : "; $state = ; chop($state); if ( $state ne "" ) { $temp = validate ($state); if ( $temp == 1 ) { last; } } else { last; } } while ( 1 ) { print "\nLocality (eg, city) : "; $location = ; chop($location); if ( $location ne "" ) { $temp = validate ($location); if ( $temp == 1 ) { last; } } else { last; } } while ( 1 ) { print "\nOrganisation (eg, company) : "; $organisation = ; chop($organisation); if ( $organisation ne "" ) { $temp = validate ($organisation); if ( $temp == 1 ) { last; } } else { last; } } while ( 1 ) { print "\nOrganisation_unit (eg, company) : "; $organisation_unit = ; chop($organisation_unit); if ( $organisation_unit ne "" ) { $temp = validate ($organisation_unit); if ( $temp == 1 ) { last; } } else { last; } } while ( 1 ) { print "\nHost Name (eg, FQDN) : "; $common_name = ; chop ( $common_name ); if ($common_name eq "") { print "HostName can not be empty. Please Enter again.\n"; $temp=0; } else { $temp = validate ($common_name); } if ( $temp == 1 ) { last; } } # check for email while ( 1 ) { print "\nEnter e-mail address (eg, your_name\@domain.com) : "; $eaddress = ; chop ( $eaddress ); if ($eaddress eq "") { last; } else { my $i,@temp; # split as two strings (before @ and after @) @temp = split("@",$eaddress); $_ = $temp[0]; # remove blank characters s/ //g; $temp[0] = $_; @temp1 = split("", $temp[0]); if ($temp1[0] eq "." || $temp1[@temp1-1] eq ".") { print "Invalid Entry. Please Enter again.1\n"; } else { for($i=0;$i<@temp1;$i++) { if($temp1[$i]!~/[A-Za-z0-9-\._]/) { print "Invalid Entry. Please Enter again.\n"; last; } } } # if terminated without matching all characters or no match if ( ($i != @temp1) || !$i ) { # print message only when no characters matched and length of the string is zero if ( !$i && !@temp1) { print "Invalid Entry. Please Enter again.\n"; } # loop to get the input next; } # remove newline/carriage-return chop($temp[1]); $_ = $temp[1]; # remove blank characters s/ //g; $temp[1] = $_; @temp1 = split("", $temp[1]); if ($temp1[0] eq "." || $temp1[@temp1-1] eq ".") { print "Invalid Entry. Please Enter again.\n"; } else { for($i=0;$i<@temp1 ;$i++) { if($temp1[$i]!~/[A-Za-z0-9-\._]/) { print "Invalid Entry. Please Enter again.\n"; last; } } } # accept the input when all characters matched our requirement and i is not zero if ( ($i == @temp1) && $i ) { last; } elsif ( !$i && !@temp1) { # print message only when no characters matched and the string after @ is nil print "Invalid Entry. Please Enter again.\n"; } $eaddress = $temp[0] . '@' . $temp[1]; } } #end of while loop # compact it, if the after-@ part contains blank characters # $eaddress = $temp[0] . '@' . $temp[1]; $cpasswd = "A challenge password"; # write to openssl.conf file open (SSLFILE, ">$CONFFILE") or die "openssl.conf : could not open for writing($!)"; print SSLFILE "[ req ]\n"; print SSLFILE "default_bits = 1024\n"; print SSLFILE "distinguished_name = req_distinguished_name\n"; print SSLFILE "prompt = no\n"; print SSLFILE "output_password = mypass\n\n"; print SSLFILE "[ req_distinguished_name ]\n"; if ( $country ne "" ) { print SSLFILE "C = " . $country . "\n"; } if ( $state ne "" ) { print SSLFILE "ST= " . $state . "\n"; } if ( $location ne "" ) { print SSLFILE "L = " . $location . "\n"; } if ( $organisation ne "" ) { print SSLFILE "O = " . $organisation . "\n"; } if ( $organisation_unit ne "" ) { print SSLFILE "OU= " . $organisation_unit . "\n"; } if ( $common_name ne "" ) { print SSLFILE "CN= " . $common_name . "\n"; } if ( $eaddress ne "" ) { print SSLFILE "emailAddress= " . $eaddress . "\n"; } print SSLFILE "[ req_attributes ]\n"; print SSLFILE "challengePassword = " . $cpasswd; close SSLFILE; # generate certificate $exit_value = system ($SIGNTOOL); $exit_value = $? >> 8; return $exit_value; } # Date : 12-12-2001 # Change owner of the created file to casuser:casusers sub change_owner { $FileName = $_[0]; $FileName =~ s/\s+//g; if ($FileName eq "") { print "ERROR: Incorrect argument passed to change_owner \n" ; return; } if ($CRM::CRM_OS eq "UNIX") { # change the permission to casuser:casusers $user = $ENV{'PX_USER'}; ($account,$passwd,$uid,$gid ) = getpwnam($user); $rc = chown $uid, $gid, $FileName; if ($rc != 1) { print "ERROR: Cannot change the ownership for $FileName\n"; print "ERROR: Please change it manually to casuser:casusers\n" ; } } else { #require Win32::FileSecurity; #$PERMS{'SYSTEM'} = Win32::FileSecurity::MakeMask("READ"); #Win32::FileSecurity::Set($KEYFILE,\%PERMS); } } # Date : 28-3-2002 # Change permission of file passed as argument sub change_perms { $FileName = $_[0]; $FileName =~ s/\s+//g; if ($FileName eq "") { print "ERROR: Incorrect argument passed to change_perm \n" ; return; } if ($CRM::CRM_OS eq "UNIX") { # change the permission to 644 #($account,$passwd,$uid,$gid ) = getpwnam($user); $rc = chmod $PERMS, $FileName; if ($rc != 1) { print "ERROR: Cannot change the ownership for $FileName\n"; print "ERROR: Please change it manually to casuser:casusers\n" ; } } else { #require Win32::FileSecurity; #$PERMS{'SYSTEM'} = Win32::FileSecurity::MakeMask("READ"); #Win32::FileSecurity::Set($KEYFILE,\%PERMS); } } # # Upload the existing certificate # sub upload_cert { $skey = validate_file ('server.key'); $scrt = validate_file ('server.crt'); #print "Enter the directory and file name for any other \ncertifcates available (optional) : "; #$s_ocert = ; #if ( ($s_ocert ne "\n") && ($s_ocert ne "\r") && ($s_ocert ne "\r\n") ) { # if ( !($temp = isfExists( $s_ocert ) ) ) { # print "The file/directory name entered by you does not exist,\n # Skipping this step because this is not mandatory\n"; # } #} # Copy the existing files to the cw2k designated directory fcreate_write( $skey, $KEYFILE); fcreate_write( $scrt, $CERTFILE); # Date : 12-12-2001 change_owner ( $KEYFILE ); change_owner ( $CERTFILE ); # check the validity of the certicate $ret = exec_java ('com.cisco.nm.cmf.ssl.CheckValidity', "$CERTFILE"); if ( !$ret ) { # call EnableSSL.pl #system ( $SSL_EN); return 0; } # Date : 12-12-2001 print "INFO : The certificate entered is not valid\n"; return 1; } # # Get option from the user ( new certificate/existing certificate ) # sub get_option { print "You don't have a private key and/or certificate\n\n"; return new_cert(); #print "Do you want to"; #while ( 1 ) { # print "\n1. Create New Cerificate\n"; # print "2. Upload Existing Certificate\n"; # print "\nEnter 1 or 2 : "; # $temp = ; # chop($temp); # if ( ord($temp) == 49 ) { #1 # return new_cert(); # } elsif ( ord($temp) == 50 ) { #2 # return upload_cert(); # } # print "Not a valid option\n"; #} } # Verify the validity of the certificate in server.crt sub exec_java { $java = "$ENV{'NMSROOT'}/bin/cwjava -cw $ENV{'NMSROOT'}"; my @javaPath; $javaPath[0] = "$ENV{'NMSROOT'}/lib/classpath"; my $fullJavaPath; if ($ENV{OS} eq 'Windows_NT') { $fullJavaPath = join(";", @javaPath); } else { $fullJavaPath = join(":", @javaPath); } $javaCmd = $_[0]; $fullCmd = join(" ", $java, "-classpath", $fullJavaPath, $javaCmd, $_[1]); # execute the java function system ($fullCmd); $exit_value = ($? >> 8); return $exit_value; } # Setup platform specific variables sub Initialize { if ($CRM::CRM_OS eq "UNIX") { $KEYFILE = "$ENV{'NMSROOT'}/MDC/Apache/conf/ssl/server.key"; $CERTFILE = "$ENV{'NMSROOT'}/MDC/Apache/conf/ssl/server.crt"; $CSRFILE = "$ENV{'NMSROOT'}/MDC/Apache/conf/ssl/server.csr"; $PK8FILE = "$ENV{'NMSROOT'}/MDC/Apache/conf/ssl/server.pk8"; #$SSL_EN = "$ENV{'NMSROOT'}/MDC/Apache/bin/EnableSSL.pl"; #$SSL_DIS = "$ENV{'NMSROOT'}/MDC/Apache/bin/EnableSSL.pl -d"; $CONFFILE = "$ENV{'NMSROOT'}/MDC/Apache/conf/ssl/openssl.conf" ; $SIGNTOOL = "$ENV{'NMSROOT'}/bin/perl $ENV{'NMSROOT'}/MDC/Apache/bin/SignTool.pl -SSL=true"; $MDPROP = "$ENV{'NMSROOT'}/lib/classpath/md.properties"; #$MDPROP_TMP = "$ENV{'NMSROOT'}/lib/classpath/md.properties.tmp"; $SSL_COM = "$ENV{'NMSROOT'}/MDC/Apache/bin/ssl_com.pl cli"; $SSL_DIS = "$ENV{'NMSROOT'}/MDC/Apache/bin/ssl_dis.pl cli"; $SSL_LOG = '/var/adm/CSCOpx/log/SSL.log'; $PERMS = 0644; } else { $KEYFILE = "$ENV{'NMSROOT'}\\MDC\\Apache\\conf\\ssl\\server.key"; $CERTFILE = "$ENV{'NMSROOT'}\\MDC\\Apache\\conf\\ssl\\server.crt"; $CSRFILE = "$ENV{'NMSROOT'}\\MDC\\Apache\\conf\\ssl\\server.csr"; $PK8FILE = "$ENV{'NMSROOT'}\\MDC\\Apache\\conf\\ssl\\server.pk8"; #$SSL_EN = "$ENV{'NMSROOT'}\\bin\\perl $ENV{'NMSROOT'}\\MDC\\Apache\\EnableSSL.pl"; #$SSL_DIS = "$ENV{'NMSROOT'}\\bin\\perl $ENV{'NMSROOT'}\\MDC\\Apache\\EnableSSL.pl -d"; $CONFFILE = "$ENV{'NMSROOT'}\\MDC\\Apache\\conf\\ssl\\openssl.conf" ; $SIGNTOOL = "$ENV{'NMSROOT'}\\bin\\perl $ENV{'NMSROOT'}\\MDC\\Apache\\SignTool.pl -SSL=true"; $MDPROP = "$ENV{'NMSROOT'}\\lib\\classpath\\md.properties"; #$MDPROP_TMP = "$ENV{'NMSROOT'}\\lib\\classpath\\md.properties.tmp"; $SSL_COM = "$ENV{'NMSROOT'}\\bin\\perl $ENV{'NMSROOT'}\\MDC\\Apache\\ssl_com.pl cli"; $SSL_DIS = "$ENV{'NMSROOT'}\\bin\\perl $ENV{'NMSROOT'}\\MDC\\Apache\\ssl_dis.pl cli"; $SSL_LOG = "$ENV{'NMSROOT'}\\log\\SSL.log"; } }