Author: arkurth
Date: Thu May 28 17:08:34 2009
New Revision: 779670
URL: http://svn.apache.org/viewvc?rev=779670&view=rev
Log:
VCL-23
Reworked firewall subroutines. That had been calling a firewall_configure() sub
by passing a hash of details. This was overly complicated. I changed each
firewall sub to call netsh.exe directly with the proper switches.
Modified:
incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows_mod.pm
Modified: incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows_mod.pm
URL:
http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows_mod.pm?rev=779670&r1=779669&r2=779670&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows_mod.pm
(original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows_mod.pm Thu May
28 17:08:34 2009
@@ -217,20 +217,6 @@
if (!$self->clean_hard_drive()) {
notify($ERRORS{'WARNING'}, 0, "unable to clean unnecessary
files the hard drive");
}
-
-#=item *
-#
-#Delete the 'System Startup Script' scheduled task
-#
-#=cut
-#
-# # This task must be deleted because it will conflict with the
post_load.cmd Run command that is added
-# # It also may cause problems after the reboot that occurs when the
pagefile is disabled
-# # SSH commands may fail while the networking and Cygwin scripts are
running
-# if (!$self->delete_scheduled_task('System Startup Script')) {
-# notify($ERRORS{'WARNING'}, 0, "unable to delete 'System Startup
Script' scheduled task");
-# return 0;
-# }
=item *
@@ -3454,10 +3440,9 @@
}
} ## end sub get_current_image_name
-
#/////////////////////////////////////////////////////////////////////////////
-=head2 firewall_configure
+=head2 firewall_enable_ping
Parameters :
Returns : 1 if succeeded, 0 otherwise
@@ -3465,108 +3450,43 @@
=cut
-sub firewall_configure {
+sub firewall_enable_ping {
my $self = shift;
if (ref($self) !~ /windows/i) {
notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a
function, it must be called as a class method");
return;
}
+
+ my $management_node_keys = $self->data->get_management_node_keys();
+ my $computer_node_name = $self->data->get_computer_node_name();
+
+ my $netsh_command;
+ $netsh_command .= "netsh.exe firewall set icmpsetting";
+ $netsh_command .= " type = 8";
+ $netsh_command .= " mode = ENABLE";
+ $netsh_command .= " profile = ALL";
- my $management_node_keys = $self->data->get_management_node_keys();
- my $computer_node_name = $self->data->get_computer_node_name();
-
- # Check the arguments
- my $firewall_parameters = shift;
- if (!defined($firewall_parameters) || !$firewall_parameters) {
- notify($ERRORS{'WARNING'}, 0, "failed to open firewall on
$computer_node_name, parameters hash reference was not passed");
- return;
- }
- if ((!defined($firewall_parameters->{port}) ||
!$firewall_parameters->{port}) && (!defined($firewall_parameters->{type}) ||
!$firewall_parameters->{type})) {
- notify($ERRORS{'WARNING'}, 0, "failed to open firewall on
$computer_node_name, 'port' or 'type' hash key was not passed");
- return;
+ # Execute the netsh.exe command
+ my ($netsh_exit_status, $netsh_output) =
run_ssh_command($computer_node_name, $management_node_keys, $netsh_command);
+
+ if (defined($netsh_output) && @$netsh_output[-1] =~ /Ok\./i) {
+ notify($ERRORS{'OK'}, 0, "configured firewall to allow ping");
}
- if (!defined($firewall_parameters->{protocol}) ||
!$firewall_parameters->{protocol}) {
- notify($ERRORS{'WARNING'}, 0, "failed to open firewall on
$computer_node_name, 'protocol' hash key was not passed");
+ elsif (defined($netsh_exit_status)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to configure firewall to
allow ping, exit status: $netsh_exit_status, output:\...@{$netsh_output}");
return;
}
-
- # Add quotes around anything with a space in the parameters hash which
isn't already enclosed in quotes
- foreach my $rule_property (sort keys(%{$firewall_parameters})) {
- $firewall_parameters->{$rule_property} =~ s/^(.*\s.*)$/\"$1\"/g;
- #notify($ERRORS{'DEBUG'}, 0, "enclosing property in quotes:
$firewall_parameters->{$rule_property}");
- }
-
- # netsh firewall set portopening
- # [ protocol = ] TCP|UDP|ALL
- # [ port = ] 1-65535
- # [ [ name = ] name (optional)
- # [ mode = ] ENABLE (default)|DISABLE (optional)
- # [ scope = ] ALL|SUBNET|CUSTOM (optional)
- # [ addresses = ] addresses (optional)
- # [ profile = ] CURRENT (default)|DOMAIN|STANDARD|ALL (optional)
- # [ interface = ] name ] (optional)
- # Remarks: 'profile' and 'interface' may not be specified together.
- # 'scope' and 'interface' may not be specified together.
- # 'scope' must be 'CUSTOM' to specify 'addresses'.
-
- # netsh firewall set icmpsetting
- # [ type = ] 2-5|8-9|11-13|17|ALL
- # [ [ mode = ] ENABLE (default)|DISABLE (optional)
- # [ profile = ] CURRENT (default)|DOMAIN|STANDARD|ALL (optional)
- # [ interface = ] name ] (optional)
- # type - ICMP type.
- # 2 - Allow outbound packet too big.
- # 3 - Allow outbound destination unreachable.
- # 4 - Allow outbound source quench.
- # 5 - Allow redirect.
- # 8 - Allow inbound echo request.
- # 9 - Allow inbound router request.
- # 11 - Allow outbound time exceeded.
- # 12 - Allow outbound parameter problem.
- # 13 - Allow inbound timestamp request.
- # 17 - Allow inbound mask request.
- # ALL - All types.
- # Remarks: 'profile' and 'interface' may not be specified together.
- # 'type' 2 and 'interface' may not be specified
together.
-
- # Assemble the command based on the keys populated in the hash
- my $set_portopening_command;
- if ($firewall_parameters->{protocol} =~ /icmp/i) {
- $set_portopening_command = "netsh.exe firewall set icmpsetting";
-
- foreach my $rule_property (sort keys(%{$firewall_parameters})) {
- next if $rule_property !~
/^type|mode|profile|interface$/;
- $set_portopening_command .= "
$rule_property=$firewall_parameters->{$rule_property}";
- }
- }
else {
- $set_portopening_command = "netsh.exe firewall set portopening";
-
- foreach my $rule_property (sort keys(%{$firewall_parameters})) {
- next if $rule_property !~
/^protocol|port|name|mode|scope|addresses|profile|interface$/;
- $set_portopening_command .= "
$rule_property=$firewall_parameters->{$rule_property}";
- }
- }
-
- my ($set_portopening_exit_status, $set_portopening_output) =
run_ssh_command($computer_node_name, $management_node_keys,
$set_portopening_command);
- if (defined($set_portopening_exit_status) &&
$set_portopening_exit_status == 0) {
- notify($ERRORS{'OK'}, 0, "set firewall portopening: " .
Dumper($firewall_parameters));
- }
- elsif (defined($set_portopening_exit_status)) {
- notify($ERRORS{'WARNING'}, 0, "failed to set firewall
portopening on $computer_node_name: " . Dumper($firewall_parameters) . ", exit
status: $set_portopening_exit_status, output:\...@{$set_portopening_output}");
- return 0;
- }
- else {
- notify($ERRORS{'WARNING'}, 0, "failed to set firewall
portopening on $computer_node_name: " . Dumper($firewall_parameters));
+ notify($ERRORS{'WARNING'}, 0, "failed to run ssh command to
configure firewall to allow ping");
return;
}
return 1;
-} ## end sub firewall_configure
+}
#/////////////////////////////////////////////////////////////////////////////
-=head2 firewall_close
+=head2 firewall_enable_ping_private
Parameters :
Returns : 1 if succeeded, 0 otherwise
@@ -3574,68 +3494,82 @@
=cut
-sub firewall_close {
+sub firewall_enable_ping_private {
my $self = shift;
if (ref($self) !~ /windows/i) {
notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a
function, it must be called as a class method");
return;
}
-
- my $management_node_keys = $self->data->get_management_node_keys();
- my $computer_node_name = $self->data->get_computer_node_name();
-
- # Make sure firewall parameters hash was passed
- my $firewall_parameters = shift;
- if (!defined($firewall_parameters) || !$firewall_parameters) {
- notify($ERRORS{'WARNING'}, 0, "failed to close firewall on
$computer_node_name, parameters hash reference was not passed");
- return;
+
+ my $management_node_keys = $self->data->get_management_node_keys();
+ my $computer_node_name = $self->data->get_computer_node_name();
+
+ my $netsh_command;
+
+ # Get the public interface name
+ # Add command to disable ping on public interface if its name is found
+ my $public_interface_name = $self->get_public_interface_name();
+ if ($public_interface_name) {
+ notify($ERRORS{'DEBUG'}, 0, "ping will be disabled on public
interface: $public_interface_name");
+
+ $netsh_command .= "netsh.exe firewall set icmpsetting";
+ $netsh_command .= " type = 8";
+ $netsh_command .= " mode = DISABLE";
+ $netsh_command .= " interface = \"$public_interface_name\"";
+ $netsh_command .= ' ;';
}
-
- # Add quotes around anything with a space in the parameters hash which
isn't already enclosed in quotes
- foreach my $rule_property (sort keys(%{$firewall_parameters})) {
- $firewall_parameters->{$rule_property} =~ s/^(.*\s.*)$/\"$1\"/g;
- #notify($ERRORS{'DEBUG'}, 0, "enclosing '$rule_property'
property in quotes: $firewall_parameters->{$rule_property}");
+ else {
+ notify($ERRORS{'WARNING'}, 0, "ping will not be disabled on
public interface because public interface name could not be determined");
}
-
- # delete portopening
- #
- # [ protocol = ] TCP|UDP|ALL
- # [ port = ] 1-65535
- # [ [ profile = ] CURRENT|DOMAIN|STANDARD|ALL (optional)
- # [ interface = ] name ] (optional)
- # Remarks: 'profile' and 'interface' may not be specified together.
-
- # Assemble the command based on the keys populated in the hash
- my $delete_portopening_command = "netsh.exe firewall delete
portopening";
- foreach my $rule_property (sort keys(%{$firewall_parameters})) {
- next if $rule_property !~ /^protocol|port|profile|interface$/;
- $delete_portopening_command .= "
$rule_property=$firewall_parameters->{$rule_property}";
+
+ # Get the private interface name
+ # Add command to ensable ping on private interface if its name is found
+ my $private_interface_name = $self->get_private_interface_name();
+ if ($private_interface_name) {
+ notify($ERRORS{'DEBUG'}, 0, "ping will be enabled on private
interface: $private_interface_name");
+
+ $netsh_command .= "netsh.exe firewall set icmpsetting";
+ $netsh_command .= " type = 8";
+ $netsh_command .= " mode = DISABLE";
+ $netsh_command .= " profile = ALL";
+ $netsh_command .= ' ;';
+
+ $netsh_command .= "netsh.exe firewall set icmpsetting";
+ $netsh_command .= " type = 8";
+ $netsh_command .= " mode = ENABLE";
+ $netsh_command .= " interface = \"$private_interface_name\"";
}
-
- # Attempt to delete existing portopenings
- notify($ERRORS{'DEBUG'}, 0, "attempting to delete matching firewall
portopenings on $computer_node_name, command:\n$delete_portopening_command");
- my ($delete_portopening_exit_status, $delete_portopening_output) =
run_ssh_command($computer_node_name, $management_node_keys,
$delete_portopening_command);
- if (defined($delete_portopening_exit_status) &&
($delete_portopening_exit_status == 0)) {
- notify($ERRORS{'OK'}, 0, "deleted matching firewall
portopenings: " . Dumper($firewall_parameters));
- return 1;
+ else {
+ notify($ERRORS{'WARNING'}, 0, "private interface name could not
be determined, ping will be enabled for all profiles");
+
+ $netsh_command .= "netsh.exe firewall set icmpsetting";
+ $netsh_command .= " type = 8";
+ $netsh_command .= " mode = ENABLE";
+ $netsh_command .= " profile = ALL";
+ $netsh_command .= ' ;';
}
- elsif (defined($delete_portopening_exit_status) &&
($delete_portopening_exit_status == 1)) {
- notify($ERRORS{'OK'}, 0, "unable to delete matching firewall
portopenings because none exist: " . Dumper($firewall_parameters));
- return 1;
+
+ # Execute the netsh.exe command
+ my ($netsh_exit_status, $netsh_output) =
run_ssh_command($computer_node_name, $management_node_keys, $netsh_command);
+
+ if (defined($netsh_output) && @$netsh_output[-1] =~ /Ok\./i) {
+ notify($ERRORS{'OK'}, 0, "configured firewall to allow ping on
private interface");
}
- elsif (defined($delete_portopening_exit_status)) {
- notify($ERRORS{'WARNING'}, 0, "failed to delete matching
firewall portopenings on $computer_node_name: " . Dumper($firewall_parameters)
. ", exit status: $delete_portopening_exit_status,
output:\...@{$delete_portopening_output}");
- return 0;
+ elsif (defined($netsh_exit_status)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to configure firewall to
allow ping on private interface, exit status: $netsh_exit_status,
output:\...@{$netsh_output}");
+ return;
}
else {
- notify($ERRORS{'WARNING'}, 0, "failed to run ssh command to
delete matching firewall portopenings on $computer_node_name: " .
Dumper($firewall_parameters));
- return 0;
+ notify($ERRORS{'WARNING'}, 0, "failed to run ssh command to
configure firewall to allow ping on private interface");
+ return;
}
-} ## end sub firewall_close
+
+ return 1;
+} ## end sub firewall_enable_ping_private
#/////////////////////////////////////////////////////////////////////////////
-=head2 firewall_enable_ping
+=head2 firewall_disable_ping
Parameters :
Returns : 1 if succeeded, 0 otherwise
@@ -3643,85 +3577,73 @@
=cut
-sub firewall_enable_ping {
+sub firewall_disable_ping {
my $self = shift;
if (ref($self) !~ /windows/i) {
notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a
function, it must be called as a class method");
return;
}
-
- my %firewall_parameters = (protocol => 'icmp',
-
type => 8,
-
mode => 'ENABLE',
-
profile => 'ALL');
-
- # Call the configure firewall subroutine, pass it the necessary
parameters
- if ($self->firewall_configure(\%firewall_parameters)) {
- notify($ERRORS{'OK'}, 0, "opened firewall for incoming ping on
all interfaces");
+ my $management_node_keys = $self->data->get_management_node_keys();
+ my $computer_node_name = $self->data->get_computer_node_name();
+
+ my $netsh_command;
+
+ # Get the private interface name
+ # Add command to disable ping on private interface if its name is found
+ my $private_interface_name = $self->get_private_interface_name();
+ if ($private_interface_name) {
+ notify($ERRORS{'DEBUG'}, 0, "retrieved private interface name:
$private_interface_name");
+
+ $netsh_command .= "netsh.exe firewall set icmpsetting";
+ $netsh_command .= " type = 8";
+ $netsh_command .= " mode = DISABLE";
+ $netsh_command .= " interface = \"$private_interface_name\"";
+ $netsh_command .= ' ;';
}
else {
- notify($ERRORS{'WARNING'}, 0, "failed to open firewall for
incoming ping on all interfaces");
- return 0;
+ notify($ERRORS{'WARNING'}, 0, "private interface name could not
be determined");
}
-
- return 1;
-}
-
-#/////////////////////////////////////////////////////////////////////////////
-
-=head2 firewall_enable_ping_private
-
- Parameters :
- Returns : 1 if succeeded, 0 otherwise
- Description :
-
-=cut
-
-sub firewall_enable_ping_private {
- my $self = shift;
- if (ref($self) !~ /windows/i) {
- notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a
function, it must be called as a class method");
- return;
+
+ # Get the public interface name
+ # Add command to disable ping on public interface if its name is found
+ my $public_interface_name = $self->get_public_interface_name();
+ if ($public_interface_name) {
+ notify($ERRORS{'DEBUG'}, 0, "retrieved public interface name:
$public_interface_name");
+
+ $netsh_command .= "netsh.exe firewall set icmpsetting";
+ $netsh_command .= " type = 8";
+ $netsh_command .= " mode = DISABLE";
+ $netsh_command .= " interface = \"$public_interface_name\"";
+ $netsh_command .= ' ;';
}
-
- my @private_interface_names = $self->get_private_interface_names();
- if (!...@private_interface_names) {
- notify($ERRORS{'WARNING'}, 0, "private interface name could not
be determined");
+ else {
+ notify($ERRORS{'WARNING'}, 0, "public interface name could not
be determined");
}
-
- for my $private_interface_name (@private_interface_names) {
- my %firewall_parameters = (protocol => 'icmp',
-
type => 8,
-
interface => $private_interface_name,
-
mode => 'ENABLE',);
-
- # Call the configure firewall subroutine, pass it the necessary
parameters
- if ($self->firewall_configure(\%firewall_parameters)) {
- notify($ERRORS{'OK'}, 0, "opened firewall for incoming
ping on private network");
- }
- else {
- notify($ERRORS{'WARNING'}, 0, "failed to open firewall
for incoming ping on private network");
- return 0;
- }
- } ## end for my $private_interface_name (@private_interface_names)
- # Remove exception for all interfaces
- my %firewall_parameters = (protocol => 'icmp',
-
type => 8,
-
mode => 'DISABLE',
-
profile => 'ALL');
-
- # Call the configure firewall subroutine, pass it the necessary
parameters
- if ($self->firewall_configure(\%firewall_parameters)) {
- notify($ERRORS{'OK'}, 0, "closed firewall for incoming ping on
all interfaces");
+ # Add command to disable ping for all profiles
+ $netsh_command .= "netsh.exe firewall set icmpsetting";
+ $netsh_command .= " type = 8";
+ $netsh_command .= " mode = DISABLE";
+ $netsh_command .= " profile = ALL";
+
+ # Execute the netsh.exe command
+ my ($netsh_exit_status, $netsh_output) =
run_ssh_command($computer_node_name, $management_node_keys, $netsh_command);
+
+ if (defined($netsh_output) && @$netsh_output[-1] =~ /Ok\./i) {
+ notify($ERRORS{'OK'}, 0, "configured firewall to disallow
ping");
+ }
+ elsif (defined($netsh_exit_status)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to configure firewall to
disallow ping, exit status: $netsh_exit_status, output:\...@{$netsh_output}");
+ return;
}
else {
- notify($ERRORS{'WARNING'}, 0, "failed to close firewall for
incoming ping on all interfaces");
+ notify($ERRORS{'WARNING'}, 0, "failed to run ssh command to
configure firewall to disallow ping");
+ return;
}
return 1;
-} ## end sub firewall_enable_ping_private
+}
#/////////////////////////////////////////////////////////////////////////////
@@ -3739,21 +3661,75 @@
notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a
function, it must be called as a class method");
return;
}
+
+ # Check if the remote IP was passed correctly as an argument
+ my $remote_ip = shift;
+
+ my $management_node_keys = $self->data->get_management_node_keys();
+ my $computer_node_name = $self->data->get_computer_node_name();
- my %firewall_parameters = (name => 'Cygwin SSHD',
-
protocol => 'TCP',
-
port => '22',
-
mode => 'ENABLE',
-
profile => 'ALL',
-
scope => 'ALL');
-
- # Call the configure firewall subroutine, pass it the necessary
parameters
- if ($self->firewall_configure(\%firewall_parameters)) {
- notify($ERRORS{'OK'}, 0, "opened firewall for incoming ssh via
TCP port 22 on all interfaces");
+ my $netsh_command;
+
+ # Get the public interface name
+ # Add command to disable SSH on public interface if its name is found
+ my $public_interface_name = $self->get_public_interface_name();
+ if ($public_interface_name) {
+ notify($ERRORS{'DEBUG'}, 0, "SSH will be disabled on public
interface: $public_interface_name");
+
+ $netsh_command .= "netsh.exe firewall delete portopening";
+ $netsh_command .= " protocol = TCP";
+ $netsh_command .= " port = 22";
+ $netsh_command .= " interface = \"$public_interface_name\"";
+ $netsh_command .= ' ;';
}
else {
- notify($ERRORS{'WARNING'}, 0, "failed to open firewall for
incoming ssh via TCP port 22 on all interfaces");
- return 0;
+ notify($ERRORS{'WARNING'}, 0, "SSH will not be disabled on
public interface because public interface name could not be determined");
+ }
+
+ # Get the private interface name
+ # Add command to disable SSH on private interface if its name is found
+ my $private_interface_name = $self->get_private_interface_name();
+ if ($private_interface_name) {
+ notify($ERRORS{'DEBUG'}, 0, "SSH will be disabled on private
interface: $private_interface_name");
+
+ $netsh_command .= "netsh.exe firewall delete portopening";
+ $netsh_command .= " protocol = TCP";
+ $netsh_command .= " port = 22";
+ $netsh_command .= " interface = \"$private_interface_name\"";
+ $netsh_command .= ' ;';
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "SSH will not be disabled on
private interface because private interface name could not be determined");
+ }
+
+ $netsh_command .= "netsh.exe firewall set portopening";
+ $netsh_command .= " name = \"Cygwin SSHD\"";
+ $netsh_command .= " protocol = TCP";
+ $netsh_command .= " port = 22";
+ $netsh_command .= " mode = ENABLE";
+
+ if (!defined($remote_ip) || $remote_ip !~ /[\d\.\/]/) {
+ $remote_ip = 'all addresses'; # Set only to display in output
+ $netsh_command .= " scope = ALL";
+ }
+ else {
+ $netsh_command .= " scope = CUSTOM";
+ $netsh_command .= " addresses = $remote_ip";
+ }
+
+ # Execute the netsh.exe command
+ my ($netsh_exit_status, $netsh_output) =
run_ssh_command($computer_node_name, $management_node_keys, $netsh_command);
+
+ if (defined($netsh_output) && @$netsh_output[-1] =~ /Ok\./i) {
+ notify($ERRORS{'OK'}, 0, "configured firewall to allow SSH from
$remote_ip");
+ }
+ elsif (defined($netsh_exit_status)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to configure firewall to
allow SSH from $remote_ip, exit status: $netsh_exit_status,
output:\...@{$netsh_output}");
+ return;
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "failed to run ssh command to
configure firewall to allow SSH from $remote_ip");
+ return;
}
return 1;
@@ -3775,40 +3751,70 @@
notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a
function, it must be called as a class method");
return;
}
-
- my @private_interface_names = $self->get_private_interface_names();
- if (!...@private_interface_names) {
- notify($ERRORS{'WARNING'}, 0, "private interface name could not
be determined");
+
+ my $management_node_keys = $self->data->get_management_node_keys();
+ my $computer_node_name = $self->data->get_computer_node_name();
+
+ my $netsh_command;
+
+ # Get the public interface name
+ # Add command to disable SSH on public interface if its name is found
+ my $public_interface_name = $self->get_public_interface_name();
+ if ($public_interface_name) {
+ notify($ERRORS{'DEBUG'}, 0, "SSH will be disabled on public
interface: $public_interface_name");
+
+ $netsh_command .= "netsh.exe firewall delete portopening";
+ $netsh_command .= " protocol = TCP";
+ $netsh_command .= " port = 22";
+ $netsh_command .= " interface = \"$public_interface_name\"";
+ $netsh_command .= ' ;';
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "SSH will not be disabled on
public interface because public interface name could not be determined");
}
-
- for my $private_interface_name (@private_interface_names) {
- my %firewall_parameters = (name => 'Cygwin SSHD',
-
protocol => 'TCP',
-
port => '22',
-
interface => $private_interface_name,
-
mode => 'ENABLE',);
-
- # Call the configure firewall subroutine, pass it the necessary
parameters
- if ($self->firewall_configure(\%firewall_parameters)) {
- notify($ERRORS{'OK'}, 0, "opened firewall for incoming
ssh via TCP port 22 on private interface");
- }
- else {
- notify($ERRORS{'WARNING'}, 0, "failed to open firewall
for incoming ssh via TCP port 22 on private interface");
- return 0;
- }
- } ## end for my $private_interface_name (@private_interface_names)
- # Remove exception for all interfaces
- my %firewall_parameters = (protocol => 'TCP',
-
port => '22',
-
profile => 'ALL',);
-
- # Call the configure firewall subroutine, pass it the necessary
parameters
- if ($self->firewall_close(\%firewall_parameters)) {
- notify($ERRORS{'OK'}, 0, "closed firewall for incoming RDP via
TCP port 22 from any address");
+ # Get the private interface name
+ # Add command to ensable SSH on private interface if its name is found
+ my $private_interface_name = $self->get_private_interface_name();
+ if ($private_interface_name) {
+ notify($ERRORS{'DEBUG'}, 0, "SSH will be enabled on private
interface: $private_interface_name");
+
+ $netsh_command .= "netsh.exe firewall delete portopening";
+ $netsh_command .= " protocol = TCP";
+ $netsh_command .= " port = 22";
+ $netsh_command .= " profile = ALL";
+ $netsh_command .= ' ;';
+
+ $netsh_command .= "netsh.exe firewall set portopening";
+ $netsh_command .= " name = \"Cygwin SSHD\"";
+ $netsh_command .= " protocol = TCP";
+ $netsh_command .= " port = 22";
+ $netsh_command .= " mode = ENABLE";
+ $netsh_command .= " interface = \"$private_interface_name\"";
}
else {
- notify($ERRORS{'WARNING'}, 0, "failed to close firewall for
incoming RDP via TCP port 22 from any address");
+ notify($ERRORS{'WARNING'}, 0, "private interface name could not
be determined, SSH will be enabled for all profiles");
+
+ $netsh_command .= "netsh.exe firewall set portopening";
+ $netsh_command .= " name = \"Cygwin SSHD\"";
+ $netsh_command .= " protocol = TCP";
+ $netsh_command .= " port = 22";
+ $netsh_command .= " profile = ALL";
+ }
+
+ # Execute the netsh.exe command
+ my ($netsh_exit_status, $netsh_output) =
run_ssh_command($computer_node_name, $management_node_keys, $netsh_command);
+
+ if (defined($netsh_output) && @$netsh_output[-1] =~ /Ok\./i) {
+ notify($ERRORS{'OK'}, 0, "configured firewall to allow SSH on
private interface");
+ }
+ elsif (defined($netsh_exit_status)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to configure firewall to
allow SSH on private interface, exit status: $netsh_exit_status,
output:\...@{$netsh_output}");
+ return;
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "failed to run ssh command to
configure firewall to allow SSH on private interface");
+ return;
}
return 1;
@@ -3905,30 +3911,41 @@
return;
}
- my %firewall_parameters = (name => 'Remote Desktop',
-
protocol => 'TCP',
-
port => '3389',
-
mode => 'ENABLE',
-
profile => 'ALL',);
-
# Check if the remote IP was passed correctly as an argument
my $remote_ip = shift;
+
+ my $management_node_keys = $self->data->get_management_node_keys();
+ my $computer_node_name = $self->data->get_computer_node_name();
+
+ my $netsh_command;
+ $netsh_command .= "netsh.exe firewall set portopening";
+ $netsh_command .= " name = \"Remote Desktop\"";
+ $netsh_command .= " protocol = TCP";
+ $netsh_command .= " port = 3389";
+ $netsh_command .= " mode = ENABLE";
+
if (!defined($remote_ip) || $remote_ip !~ /[\d\.\/]/) {
- $firewall_parameters{scope} = 'ALL';
+ $remote_ip = 'all addresses'; # Set only to display in output
+ $netsh_command .= " scope = ALL";
}
else {
- $firewall_parameters{scope} = 'CUSTOM';
- $firewall_parameters{addresses} = $remote_ip;
+ $netsh_command .= " scope = CUSTOM";
+ $netsh_command .= " addresses = $remote_ip";
}
- # Call the configure firewall subroutine, pass it the necessary
parameters
- if ($self->firewall_configure(\%firewall_parameters)) {
- notify($ERRORS{'OK'}, 0, "opened firewall for incoming RDP via
TCP port 3389");
- return 1;
+ # Execute the netsh.exe command
+ my ($netsh_exit_status, $netsh_output) =
run_ssh_command($computer_node_name, $management_node_keys, $netsh_command);
+
+ if (defined($netsh_output) && @$netsh_output[-1] =~ /Ok\./i) {
+ notify($ERRORS{'OK'}, 0, "configured firewall to allow RDP from
$remote_ip");
+ }
+ elsif (defined($netsh_exit_status)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to configure firewall to
allow RDP from $remote_ip, exit status: $netsh_exit_status,
output:\...@{$netsh_output}");
+ return;
}
else {
- notify($ERRORS{'WARNING'}, 0, "failed to open firewall for
incoming RDP via TCP port 3389");
- return 0;
+ notify($ERRORS{'WARNING'}, 0, "failed to run ssh command to
configure firewall to allow RDP from $remote_ip");
+ return;
}
} ## end sub firewall_enable_rdp
@@ -3948,20 +3965,66 @@
notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a
function, it must be called as a class method");
return;
}
+
+ my $management_node_keys = $self->data->get_management_node_keys();
+ my $computer_node_name = $self->data->get_computer_node_name();
+
+ my $netsh_command;
+
+ # Get the private interface name
+ # Add command to disable RDP on private interface if its name is found
+ my $private_interface_name = $self->get_private_interface_name();
+ if ($private_interface_name) {
+ notify($ERRORS{'DEBUG'}, 0, "RDP will be disabled on private
interface: $private_interface_name");
+
+ $netsh_command .= "netsh.exe firewall delete portopening";
+ $netsh_command .= " protocol = TCP";
+ $netsh_command .= " port = 3389";
+ $netsh_command .= " interface = \"$private_interface_name\"";
+ $netsh_command .= ' ;';
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "private interface name could not
be determined");
+ }
+
+ # Get the public interface name
+ # Add command to disable RDP on public interface if its name is found
+ my $public_interface_name = $self->get_public_interface_name();
+ if ($public_interface_name) {
+ notify($ERRORS{'DEBUG'}, 0, "RDP will be disabled on public
interface: $public_interface_name");
+
+ $netsh_command .= "netsh.exe firewall delete portopening";
+ $netsh_command .= " protocol = TCP";
+ $netsh_command .= " port = 3389";
+ $netsh_command .= " interface = \"$public_interface_name\"";
+ $netsh_command .= ' ;';
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "public interface name could not
be determined");
+ }
+
+ # Add command to disable RDP for all profiles
+ $netsh_command .= "netsh.exe firewall delete portopening";
+ $netsh_command .= " protocol = TCP";
+ $netsh_command .= " port = 3389";
+ $netsh_command .= " profile = ALL";
- my %firewall_parameters = (protocol => 'TCP',
-
port => '3389',
-
profile => 'ALL',);
-
- # Call the configure firewall subroutine, pass it the necessary
parameters
- if ($self->firewall_close(\%firewall_parameters)) {
- notify($ERRORS{'OK'}, 0, "closed firewall for incoming RDP via
TCP port 3389");
- return 1;
+ # Execute the netsh.exe command
+ my ($netsh_exit_status, $netsh_output) =
run_ssh_command($computer_node_name, $management_node_keys, $netsh_command);
+
+ if (defined($netsh_output) && @$netsh_output[-1] =~ /Ok\./i) {
+ notify($ERRORS{'OK'}, 0, "configured firewall to disallow RDP");
+ }
+ elsif (defined($netsh_exit_status)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to configure firewall to
disallow RDP, exit status: $netsh_exit_status, output:\...@{$netsh_output}");
+ return;
}
else {
- notify($ERRORS{'WARNING'}, 0, "failed to close firewall for
incoming RDP via TCP port 3389");
- return 0;
+ notify($ERRORS{'WARNING'}, 0, "failed to run ssh command to
configure firewall to disallow RDP");
+ return;
}
+
+ return 1;
} ## end sub firewall_disable_rdp
#/////////////////////////////////////////////////////////////////////////////
@@ -3994,212 +4057,321 @@
my $management_node_keys = $self->data->get_management_node_keys();
my $computer_node_name = $self->data->get_computer_node_name();
-
- my ($exit_status, $output) = run_ssh_command($computer_node_name,
$management_node_keys, '$SYSTEMROOT/System32/ipconfig.exe /all', '', '', 1);
- if (defined($exit_status) && $exit_status == 0) {
- notify($ERRORS{'DEBUG'}, 0, "ran ipconfig");
- }
- elsif (defined($exit_status)) {
- notify($ERRORS{'WARNING'}, 0, "failed to run ipconfig, exit
status: $exit_status, output:\...@{$output}");
- return 0;
+
+ # Check if a 'public' or 'private' network type argument was specified
+ my $network_type = lc(shift());
+ if ($network_type && $network_type !~ /(public|private)/i) {
+ notify($ERRORS{'WARNING'}, 0, "network type argument can only
be 'public' or 'private'");
+ return;
+ }
+
+ my %network_configuration;
+ if (!$self->{network_configuration}) {
+ notify($ERRORS{'DEBUG'}, 0, "attempting to retrieve network
configuration");
+
+ # Run ipconfig /all
+ my ($exit_status, $output) =
run_ssh_command($computer_node_name, $management_node_keys,
'$SYSTEMROOT/System32/ipconfig.exe /all', '', '', 1);
+ if (defined($exit_status) && $exit_status == 0) {
+ notify($ERRORS{'DEBUG'}, 0, "ran ipconfig");
+ }
+ elsif (defined($exit_status)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to run ipconfig,
exit status: $exit_status, output:\...@{$output}");
+ return 0;
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "failed to run the SSH
command to run ipconfig");
+ return;
+ }
+
+ my $interface_name;
+ my $previous_ip = 0;
+ my $setting;
+
+ for my $line (@{$output}) {
+ # Find beginning of interface section
+ if ($line =~ /ethernet adapter (.*):/i) {
+ # Get the interface name
+ $interface_name = $1;
+ next;
+ }
+
+ # Skip line if interface hasn't been found yet
+ next if !$interface_name;
+
+ # Take apart the line finding the setting name and
value with a hideous regex
+ my ($line_setting, $value) = $line =~ /^[
]{1,8}(\w[^\.]*\w)?[ \.:]+([^\r\n]*)/i;
+
+ # If the setting was found in the line, use it
+ # Otherwise, use the last found setting
+ $setting = $line_setting if $line_setting;
+
+ # Skip line if value wasn't found
+ next if !$value;
+
+ # Normalize the setting format, make it lowercase,
convert dashes and spaces to underscores
+ $setting = lc($setting);
+ $setting =~ s/[ -]/_/;
+
+ # Windows 6.x includes a version indicator in IP
address lines such as IPv4, remove this
+ $setting =~ s/ip(v\d)?_address/ip_address/;
+
+ # Remove the trailing s from dns_servers
+ $setting =~ s/dns_servers/dns_server/;
+
+ # Check which setting was found and add to hash
+ if ($setting =~ /dns_servers/) {
+
push(@{$network_configuration{$interface_name}{$setting}}, $value);
+ #notify($ERRORS{'OK'}, 0,
"$interface_name:$setting =
@{$network_configuration{$interface_name}{$setting}}");
+ }
+ elsif ($setting =~ /ip_address/) {
+ $value =~ s/[^\.\d]//g;
+
$network_configuration{$interface_name}{$setting}{$value} = '';
+ $previous_ip = $value;
+ #notify($ERRORS{'OK'}, 0,
"$interface_name:$setting =
$network_configuration{$interface_name}{$setting}{$value}");
+ }
+ elsif ($setting =~ /subnet_mask/) {
+
$network_configuration{$interface_name}{ip_address}{$previous_ip} = $value;
+ #notify($ERRORS{'OK'}, 0,
"$interface_name:$setting($previous_ip) =
$network_configuration{$interface_name}{ip_address}{$previous_ip}");
+ }
+ else {
+
$network_configuration{$interface_name}{$setting} = $value;
+ #notify($ERRORS{'OK'}, 0,
"$interface_name:$setting = $network_configuration{$interface_name}{$setting}");
+ }
+ }
+
+ notify($ERRORS{'DEBUG'}, 0, 'saving network configuration in
$self->{network_configuration}');
+ $self->{network_configuration} = \%network_configuration;
}
else {
- notify($ERRORS{'WARNING'}, 0, "failed to run the SSH command to
run ipconfig");
+ notify($ERRORS{'DEBUG'}, 0, "network configuration has already
been retrieved");
+ %network_configuration = %{$self->{network_configuration}};
+ }
+
+#print "\n\n" . format_data(\%network_configuration) . "\n\n";
+
+ # 'public' or 'private' wasn't specified, return all network interface
information
+ if (!$network_type) {
+ return \%network_configuration;
+ }
+
+ # Get the computer private IP address
+ my $computer_private_ip_address =
$self->data->get_computer_private_ip_address();
+ if (!$computer_private_ip_address) {
+ notify($ERRORS{'DEBUG'}, 0, "unable to retrieve computer
private IP address from reservation data");
return;
}
+
+ my $computer_public_ip_address;
+
+ my %public_interface;
+
+ # Loop through all of the network interfaces found
+ foreach my $interface_name (sort keys %network_configuration) {
+ my @ip_addresses = keys
%{$network_configuration{$interface_name}{ip_address}};
+ my $description =
$network_configuration{$interface_name}{description};
+ $description = '' if !$description;
- my %interfaces;
- my $interface_name;
- my $previous_dns = 0;
- for my $line (@{$output}) {
- # Find beginning of interface section
- if ($line =~ /ethernet adapter (.*):/i) {
- # Get the interface name
- $interface_name = $1;
-
- # Initialize hash values
- $interfaces{$interface_name}{dhcp_enabled} = '';
- $interfaces{$interface_name}{description} = '';
- $interfaces{$interface_name}{ip_address} = '';
- $interfaces{$interface_name}{subnet_mask} = '';
- $interfaces{$interface_name}{default_gateway} = '';
- $interfaces{$interface_name}{dns_servers} = ();
- } ## end if ($line =~ /ethernet adapter (.*):/i)
-
- # Check lines, see if they contain information to be saved
- $interfaces{$interface_name}{dhcp_enabled} = $1 if ($line =~
/dhcp enabled[\s\.:]*(.*)/i);
- $interfaces{$interface_name}{description} = $1 if ($line =~
/description[\s\.:]*(.*)/i);
- $interfaces{$interface_name}{ip_address} = $1 if ($line =~
/ip address[\s\.:]*([\d\.]*)/i);
- $interfaces{$interface_name}{subnet_mask} = $1 if ($line =~
/subnet mask[\s\.:]*([\d\.]*)/i);
- $interfaces{$interface_name}{default_gateway} = $1 if ($line =~
/default gateway[\s\.:]*([\d\.]*)/i);
- if ($line =~ /dns servers[\s\.:]*(.*)/i || ($previous_dns &&
$line =~ /^\s+([\d\.]+)/)) {
- push(@{$interfaces{$interface_name}{dns_servers}}, $1);
- $previous_dns = 1;
+ # Make sure an IP address was found
+ if (!...@ip_addresses) {
+ notify($ERRORS{'DEBUG'}, 0, "interface does not have an
ip address: $interface_name");
+ next;
}
- else {
- $previous_dns = 0;
+ elsif (grep(/$computer_private_ip_address/, @ip_addresses)) {
+ # If private interface information was requested,
return a hash containing only this interface
+ notify($ERRORS{'DEBUG'}, 0, "private interface found:
$interface_name, description: $description, address(es): " . join (", ",
@ip_addresses));
+ if ($network_type =~ /private/i) {
+ my %return_hash = ($interface_name =>
$network_configuration{$interface_name});
+ notify($ERRORS{'DEBUG'}, 0, "returning data for
private interface: $interface_name (" . join (", ", @ip_addresses) . ")");
+ return \%return_hash;
+ }
+ else {
+ next;
+ }
}
- } ## end for my $line (@{$output})
+
+ # Check if the interface should be ignored based on the name or
description
+ if ($interface_name =~ /loopback|vmnet|afs/i) {
+ notify($ERRORS{'DEBUG'}, 0, "interface ignored because
of name: $interface_name, description: $description, address(es): " . join (",
", @ip_addresses));
+ next;
+ }
+ elsif ($description =~ /loopback|virtual|afs/i) {
+ notify($ERRORS{'DEBUG'}, 0, "interface ignored because
of description: $interface_name, description: $description, address(es): " .
join (", ", @ip_addresses));
+ next;
+ }
+
+ # Loop through the IP addresses for the interface
+ # Once a public address is found, return the data for that
interface
+ for my $ip_address (@ip_addresses) {
+ # Split up the IP address being checked into its octets
+ my @octets = split(/\./, $ip_address);
+
+ # Determine if this is a private or public address
+ # Private:
+ # 10.0.0.0 - 10.255.255.255
+ # 172.16.0.0 - 172.16.31.255.255
+ # 192.168.0.0 - 192.168.255.255
+ if (($octets[0] == 10) ||
+ ($octets[0] != 172 && ($octets[1] >= 16 &&
$octets[1] <= 31)) ||
+ ($octets[0] == 192 && $octets[1] == 168)
+ ) {
+ notify($ERRORS{'DEBUG'}, 0, "interface found
with private address not matching private address for reservation:
$interface_name, description: $description, address(es): " . join (", ",
@ip_addresses));
+
+ if (keys(%public_interface)) {
+ notify($ERRORS{'DEBUG'}, 0, "already
found another interface with a private address not matching private address for
reservation, this one will be used if a public address isn't found");
+ next;
+ }
+ else {
+ notify($ERRORS{'DEBUG'}, 0, "interface
will be returned if another with a public address isn't found");
+ $public_interface{$interface_name} =
$network_configuration{$interface_name};
+ }
+ }
+ else {
+ notify($ERRORS{'DEBUG'}, 0, "public interface
found: $interface_name, description: $description, address(es): " . join (", ",
@ip_addresses));
+ my %return_hash = ($interface_name =>
$network_configuration{$interface_name});
+ notify($ERRORS{'DEBUG'}, 0, "returning data for
public interface: $interface_name (" . join (", ", @ip_addresses) . ")");
+ return \%return_hash;
+ }
+ }
+ }
- return \%interfaces;
+ if ($network_type =~ /private/i) {
+ notify($ERRORS{'WARNING'}, 0, "did not find an interface using
the private IP address for the reservation: $computer_private_ip_address\n" .
format_data(\%network_configuration));
+ return;
+ }
+ elsif (keys(%public_interface)) {
+ notify($ERRORS{'OK'}, 0, "did not find a public interface using
a public IP address, but found interface using private IP address not matching
reservation private IP address, returning data for public interface:\n" .
format_data(\%public_interface));
+ return \%public_interface;
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "unable to determine the public
interface:\n" . format_data(\%network_configuration));
+ return;
+ }
+
} ## end sub get_network_configuration
#/////////////////////////////////////////////////////////////////////////////
-=head2 get_private_interface_names
+=head2 get_private_interface_name
Parameters :
- Returns : array containing names of private interfaces
+ Returns :
Description :
=cut
-sub get_private_interface_names {
+sub get_private_interface_name {
my $self = shift;
if (ref($self) !~ /windows/i) {
notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a
function, it must be called as a class method");
return;
}
- my $network_configuration = $self->get_network_configuration();
-
# Make sure network configuration was retrieved
+ my $network_configuration = $self->get_network_configuration('private');
if (!$network_configuration) {
- notify($ERRORS{'WARNING'}, 0, "unable to determine private
adapter name, failed to retrieve network configuration");
+ notify($ERRORS{'WARNING'}, 0, "unable to retrieve network
configuration");
return;
}
+
+ my $interface_name = (keys(%{$network_configuration}))[0];
+ notify($ERRORS{'DEBUG'}, 0, "returning private interface name:
$interface_name");
+
+ return $interface_name;
+}
- my @private_interface_names;
-
- # Loop through all of the network interfaces
- foreach my $interface_name (sort keys %{$network_configuration}) {
- my $ip_address =
$network_configuration->{$interface_name}{ip_address};
- my $description =
$network_configuration->{$interface_name}{description};
- $description = '' if !$description;
-
- # Make sure an IP address was found
- if (!$ip_address) {
- notify($ERRORS{'DEBUG'}, 0, "interface does not have an
ip address: $interface_name");
- next;
- }
-
- # Split the ip address up
- my @octets = split(/\./, $ip_address);
+#/////////////////////////////////////////////////////////////////////////////
- # Figure out if this is a private or public address
+=head2 get_public_interface_name
- # Private: 10.0.0.0 10.255.255.255 16,777,216
- if ($interface_name =~ /loopback|virtual|pseudo|vmware|afs/i) {
- notify($ERRORS{'DEBUG'}, 0, "interface ignored because
of name: $interface_name, description: $description, address: $ip_address");
- next;
- }
- elsif (($octets[0] == 10) ||
- ($octets[0] != 172 && ($octets[1] >= 16 &&
$octets[1] <= 31)) ||
- ($octets[0] == 192 && $octets[1] == 168)
- ) {
- # Check if a matching interface was already found
- if (@private_interface_names) {
- notify($ERRORS{'WARNING'}, 0, "multiple
interfaces found with private IP address");
- }
+ Parameters :
+ Returns :
+ Description :
- push(@private_interface_names, $interface_name);
- }
-
- } ## end foreach my $interface_name (sort keys
%{$network_configuration...
+=cut
- # Check if a matching interface was found
- if (!...@private_interface_names) {
- notify($ERRORS{'WARNING'}, 0, "private interface was not
found");
+sub get_public_interface_name {
+ my $self = shift;
+ if (ref($self) !~ /windows/i) {
+ notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a
function, it must be called as a class method");
return;
}
- notify($ERRORS{'DEBUG'}, 0, "returning private interface array: " .
join(", ", @private_interface_names));
- return @private_interface_names;
-} ## end sub get_private_interface_names
+ # Make sure network configuration was retrieved
+ my $network_configuration = $self->get_network_configuration('public');
+ if (!$network_configuration) {
+ notify($ERRORS{'WARNING'}, 0, "unable to retrieve network
configuration");
+ return;
+ }
+
+ my $interface_name = (keys(%{$network_configuration}))[0];
+ notify($ERRORS{'DEBUG'}, 0, "returning public interface name:
$interface_name");
+
+ return $interface_name;
+}
#/////////////////////////////////////////////////////////////////////////////
-=head2 get_public_interface_names
+=head2 get_private_ip_addresses
Parameters :
- Returns : array containing names of public interfaces
+ Returns :
Description :
=cut
-sub get_public_interface_names {
+sub get_private_ip_addresses {
my $self = shift;
if (ref($self) !~ /windows/i) {
notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a
function, it must be called as a class method");
return;
}
- my $network_configuration = $self->get_network_configuration();
-
# Make sure network configuration was retrieved
+ my $network_configuration = $self->get_network_configuration('private');
if (!$network_configuration) {
- notify($ERRORS{'WARNING'}, 0, "unable to determine public
adapter name, failed to retrieve network configuration");
+ notify($ERRORS{'WARNING'}, 0, "unable to retrieve network
configuration");
return;
}
+
+ my $interface_name = (keys(%{$network_configuration}))[0];
+
+ my $ip_address = $network_configuration->{$interface_name}{ip_address};
+ notify($ERRORS{'DEBUG'}, 0, "returning IP address: $ip_address");
+
+ return $ip_address;
+}
- my @public_interface_names;
-
- # Loop through all of the network interfaces
- foreach my $interface_name (sort keys %{$network_configuration}) {
- my $ip_address =
$network_configuration->{$interface_name}{ip_address};
- my $description =
$network_configuration->{$interface_name}{description};
- $description = '' if !$description;
-
- # Make sure an IP address was found
- if (!$ip_address) {
- notify($ERRORS{'DEBUG'}, 0, "interface does not have an
ip address: $interface_name");
- next;
- }
+#/////////////////////////////////////////////////////////////////////////////
- # Split the ip address up
- my @octets = split(/\./, $ip_address);
+=head2 get_public_ip_addresses
- # Figure out if this is a public or public address
- # Igore loopback and other interface names
- if ($interface_name =~ /loopback|virtual|pseudo|vmware|afs/i) {
- notify($ERRORS{'DEBUG'}, 0, "interface ignored because
of name: $interface_name, description: $description, address: $ip_address");
- next;
- }
- # Private: 10.0.0.0 10.255.255.255 16,777,216
- elsif ($octets[0] == 10) {
- next;
- }
- # Private: 172.16.0.0 - 172.31.255.255
- elsif ($octets[0] != 172 && ($octets[1] >= 16 && $octets[1] <=
31)) {
- next;
- }
- # Private: 192.168.0.0 - 192.168.255.255
- elsif ($octets[0] == 192 && $octets[1] == 168) {
- next;
- }
- # Loopback: 127.0.0.0 to 127.255.255.255
- elsif ($octets[0] == 127) {
- next;
- }
- else {
- # Check if a matching interface was already found
- if (@public_interface_names) {
- notify($ERRORS{'WARNING'}, 0, "multiple
interfaces found with public IP address");
- }
+ Parameters :
+ Returns :
+ Description :
- push(@public_interface_names, $interface_name);
- }
- } ## end foreach my $interface_name (sort keys
%{$network_configuration...
+=cut
- # Check if a matching interface was found
- if (!...@public_interface_names) {
- notify($ERRORS{'WARNING'}, 0, "public interface was not found");
+sub get_public_ip_addresses {
+ my $self = shift;
+ if (ref($self) !~ /windows/i) {
+ notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a
function, it must be called as a class method");
return;
}
- notify($ERRORS{'DEBUG'}, 0, "returning public interface array: " .
join(", ", @public_interface_names));
- return @public_interface_names;
-} ## end sub get_public_interface_names
+ # Make sure network configuration was retrieved
+ my $network_configuration = $self->get_network_configuration('public');
+ if (!$network_configuration) {
+ notify($ERRORS{'WARNING'}, 0, "unable to retrieve network
configuration");
+ return;
+ }
+
+ my $interface_name = (keys(%{$network_configuration}))[0];
+
+ my $ip_address = $network_configuration->{$interface_name}{ip_address};
+ notify($ERRORS{'DEBUG'}, 0, "returning IP address: $ip_address");
+
+ return $ip_address;
+}
#/////////////////////////////////////////////////////////////////////////////
@@ -4224,14 +4396,14 @@
my $interface_name_argument = shift;
my @interface_names;
if (!$interface_name_argument) {
- push(@interface_names, $self->get_public_interface_names());
- push(@interface_names, $self->get_private_interface_names());
+ push(@interface_names, $self->get_public_interface_name());
+ push(@interface_names, $self->get_private_interface_name());
}
elsif ($interface_name_argument =~ /public/i) {
- push(@interface_names, $self->get_public_interface_names());
+ push(@interface_names, $self->get_public_interface_name());
}
elsif ($interface_name_argument =~ /private/i) {
- push(@interface_names, $self->get_private_interface_names());
+ push(@interface_names, $self->get_private_interface_name());
}
else {
push(@interface_names, $interface_name_argument);
@@ -6023,6 +6195,103 @@
#/////////////////////////////////////////////////////////////////////////////
+=head2 run_newsid_new
+
+ Parameters :
+ Returns : 1 success 0 failure
+ Description :
+
+=cut
+
+sub run_newsid_new {
+ my $self = shift;
+ if (ref($self) !~ /windows/i) {
+ notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a
function, it must be called as a class method");
+ return;
+ }
+
+ my $reservation_id = $self->data->get_reservation_id();
+ my $management_node_keys = $self->data->get_management_node_keys();
+ my $computer_node_name = $self->data->get_computer_node_name();
+ my $computer_id = $self->data->get_computer_id();
+
+ my $registry_string .= <<'EOF';
+Windows Registry Editor Version 5.00
+
+; This registry file contains the entries to bypass the license agreement when
newsid.exe is run
+
+[HKEY_CURRENT_USER\\Software\\Sysinternals\\NewSID]
+"EulaAccepted"=dword:00000001
+EOF
+
+ # Import the string into the registry
+ if ($self->import_registry_string($registry_string)) {
+ notify($ERRORS{'DEBUG'}, 0, "added newsid eulaaccepted registry
string");
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "failed to add newsid
eulaaccepted registry string");
+ }
+
+ # Attempt to run newsid.exe
+ # newsid.exe should automatically reboot the computer
+ # It isn't done when the process exits, newsid.exe starts working and
immediately returns
+ # NewSid.exe [/a[[/n]|[/d <reboot delay (in seconds)>]]][<new computer
name>]
+ # /a - run without prompts
+ # /n - Don't reboot after automatic run
+ my $newsid_command =
"\"$NODE_CONFIGURATION_DIRECTORY/Utilities/newsid.exe\" /a
\"$computer_node_name\"";
+
+ my $newsid_start_processing_time = time();
+ my ($newsid_exit_status, $newsid_output) =
run_ssh_command($computer_node_name, $management_node_keys, $newsid_command);
+ my $newsid_end_processing_time = time();
+
+ if (defined($newsid_exit_status) && $newsid_exit_status == 0) {
+ notify($ERRORS{'DEBUG'}, 0, "ran newsid.exe on
$computer_node_name");
+ }
+ elsif (defined($newsid_exit_status)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to run newsid.exe on
$computer_node_name, exit status: $newsid_exit_status,
output:\...@{$newsid_output}");
+ return;
+ }
+ else {
+ notify($ERRORS{'WARNING'}, 0, "failed to run ssh command to run
newsid.exe on $computer_node_name");
+ return;
+ }
+ my $newsid_processing_duration = ($newsid_end_processing_time -
$newsid_start_processing_time);
+ notify($ERRORS{'DEBUG'}, 0, "newsid.exe finished processing, newsid.exe
took $newsid_processing_duration seconds");
+ insertloadlog($reservation_id, $computer_id, "info", "newsid.exe
processing took $newsid_processing_duration seconds");
+
+ # After launching newsid.exe, wait for machine to become unresponsive
+ if (!$self->wait_for_no_ping(10)) {
+ notify($ERRORS{'WARNING'}, 0, "failed to run newsid.exe,
$computer_node_name never became unresponsive after waiting 10 minutes");
+ return;
+ }
+ my $newsid_shutdown_time = time();
+ notify($ERRORS{'DEBUG'}, 0, "newsid.exe initiated reboot,
$computer_node_name is unresponsive, reboot initialization took " .
($newsid_shutdown_time - $newsid_end_processing_time) . " seconds");
+
+ # Wait maximum of 6 minutes for the computer to come back up
+ if (!$self->wait_for_ping(6)) {
+ notify($ERRORS{'WARNING'}, 0, "$computer_node_name never
responded to ping, it never came back up");
+ return;
+ }
+
+ my $newsid_ping_respond_time = time();
+ notify($ERRORS{'DEBUG'}, 0, "reboot nearly complete on
$computer_node_name after running newsid.exe, ping response took " .
($newsid_ping_respond_time - $newsid_shutdown_time) . " seconds");
+
+ # Ping successful, try ssh
+ notify($ERRORS{'OK'}, 0, "waiting for ssh to respond on
$computer_node_name");
+ if (!$self->wait_for_ssh(3)) {
+ notify($ERRORS{'WARNING'}, 0, "newsid.exe failed,
$computer_node_name rebooted but ssh never became available");
+ return;
+ }
+ my $newsid_ssh_respond_time = time();
+ my $newsid_entire_duration = ($newsid_ssh_respond_time -
$newsid_start_processing_time);
+ notify($ERRORS{'OK'}, 0, "newsid.exe succeeded on $computer_node_name,
entire process took $newsid_entire_duration seconds");
+ insertloadlog($reservation_id, $computer_id, "info", "entire newsid.exe
process took $newsid_entire_duration seconds");
+
+ return 1;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
1;
__END__