]> git.defcon.no Git - hermes/blob - guc-clients/reset-tool
Remote reset of phones, using sipsak NOTIFY
[hermes] / guc-clients / reset-tool
1 #!/usr/bin/perl
2 use strict;
3
4 use Data::Dumper;
5
6 #TODO: Add support for assigning phone number
7 #TODO: Add support for overriding default domain ...
8
9 use Getopt::Long;
10 use Net::LDAP;
11 use Net::LDAP::Control::Paged;
12 use Net::LDAP::Constant qw( LDAP_CONTROL_PAGED );
13 use LWP;
14 use JSON;
15 use AppConfig;
16 use Text::Iconv;
17
18 my $api_key;
19
20 my $help;
21 my $username;
22 my $agent;
23 my $file;
24 my $proxy;
25 my $sipsak;
26
27 my $configfile = undef;
28 my $format = 0;
29 my ($g_ua, $session, $api_key, $auth_key, $data, $domain);
30
31 my $config = AppConfig->new({ CREATE => 1 });
32
33 $config->define("api_url=s");
34 $config->define("api_keyfile=s");
35
36 foreach (
37 "/usr/local/etc/hermes/hermes_config",
38 "/usr/local/etc/hermes/config",
39 "/etc/hermes/config",
40 $ENV{"HOME"} . "/.hermes/config",
41 $ENV{"HOME"} . "/.hermes_config",
42 ) { $configfile = $_ if ( -f $_ ); }
43
44 GetOptions(
45 "help" => \$help,
46 "configfile=s" => \$configfile,
47 "username=s" => \$username,
48 "agent=s" => \$agent,
49 "file=s" => \$file,
50 "proxy=s" => \$proxy,
51 "sipsak=s" => \$sipsak,
52 );
53
54 if (
55 (not $agent) ||
56 (not $file) ||
57 (not $proxy) ||
58 (not $sipsak) ||
59 (not $username) ||
60 (not $configfile) ||
61 (( $configfile ) && ( not -f $configfile ))
62 )
63 {
64 $help = 1;
65 }
66
67 $config->file( $configfile );
68
69 if ( ( not $config->api_url ) ||
70 ( not $config->api_keyfile ) ||
71 ( $config->api_keyfile && not -f $config->api_keyfile )
72 )
73 {
74 $help = 1;
75 }
76
77 if ( $help ) {
78 print <<END_HELP;
79 Verify that the following options are set:
80 --username=s|--user|-u
81 --agent=s|-a User agent to match
82 --file=s|-f SIPSAK template file
83 --proxy=s|-p SIP Proxy to send SIP messages to
84 --sipsak=s|-s Path to sipsak executable
85 --configfile=s
86
87 Verify the contents of the configuration file.
88 Verify that the key-file exists.
89 END_HELP
90 exit; }
91
92 open KEY, "<" . $config->api_keyfile;
93 chomp( $api_key = <KEY> );
94 close KEY;
95
96 if ( not $username =~ m/\w+/ )
97 { print "Illegal username\n"; exit; }
98
99 $g_ua = LWP::UserAgent->new;
100 $g_ua->cookie_jar({}); # In-memory jar, look at HTTP::Cookies for persistant
101
102 login_apikey();
103
104 # First: fetch a supported domain from the API...
105 $data = exec_apinode("domain/list", undef);
106 if ( $data->{'response'} eq 'ok' )
107 {
108 $domain = $data->{'list'}[0];
109 }
110 else
111 {
112 printf("Unable to get domain name. Aborting\n");
113 logout();
114 exit;
115 }
116
117 if ( $username =~ /@/ )
118 {
119 ( $username, $domain ) = split /@/, $username;
120 }
121
122 $data = exec_apinode("user/location", { 'username' => $username, 'domain' => $domain });
123 if ( not $data->{'response'} eq 'ok' )
124 {
125 printf("Unable to fetch location: %s\n", $data->{'cause'});
126 exit;
127 }
128 my $t = $data->{'locations'};
129 my @locations = @$t;
130
131 foreach my $l ( @locations )
132 {
133 if ( $l->{'useragent'} =~ m/$agent/ )
134 {
135 $l->{'contact'} =~ m/sip:(\w+)@(.*):(\d+)/;
136 my ( $user, $host, $port) = ( $1, $2, $3 );
137
138 $data = exec_apinode("user/get", { 'username' => $user, 'domain' => $domain });
139 if ( not $data->{'response'} eq 'ok' )
140 {
141 printf("Unable to fetch user: %s\n", $data->{'cause'});
142 exit;
143 }
144
145 my $sipuser = $data->{'user'};
146 my $pass = $data->{'user'}->{'password'};
147 #printf("Auth password.: %s\n", $sipuser->{'password'});
148
149 printf("%s -vvv -G -f %s -p %s -H %s -s sip:%s@%s -a %s\n",
150 $sipsak,
151 $file,
152 $proxy,
153 $host,
154 $user,
155 $domain,
156 $pass,
157 );
158 }
159 }
160
161 undef $data;
162
163 logout();
164 ################################################################################################
165 sub exec_apinode($$)
166 {
167 my $node = shift;
168 my $param = shift;
169
170 my ( $response, $data );
171
172 $session = "" if not defined $session;
173 $auth_key = "" if not defined $auth_key;
174 my $url = $config->api_url . "/" . $node;
175
176 $param->{'session'} = $session;
177 $param->{'auth_key'} = $auth_key;
178
179 $response = $g_ua->post( $url, $param );
180 if ( $response->is_success )
181 {
182 if ( $response->content =~ m/\s*{/ )
183 {
184 $data = decode_json( $response->content);
185 }
186 else
187 {
188 $data = $response->content;
189 }
190
191 }
192 return $data;
193 }
194
195 sub login_apikey
196 {
197 my $response = $g_ua->post( $config->api_url . "/auth/login",
198 [ "api_key" => $api_key ] );
199
200 my $data = decode_json( $response->content) if $response->is_success;
201 die("HTTP error") unless $response->is_success;
202
203 if ( $data->{'response'} eq "ok" )
204 {
205 $session = $data->{'session'};
206 $auth_key = $data->{'auth_key'};
207 }
208 else
209 {
210 print "Unable to log in to Hermes API\n";
211 exit;
212 }
213 undef $data; undef $response;
214 }
215
216 sub logout
217 {
218 my $response = $g_ua->post( $config->api_url . "/auth/logout",
219 [ "session" => $session ] );
220 die("HTTP error") unless $response->is_success;
221 undef $session; undef $auth_key;
222 }