1#!/usr/local/bin/perl 2# (c) Artica Soluciones Tecnologicas 2010 3# This script is licensed under GPL v2 licence. 4 5use strict; 6use POSIX qw(floor); 7 8 9# TODO: Let more massive changes (fields) to be changed. 10 11# Used to calculate the MD5 checksum of a string 12use constant MOD232 => 2**32; 13if ($#ARGV != 1) { 14 print "This tool is used to do a massive change in all remote configuration\n"; 15 print "files for the remote agents, and change a list of files, given it's \n"; 16 print "agent name (case sensisitive)\n\n"; 17 print "Usage: change_remoteconfig.pl <file_with_server_names> <server_ip>\n\n"; 18 exit; 19} 20 21my $fichero_nombres = $ARGV[0]; 22my $servidor_destino = $ARGV[1]; 23 24# Ruta al directorio data_in 25my $data_in = "/var/spool/pandora/data_in"; 26print "Massive changes are set. Ready to modify files at $data_in/conf and the MD5 hashes in $data_in/md5\n"; 27 28md5_init(); 29open (NOMBRES, $fichero_nombres) or die ("File $fichero_nombres not readable : $!"); 30my @servidores = <NOMBRES>; 31close (NOMBRES); 32print "Server IP address '$servidor_destino' is about to be changed in these agents:\n"; 33print "Total agents: ". scalar(@servidores)."\n"; 34print @servidores; 35 36print "Waiting 10 seconds. Press ^C to cancel.n\n"; 37sleep (10); 38 39foreach (@servidores) { 40 my $servidor = $_; 41 chomp ($servidor); 42 print "Procesing: $servidor " ; 43 my $nombre_md5 = md5($servidor); 44 my $fichero_conf = "$data_in/conf/$nombre_md5.conf"; 45 # Se lee el fichero y se cambia la linea correspondiente 46 open (CONF_FILE, $fichero_conf)or print ("Could not open file '$fichero_conf': $!."); 47 open (NEW_CONF_FILE, '>', "$fichero_conf.new")or print ("Could not open file '$fichero_conf.new': $!."); 48 while (my $linea = <CONF_FILE>) { 49 if ($linea =~ m/^\s*server_ip.*/) { 50 $linea = "server_ip\t$servidor_destino\n"; 51 } 52 print NEW_CONF_FILE $linea; 53 } 54 close (CONF_FILE); 55 close (NEW_CONF_FILE); 56 `mv $fichero_conf.new $fichero_conf`; 57 58 # Calculate the new configuration file MD5 digest 59 open (CONF_FILE, $fichero_conf)or print ("Could not open file '$fichero_conf': $!."); 60 binmode(CONF_FILE); 61 my $conf_md5 = md5 (join ('', <CONF_FILE>)); 62 close (CONF_FILE); 63 print "Nuevo MD5 : $conf_md5\t"; 64 my $fichero_md5 = "$data_in/md5/$nombre_md5.md5"; 65 `echo -n "$conf_md5" > $fichero_md5`; 66} 67 68############################################################################### 69# MD5 leftrotate function. See http://en.wikipedia.org/wiki/MD5#Pseudocode. 70############################################################################### 71sub leftrotate ($$) { 72 my ($x, $c) = @_; 73 74 return (0xFFFFFFFF & ($x << $c)) | ($x >> (32 - $c)); 75} 76 77############################################################################### 78# Initialize some variables needed by the MD5 algorithm. 79# See http://en.wikipedia.org/wiki/MD5#Pseudocode. 80############################################################################### 81my (@R, @K); 82sub md5_init () { 83 84 # R specifies the per-round shift amounts 85 @R = (7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 86 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 87 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 88 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21); 89 90 # Use binary integer part of the sines of integers (radians) as constants 91 for (my $i = 0; $i < 64; $i++) { 92 $K[$i] = floor(abs(sin($i + 1)) * MOD232); 93 } 94} 95 96############################################################################### 97# Return the MD5 checksum of the given string. 98# Pseudocode from http://en.wikipedia.org/wiki/MD5#Pseudocode. 99############################################################################### 100sub md5 ($) { 101 my $str = shift; 102 103 # Note: All variables are unsigned 32 bits and wrap modulo 2^32 when calculating 104 105 # Initialize variables 106 my $h0 = 0x67452301; 107 my $h1 = 0xEFCDAB89; 108 my $h2 = 0x98BADCFE; 109 my $h3 = 0x10325476; 110 111 # Pre-processing 112 my $msg = unpack ("B*", pack ("A*", $str)); 113 my $bit_len = length ($msg); 114 115 # Append "1" bit to message 116 $msg .= '1'; 117 118 # Append "0" bits until message length in bits â¡ 448 (mod 512) 119 $msg .= '0' while ((length ($msg) % 512) != 448); 120 121 # Append bit /* bit, not byte */ length of unpadded message as 64-bit little-endian integer to message 122 $msg .= unpack ("B64", pack ("VV", $bit_len)); 123 124 # Process the message in successive 512-bit chunks 125 for (my $i = 0; $i < length ($msg); $i += 512) { 126 127 my @w; 128 my $chunk = substr ($msg, $i, 512); 129 130 # Break chunk into sixteen 32-bit little-endian words w[i], 0 <= i <= 15 131 for (my $j = 0; $j < length ($chunk); $j += 32) { 132 push (@w, unpack ("V", pack ("B32", substr ($chunk, $j, 32)))); 133 } 134 135 # Initialize hash value for this chunk 136 my $a = $h0; 137 my $b = $h1; 138 my $c = $h2; 139 my $d = $h3; 140 my $f; 141 my $g; 142 143 # Main loop 144 for (my $y = 0; $y < 64; $y++) { 145 if ($y <= 15) { 146 $f = $d ^ ($b & ($c ^ $d)); 147 $g = $y; 148 } 149 elsif ($y <= 31) { 150 $f = $c ^ ($d & ($b ^ $c)); 151 $g = (5 * $y + 1) % 16; 152 } 153 elsif ($y <= 47) { 154 $f = $b ^ $c ^ $d; 155 $g = (3 * $y + 5) % 16; 156 } 157 else { 158 $f = $c ^ ($b | (0xFFFFFFFF & (~ $d))); 159 $g = (7 * $y) % 16; 160 } 161 162 my $temp = $d; 163 $d = $c; 164 $c = $b; 165 $b = ($b + leftrotate (($a + $f + $K[$y] + $w[$g]) % MOD232, $R[$y])) % MOD232; 166 $a = $temp; 167 } 168 169 # Add this chunk's hash to result so far 170 $h0 = ($h0 + $a) % MOD232; 171 $h1 = ($h1 + $b) % MOD232; 172 $h2 = ($h2 + $c) % MOD232; 173 $h3 = ($h3 + $d) % MOD232; 174 } 175 176 # Digest := h0 append h1 append h2 append h3 #(expressed as little-endian) 177 return unpack ("H*", pack ("V", $h0)) . unpack ("H*", pack ("V", $h1)) . unpack ("H*", pack ("V", $h2)) . unpack ("H*", pack ("V", $h3)); 178} 179 180 181