From: Michael Gernoth Date: Tue, 27 Jan 2009 07:05:51 +0000 (+0100) Subject: start of a CLI from the RSB S2 card X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/rsbs2/commitdiff_plain/190cff1382ffb8c929861f8c19983c778f3f0559 start of a CLI from the RSB S2 card --- 190cff1382ffb8c929861f8c19983c778f3f0559 diff --git a/rsbs2 b/rsbs2 new file mode 100755 index 0000000..4da514f --- /dev/null +++ b/rsbs2 @@ -0,0 +1,194 @@ +#!/usr/bin/perl -w + +use LWP::UserAgent; +use XML::Simple; +use Data::Dumper; +use MIME::Base64; +use Digest::MD5 qw(md5); + +my $ua = LWP::UserAgent->new; +my $sid; + +my $host = "192.168.50.6"; +my $user = "admin"; +my $pass = "admin"; + +sub _crc16 { + my $str = shift; + my $crc = 0; + for my $k (0..length($str)-1) { + $crc ^= ord(substr($str, $k, 1)) << 8; + for (0..7) { + $crc = (($crc & 0x8000) == 32768 ? ($crc<<1) ^ 0x1021 : $crc<<1); + } + } + $crc = $crc & 0xFFFF; + return $crc; +} + +sub _hash { + my ($password, $challenge) = @_; + my @challenge_bytes = unpack 'c16', decode_base64($challenge); + my @pwd_hash = unpack 'c16', md5($password); + my @xor_bytes; + for my $i (0..15) { + $xor_bytes[$i] = $challenge_bytes[$i] ^ $pwd_hash[$i]; + }; + my $hash = md5(pack 'c16', @xor_bytes); + my $crc = _crc16($hash); + $hash .= chr($crc & 0xff) . chr($crc >> 8 & 0xff); + return encode_base64($hash, ""); +} + +sub _req { + my $xml = shift; + $request = HTTP::Request->new(POST => "http://${host}/cgi/bin"); + $request->header(Cookie => "sid=$sid"); + $request->content_type('application/x-www-form-urlencoded'); + $request->content($xml); + $response = $ua->request($request); + die("Error in request: " . $response->status_line . "\n") unless ($response->is_success); + XMLin($response->content); +} + +sub _getprop { + my $property = shift; + + my $reqstr=''; + my $resp = _req($reqstr); + + if ($resp->{RESP}->{RC} ne '0x0') { + "Error: " . $resp->{RESP}->{RC}; + } else { + $resp->{RESP}->{PROPLIST}->{PROP}->{VAL}; + } +} + +sub logout { + print "Logout\n"; + my $request = HTTP::Request->new(GET => "http://${host}/cgi/logout"); + $request->header(Cookie => "sid=$sid"); + my $response = $ua->request($request); + die("While trying to logout: " . $response->status_line . "\n") unless ($response->is_success); + + my $xmlin = XMLin($response->decoded_content); + die "Error logging out: ".$xmlin->{RC} if ($xmlin->{RC} ne '0x0'); +} + +sub setprop { + my $property = shift; + my $value = shift; + + my $oldval = _getprop($property); + + if ($value eq $oldval) { + print "${property} is already ${value}\n"; + return; + } + + my $reqstr=''.$value.''; + my $res = _req($reqstr); + + if ($res->{RESP}->{RC} ne '0x0') { + print "Error setting ${property} to ${value}: ".$res->{RESP}->{RC}."\n"; + } else { + print "${property}: ${oldval} -> ${value}\n"; + } +} + +sub serveraction { + my $action = shift; + + print "${action}...\n"; + my $reqstr=''.$action.''; + my $res = _req($reqstr); + + if ($res->{RESP}->{RC} ne '0x0') { + print "FAILED:".$res->{RESP}->{RC}."\n"; + } +} + +sub showprop { + my $property = shift; + + print "${property}: " . _getprop($property) . "\n"; +} + +#Login... +my $response = $ua->get("http://${host}/cgi/challenge"); +die $response->status_line if (!($response->is_success)); + +my $xmlin = XMLin($response->decoded_content); +die "Error getting Challenge: ".$xmlin->{RC} if ($xmlin->{RC} ne '0x0'); +my $challenge = $xmlin->{CHALLENGE}; +print "Challenge: ${challenge}\n"; + +$sid = $response->headers->header('Set-Cookie'); +die "No SessionID!" if (!defined($sid)); +chomp($sid); +$sid =~ s/.*sid=(.*);.*/$1/; +print "SID: ${sid}\n"; + +my $login_hash = _hash($pass, $challenge); +print "Hash: ${login_hash}\n"; + +my $request = HTTP::Request->new(GET => "http://${host}/cgi/login?user=${user}&hash=${login_hash}"); +$request->header(Cookie => "sid=$sid"); +$response = $ua->request($request); +die("While trying to login: " . $response->status_line . "\n") unless ($response->is_success); + +$xmlin = XMLin($response->decoded_content); +die "Error logging in: ".$xmlin->{RC} if ($xmlin->{RC} ne '0x0'); + +$reqstr=''; +my $boarddesc64 = _req($reqstr)->{RESP}->{BPROPLIST}->{BPROP}->{VAL}; +my $boarddesc = decode_base64($boarddesc64); +my @board = split(//, $boarddesc); +foreach my $byte (@board) { + printf ("0x%02x ", ord($byte)); +} +print "\n"; +printf("byte 22: 0x%x\n", ord($board[22])); +$board[22] = chr(ord($board[22]) | 0x3); +printf("byte 22: 0x%x\n", ord($board[22])); +my $boarddesc_new = encode_base64(join('',@board)); +chomp($boarddesc_new); +print "BOARD_DESCRIPTION: ${boarddesc64} -> ${boarddesc_new}\n"; +#AQFQAAAAAAAAAAAAiAKsAdAFAABqOgAABgABAAAAAAA= + +showprop("FP_REMOTE_POWER"); +showprop("FP_REMOTE_BOOT"); +showprop("SERVER_HARD_RESET_VIA_IPMI"); +showprop("SERVER_HARD_RESET_PULSE_MS"); +showprop("SERVER_POWER_CHANGE_VIA_IPMI"); +showprop("SERVER_POWER_ON_MODE"); +showprop("SERVER_POWER_ON_PULSE_MS"); +showprop("SERVER_POWER_OFF_MODE"); +showprop("SERVER_POWER_OFF_PULSE_MS"); + +#server_power_on modes: (com/agilent/rmc/mgui/panels/PowerMgmtConf.class) +#0: l_pmconf_option_disabled +#1: l_pmconf_option_atx +#2: l_pmconf_option_relay +#default: disabled + +my $pmode = 2; + +setprop("SERVER_HARD_RESET_VIA_IPMI", "FALSE"); +setprop("SERVER_POWER_CHANGE_VIA_IPMI", "FALSE"); +#Power Mgmt. Pane +setprop("FP_REMOTE_POWER", "TRUE"); +#PM Mode +setprop("SERVER_POWER_ON_MODE", sprintf("0x%x", $pmode)); +setprop("SERVER_POWER_OFF_MODE", sprintf("0x%x", $pmode)); + +#$reqstr=''.$boarddesc_new.''; +#print $reqstr."\n"; +#print Dumper(_req($reqstr)); +setprop("BOARD_DESCRIPTION", $boarddesc_new); + +#serveraction("hardreset"); +serveraction("powerup"); +serveraction("powerdown"); + +logout();