]>
Commit | Line | Data |
---|---|---|
190cff13 MG |
1 | #!/usr/bin/perl -w |
2 | ||
3 | use LWP::UserAgent; | |
4 | use XML::Simple; | |
5 | use Data::Dumper; | |
6 | use MIME::Base64; | |
7 | use Digest::MD5 qw(md5); | |
8 | ||
9 | my $ua = LWP::UserAgent->new; | |
10 | my $sid; | |
11 | ||
12 | my $host = "192.168.50.6"; | |
13 | my $user = "admin"; | |
14 | my $pass = "admin"; | |
15 | ||
16 | sub _crc16 { | |
17 | my $str = shift; | |
18 | my $crc = 0; | |
19 | for my $k (0..length($str)-1) { | |
20 | $crc ^= ord(substr($str, $k, 1)) << 8; | |
21 | for (0..7) { | |
22 | $crc = (($crc & 0x8000) == 32768 ? ($crc<<1) ^ 0x1021 : $crc<<1); | |
23 | } | |
24 | } | |
25 | $crc = $crc & 0xFFFF; | |
26 | return $crc; | |
27 | } | |
28 | ||
29 | sub _hash { | |
30 | my ($password, $challenge) = @_; | |
31 | my @challenge_bytes = unpack 'c16', decode_base64($challenge); | |
32 | my @pwd_hash = unpack 'c16', md5($password); | |
33 | my @xor_bytes; | |
34 | for my $i (0..15) { | |
35 | $xor_bytes[$i] = $challenge_bytes[$i] ^ $pwd_hash[$i]; | |
36 | }; | |
37 | my $hash = md5(pack 'c16', @xor_bytes); | |
38 | my $crc = _crc16($hash); | |
39 | $hash .= chr($crc & 0xff) . chr($crc >> 8 & 0xff); | |
40 | return encode_base64($hash, ""); | |
41 | } | |
42 | ||
43 | sub _req { | |
44 | my $xml = shift; | |
45 | $request = HTTP::Request->new(POST => "http://${host}/cgi/bin"); | |
46 | $request->header(Cookie => "sid=$sid"); | |
47 | $request->content_type('application/x-www-form-urlencoded'); | |
48 | $request->content($xml); | |
49 | $response = $ua->request($request); | |
50 | die("Error in request: " . $response->status_line . "\n") unless ($response->is_success); | |
51 | XMLin($response->content); | |
52 | } | |
53 | ||
54 | sub _getprop { | |
55 | my $property = shift; | |
56 | ||
57 | my $reqstr='<?xml version="1.0"?><?RMCXML version="1.0"?><RMCSEQ><REQ CMD="propget"><PROPLIST><PROP NAME="'.$property.'"/></PROPLIST></REQ></RMCSEQ>'; | |
58 | my $resp = _req($reqstr); | |
59 | ||
60 | if ($resp->{RESP}->{RC} ne '0x0') { | |
61 | "Error: " . $resp->{RESP}->{RC}; | |
62 | } else { | |
63 | $resp->{RESP}->{PROPLIST}->{PROP}->{VAL}; | |
64 | } | |
65 | } | |
66 | ||
67 | sub logout { | |
68 | print "Logout\n"; | |
69 | my $request = HTTP::Request->new(GET => "http://${host}/cgi/logout"); | |
70 | $request->header(Cookie => "sid=$sid"); | |
71 | my $response = $ua->request($request); | |
72 | die("While trying to logout: " . $response->status_line . "\n") unless ($response->is_success); | |
73 | ||
74 | my $xmlin = XMLin($response->decoded_content); | |
75 | die "Error logging out: ".$xmlin->{RC} if ($xmlin->{RC} ne '0x0'); | |
76 | } | |
77 | ||
78 | sub setprop { | |
79 | my $property = shift; | |
80 | my $value = shift; | |
81 | ||
82 | my $oldval = _getprop($property); | |
83 | ||
84 | if ($value eq $oldval) { | |
85 | print "${property} is already ${value}\n"; | |
86 | return; | |
87 | } | |
88 | ||
89 | my $reqstr='<?xml version="1.0"?><?RMCXML version="1.0"?><RMCSEQ><REQ CMD="propset"><PROP NAME="'.$property.'"><VAL>'.$value.'</VAL></PROP></REQ></RMCSEQ>'; | |
90 | my $res = _req($reqstr); | |
91 | ||
92 | if ($res->{RESP}->{RC} ne '0x0') { | |
93 | print "Error setting ${property} to ${value}: ".$res->{RESP}->{RC}."\n"; | |
94 | } else { | |
95 | print "${property}: ${oldval} -> ${value}\n"; | |
96 | } | |
97 | } | |
98 | ||
99 | sub serveraction { | |
100 | my $action = shift; | |
101 | ||
102 | print "${action}...\n"; | |
103 | my $reqstr='<?xml version="1.0"?><?RMCXML version="1.0"?><RMCSEQ><REQ CMD="serveraction"><ACT>'.$action.'</ACT></REQ></RMCSEQ>'; | |
104 | my $res = _req($reqstr); | |
105 | ||
106 | if ($res->{RESP}->{RC} ne '0x0') { | |
107 | print "FAILED:".$res->{RESP}->{RC}."\n"; | |
108 | } | |
109 | } | |
110 | ||
111 | sub showprop { | |
112 | my $property = shift; | |
113 | ||
114 | print "${property}: " . _getprop($property) . "\n"; | |
115 | } | |
116 | ||
117 | #Login... | |
118 | my $response = $ua->get("http://${host}/cgi/challenge"); | |
119 | die $response->status_line if (!($response->is_success)); | |
120 | ||
121 | my $xmlin = XMLin($response->decoded_content); | |
122 | die "Error getting Challenge: ".$xmlin->{RC} if ($xmlin->{RC} ne '0x0'); | |
123 | my $challenge = $xmlin->{CHALLENGE}; | |
124 | print "Challenge: ${challenge}\n"; | |
125 | ||
126 | $sid = $response->headers->header('Set-Cookie'); | |
127 | die "No SessionID!" if (!defined($sid)); | |
128 | chomp($sid); | |
129 | $sid =~ s/.*sid=(.*);.*/$1/; | |
130 | print "SID: ${sid}\n"; | |
131 | ||
132 | my $login_hash = _hash($pass, $challenge); | |
133 | print "Hash: ${login_hash}\n"; | |
134 | ||
135 | my $request = HTTP::Request->new(GET => "http://${host}/cgi/login?user=${user}&hash=${login_hash}"); | |
136 | $request->header(Cookie => "sid=$sid"); | |
137 | $response = $ua->request($request); | |
138 | die("While trying to login: " . $response->status_line . "\n") unless ($response->is_success); | |
139 | ||
140 | $xmlin = XMLin($response->decoded_content); | |
141 | die "Error logging in: ".$xmlin->{RC} if ($xmlin->{RC} ne '0x0'); | |
142 | ||
143 | $reqstr='<?xml version="1.0"?><?RMCXML version="1.0"?><RMCSEQ><REQ CMD="boardpropget"><BPROPLIST><BPROP NAME="BOARD_DESCRIPTION"/></BPROPLIST></REQ></RMCSEQ>'; | |
144 | my $boarddesc64 = _req($reqstr)->{RESP}->{BPROPLIST}->{BPROP}->{VAL}; | |
145 | my $boarddesc = decode_base64($boarddesc64); | |
146 | my @board = split(//, $boarddesc); | |
147 | foreach my $byte (@board) { | |
148 | printf ("0x%02x ", ord($byte)); | |
149 | } | |
150 | print "\n"; | |
151 | printf("byte 22: 0x%x\n", ord($board[22])); | |
152 | $board[22] = chr(ord($board[22]) | 0x3); | |
153 | printf("byte 22: 0x%x\n", ord($board[22])); | |
154 | my $boarddesc_new = encode_base64(join('',@board)); | |
155 | chomp($boarddesc_new); | |
156 | print "BOARD_DESCRIPTION: ${boarddesc64} -> ${boarddesc_new}\n"; | |
157 | #AQFQAAAAAAAAAAAAiAKsAdAFAABqOgAABgABAAAAAAA= | |
158 | ||
159 | showprop("FP_REMOTE_POWER"); | |
160 | showprop("FP_REMOTE_BOOT"); | |
161 | showprop("SERVER_HARD_RESET_VIA_IPMI"); | |
162 | showprop("SERVER_HARD_RESET_PULSE_MS"); | |
163 | showprop("SERVER_POWER_CHANGE_VIA_IPMI"); | |
164 | showprop("SERVER_POWER_ON_MODE"); | |
165 | showprop("SERVER_POWER_ON_PULSE_MS"); | |
166 | showprop("SERVER_POWER_OFF_MODE"); | |
167 | showprop("SERVER_POWER_OFF_PULSE_MS"); | |
168 | ||
169 | #server_power_on modes: (com/agilent/rmc/mgui/panels/PowerMgmtConf.class) | |
170 | #0: l_pmconf_option_disabled | |
171 | #1: l_pmconf_option_atx | |
172 | #2: l_pmconf_option_relay | |
173 | #default: disabled | |
174 | ||
175 | my $pmode = 2; | |
176 | ||
177 | setprop("SERVER_HARD_RESET_VIA_IPMI", "FALSE"); | |
178 | setprop("SERVER_POWER_CHANGE_VIA_IPMI", "FALSE"); | |
179 | #Power Mgmt. Pane | |
180 | setprop("FP_REMOTE_POWER", "TRUE"); | |
181 | #PM Mode | |
182 | setprop("SERVER_POWER_ON_MODE", sprintf("0x%x", $pmode)); | |
183 | setprop("SERVER_POWER_OFF_MODE", sprintf("0x%x", $pmode)); | |
184 | ||
185 | #$reqstr='<?xml version="1.0"?><?RMCXML version="1.0"?><RMCSEQ><REQ CMD="boardpropset"><BPROP NAME="BOARD_DESCRIPTION"><VAL>'.$boarddesc_new.'</VAL></BPROP></REQ></RMCSEQ>'; | |
186 | #print $reqstr."\n"; | |
187 | #print Dumper(_req($reqstr)); | |
188 | setprop("BOARD_DESCRIPTION", $boarddesc_new); | |
189 | ||
190 | #serveraction("hardreset"); | |
191 | serveraction("powerup"); | |
192 | serveraction("powerdown"); | |
193 | ||
194 | logout(); |