summaryrefslogtreecommitdiffstats
path: root/contrib/check_ica_program_neigbourhood.pl
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/check_ica_program_neigbourhood.pl')
-rwxr-xr-xcontrib/check_ica_program_neigbourhood.pl618
1 files changed, 0 insertions, 618 deletions
diff --git a/contrib/check_ica_program_neigbourhood.pl b/contrib/check_ica_program_neigbourhood.pl
deleted file mode 100755
index 1f0fb455..00000000
--- a/contrib/check_ica_program_neigbourhood.pl
+++ /dev/null
@@ -1,618 +0,0 @@
1#!/usr/bin/perl -w
2
3# $Id: check_ica_program_neigbourhood.pl 1097 2005-01-25 09:05:53Z stanleyhopcroft $
4
5# Revision 1.1 2005/01/25 09:05:53 stanleyhopcroft
6# New plugin to check Citrix Metaframe XP "Program Neighbourhood"
7#
8# Revision 1.1 2005-01-25 16:50:30+11 anwsmh
9# Initial revision
10#
11
12use strict ;
13
14use Getopt::Long;
15
16use utils qw($TIMEOUT %ERRORS &print_revision &support);
17use LWP 5.65 ;
18use XML::Parser ;
19
20my $PROGNAME = 'check_program_neigbourhood' ;
21my ($debug, $xml_debug, $pn_server, $pub_apps, $app_servers, $server_farm, $usage) ;
22
23Getopt::Long::Configure('bundling', 'no_ignore_case') ;
24GetOptions
25 ("V|version" => \&version,
26 "A|published_app:s" => \$pub_apps,
27 "h|help" => \&help,
28 'usage|?' => \&usage,
29 "F|server_farm=s" => \$server_farm,
30 "P|pn_server=s" => \$pn_server,
31 "S|app_server=s" => \$app_servers,
32 "v|verbose" => \$debug,
33 "x|xml_debug" => \$xml_debug,
34) ;
35
36$pn_server || do {
37 print "Name or IP Address of _one_ Program Neighbourhood server is required.\n" ;
38 &print_usage ;
39 exit $ERRORS{UNKNOWN} ;
40} ;
41
42$pub_apps ||= 'Word 2003' ;
43$pub_apps =~ s/["']//g ;
44my @pub_apps = split /,\s*/, $pub_apps ;
45
46my @app_servers = split /,\s*/, $app_servers ;
47
48@app_servers || do {
49 print "IP Address of _each_ Application server in the Metaframe Citrix XP server farm is required.\n" ;
50 &print_usage ;
51 exit $ERRORS{UNKNOWN} ;
52} ;
53
54my @non_ip_addresses = grep ! /\d+\.\d+\.\d+\.\d+/, @app_servers ;
55
56scalar(@non_ip_addresses) && do {
57 print qq(Application servers must be specified by IP Address (not name): "@non_ip_addresses".\n) ;
58 &print_usage ;
59 exit $ERRORS{UNKNOWN} ;
60} ;
61
62$server_farm || do {
63 print "Name of Citrix Metaframe XP server farm is required.\n" ;
64 &print_usage ;
65 exit $ERRORS{UNKNOWN} ;
66} ;
67
68my %xml_tag = () ;
69my @tag_stack = () ;
70
71my $xml_p = new XML::Parser(Handlers => {Start => \&handle_start,
72 End => sub { pop @tag_stack },
73 Char => \&handle_char}) ;
74
75# values required by Metaframe XP that don't appear to matter too much
76
77my $client_host = 'Nagios server (http://www.Nagios.ORG)' ;
78my $user_name = 'nagios' ;
79my $domain = 'Nagios_Uber_Alles' ;
80
81# end values required by Metaframe XP
82
83my $nilpotent_req = <<'EOR' ;
84<?xml version="1.0" encoding="ISO-8859-1"?>
85<!DOCTYPE NFuseProtocol SYSTEM "NFuse.dtd"><NFuseProtocol version="1.1">
86 <RequestProtocolInfo>
87 <ServerAddress addresstype="dns-port" />
88 </RequestProtocolInfo>
89</NFuseProtocol>
90EOR
91
92my $server_farm_req = <<'EOR' ;
93<?xml version="1.0" encoding="ISO-8859-1"?>
94<!DOCTYPE NFuseProtocol SYSTEM "NFuse.dtd">
95<NFuseProtocol version="1.1">
96 <RequestServerFarmData>
97 <Nil />
98 </RequestServerFarmData>
99</NFuseProtocol>
100EOR
101
102my $spec_server_farm_req = <<EOR ;
103<?xml version="1.0" encoding="ISO-8859-1"?>
104<!DOCTYPE NFuseProtocol SYSTEM "NFuse.dtd">
105<NFuseProtocol version="1.1">
106 <RequestAddress>
107 <Name>
108 <UnspecifiedName>$server_farm*</UnspecifiedName>
109 </Name>
110 <ClientName>$client_host</ClientName>
111 <ClientAddress addresstype="dns-port" />
112 <ServerAddress addresstype="dns-port" />
113 <Flags />
114 <Credentials>
115 <UserName>$user_name</UserName>
116 <Domain>$domain</Domain>
117 </Credentials>
118 </RequestAddress>
119</NFuseProtocol>
120EOR
121
122my $app_req = <<EOR ;
123<?xml version="1.0" encoding="ISO-8859-1"?>
124<!DOCTYPE NFuseProtocol SYSTEM "NFuse.dtd">
125<NFuseProtocol version="1.1">
126 <RequestAddress>
127 <Name>
128 <UnspecifiedName>PUBLISHED_APP_ENCODED</UnspecifiedName>
129 </Name>
130 <ClientName>Nagios_Service_Check</ClientName>
131 <ClientAddress addresstype="dns-port"/>
132 <ServerAddress addresstype="dns-port" />
133 <Flags />
134 <Credentials>
135 <UserName>$PROGNAME</UserName>
136 <Domain>$domain</Domain>
137 </Credentials>
138 </RequestAddress>
139</NFuseProtocol>
140EOR
141
142my $ua = LWP::UserAgent->new ;
143my $req = HTTP::Request->new('POST', "http://$pn_server/scripts/WPnBr.dll") ;
144 $req->content_type('text/xml') ;
145
146my $svr ;
147
148my @pubapp_encoded = map { my $x = $_ ; $x =~ s/(\W)/'&#' . ord($1) . ';'/eg; $x } @pub_apps ;
149
150my $error_tag_cr = sub { ! exists($xml_tag{ErrorId}) } ;
151
152my @app_reqs = (
153 # { Content => url, Ok => ok_condition, Seq => \d+ }
154
155 { Content => $nilpotent_req, Ok => $error_tag_cr, Seq => 0 },
156 { Content => $server_farm_req, Ok => sub {
157 ! exists($xml_tag{ErrorId}) &&
158 exists( $xml_tag{ServerFarmName}) &&
159 defined($xml_tag{ServerFarmName}) &&
160 $xml_tag{ServerFarmName} eq $server_farm
161 }, Seq => 2 },
162 { Content => $nilpotent_req, Ok => $error_tag_cr, Seq => 4 },
163 { Content => $spec_server_farm_req, Ok => sub {
164 ! exists($xml_tag{ErrorId}) &&
165 exists( $xml_tag{ServerAddress}) &&
166 defined($xml_tag{ServerAddress}) &&
167 $xml_tag{ServerAddress} =~ /\d+\.\d+\.\d+\.\d+:\d+/
168 }, Seq => 6 },
169 { Content => $nilpotent_req, Ok => $error_tag_cr, Seq => 8 },
170 { Content => $app_req, Ok => sub {
171 ! exists($xml_tag{ErrorId}) &&
172 exists( $xml_tag{ServerAddress}) &&
173 defined($xml_tag{ServerAddress}) &&
174 (($svr) = split(/:/, $xml_tag{ServerAddress})) &&
175 defined($svr) &&
176 scalar(grep $_ eq $svr, @app_servers)
177 }, Seq => 10 }
178) ;
179
180my $app_location ;
181
182foreach my $pub_app (@pub_apps) {
183
184 my $pubapp_enc = shift @pubapp_encoded ;
185 my $app_req_tmp = $app_reqs[5]{Content} ;
186 $app_reqs[5]{Content} =~ s/PUBLISHED_APP_ENCODED/$pubapp_enc/ ;
187
188 foreach (@app_reqs) {
189
190 $req->content($_->{Content}) ;
191
192 $debug && print STDERR "App: $pub_app Seq: $_->{Seq}\n", $req->as_string, "\n" ;
193
194 my $resp = $ua->request($req) ;
195
196 $debug && print STDERR "App: $pub_app Seq: ", $_->{Seq} + 1, "\n", $resp->as_string, "\n" ;
197
198 $resp->is_error && do {
199 my $err = $resp->as_string ;
200 $err =~ s/\n//g ;
201 &outahere(qq(Failed. HTTP error finding $pub_app at seq $_->{Seq}: "$err")) ;
202 } ;
203 my $xml = $resp->content ;
204
205 my $xml_disp ;
206 ($xml_disp = $xml) =~ s/\n//g ;
207 $xml_disp =~ s/ \s+/ /g ;
208
209 &outahere($resp->as_string)
210 unless $xml ;
211
212 my ($xml_ok, $whine) = &valid_xml($xml_p, $xml) ;
213
214 $xml_ok || &outahere(qq(Failed. Bad XML finding $pub_app at eq $_->{Seq} in "$xml_disp".)) ;
215
216 &{$_->{Ok}} || &outahere(qq(Failed. \"\&\$_->{Ok}\" false finding $pub_app at seq $_->{Seq} in "$xml_disp".)) ;
217
218 # Ugly but alternative is $_->{Ok}->().
219 # eval $_->{Ok} where $_->{Ok} is an
220 # expression returning a bool is possible. but
221 # sub { } prevent recompilation.
222
223 }
224
225 $app_reqs[5]{Content} = $app_req_tmp ;
226
227 $app_location .= qq("$pub_app" => $svr, ) ;
228
229}
230
231substr($app_location, -2, 2) = '' ;
232print qq(Ok. Citrix XML service located all published apps $app_location.\n) ;
233exit $ERRORS{'OK'} ;
234
235sub outahere {
236 print "Citrix XML service $_[0]\n" ;
237 exit $ERRORS{CRITICAL} ;
238}
239
240sub valid_xml {
241 my ($p, $input) = @_ ;
242
243 %xml_tag = () ;
244 @tag_stack = () ;
245
246 eval {
247 $p->parse($input)
248 } ;
249
250 return (0, qq(XML::Parser->parse failed: Bad XML in "$input".!))
251 if $@ ;
252
253 if ( $xml_debug ) {
254 print STDERR pack('A4 A30 A40', ' ', $_, qq(-> "$xml_tag{$_}")), "\n"
255 foreach (keys %xml_tag)
256 }
257
258 return (1, 'valid xml')
259
260}
261
262
263sub handle_start {
264 push @tag_stack, $_[1] ;
265
266 $xml_debug && print STDERR pack('A8 A30 A40', ' ', 'handle_start - tag', " -> '$_[1]'"), "\n" ;
267 $xml_debug && print STDERR pack('A8 A30 A60', ' ', 'handle_start - @tag_stack', " -> (@tag_stack)"), "\n" ;
268}
269
270sub handle_char {
271 my $text = $_[1] ;
272
273 !($text =~ /\S/ || $text =~ /^[ \t]$/) && return ;
274
275 $text =~ s/\n//g ;
276
277 my $tag = $tag_stack[-1] ;
278
279 $xml_debug && print STDERR pack('A8 A30 A30', ' ', 'handle_char - tag', " -> '$tag'"), "\n" ;
280 $xml_debug && print STDERR pack('A8 A30 A40', ' ', 'handle_char - text', " -> '$text'"), "\n" ;
281
282 $xml_tag{$tag} .= $text ;
283
284}
285
286
287sub print_help() {
288
289# 1 2 3 4 5 6 7 8
290#12345678901234567890123456789012345678901234567890123456789012345678901234567890
291
292 print_revision($PROGNAME,'$Revision: 1097 $ ');
293
294my $help = <<EOHELP ;
295Copyright (c) 2004 Karl DeBisschop/S Hopcroft
296
297$PROGNAME -P <pn_server> -S <svr1,svr2,..> -A <app1,app2,..>
298 -F <Farm> [-v -x -h -V]
299
300Check the Citrix Metaframe XP service by completing an HTTP dialogue with a Program
301Neigbourhood server (pn_server) that returns an ICA server in the named Server farm
302hosting the specified applications (an ICA server in a farm which runs some MS app).
303EOHELP
304
305 print $help ;
306 print "\n";
307 print "\n";
308 print_usage();
309 print "\n";
310 support();
311}
312
313sub print_usage () {
314
315# 1 2 3 4 5 6 7 8
316#12345678901234567890123456789012345678901234567890123456789012345678901234567890
317
318my $usage = <<EOUSAGE ;
319$PROGNAME
320[-P | --pn_server] The name or address of the Citrix Metaframe XP
321 Program Neigbourhood server (required).
322[-A | --pub_apps] The name or names of an application published by the
323 server farm (default 'Word 2003').
324[-F | --server_farm] The name of a Citrix Metaframe XP server farm. (required)
325[-S | --app_servers] The _IP addresses_ of _all_ of the Farms ICA servers expected
326 to host the published application.
327 Enter as a comma separated string eg 'Srv1, Svr2, ..,Srvn'.
328 Since the PN servers round-robin the app servers to the clients,
329 _all_ the server farm addresses must be specified or the check
330 will fail (required).
331[-v | --verbose]
332[-h | --help]
333[-x | --xml_debug]
334[-V | --version]
335EOUSAGE
336
337 print $usage ;
338
339}
340
341sub usage {
342 &print_usage ;
343 exit $ERRORS{'OK'} ;
344}
345
346sub version () {
347 print_revision($PROGNAME,'$Revision: 1097 $ ');
348 exit $ERRORS{'OK'};
349}
350
351sub help () {
352 print_help();
353 exit $ERRORS{'OK'};
354}
355
356=begin comment
357
358This is the set of requests and responses transmitted between a Citrix Metaframe XP Program Neigbourhood (PN) client and a PN server.
359
360This dialogue was captured by and reconstructed from tcpdump.
361
362Citrix are not well known for documenting their protocols although the DTD may be informative. Note that the pair(s) 0 and 1, 4 and 5, ...
363do not appear to do anything.
364
365req 0
366POST /scripts/WPnBr.dll HTTP/1.1
367Content-type: text/xml
368Host: 10.1.2.2:80
369Content-Length: 220
370Connection: Keep-Alive
371
372
373<?xml version="1.0" encoding="ISO-8859-1"?>
374<!DOCTYPE NFuseProtocol SYSTEM "NFuse.dtd">
375<NFuseProtocol version="1.1"><RequestProtocolInfo><ServerAddress addresstype="dns-port" /></RequestProtocolInfo></NFuseProtocol>
376
377HTTP/1.1 100 Continue
378Server: Citrix Web PN Server
379Date: Thu, 30 Sep 2004 00:12:40 GMT
380
381
382resp 1
383HTTP/1.1 200 OK
384Server: Citrix Web PN Server
385Date: Thu, 30 Sep 2004 00:12:40 GMT
386Content-type: text/xml
387Content-length: 253
388
389
390<?xml version="1.0" encoding="ISO-8859-1" ?>
391<!DOCTYPE NFuseProtocol SYSTEM "NFuse.dtd">
392<NFuseProtocol version="1.1">
393 <ResponseProtocolInfo>
394 <ServerAddress addresstype="no-change"></ServerAddress>
395 </ResponseProtocolInfo>
396</NFuseProtocol>
397
398req 2
399POST /scripts/WPnBr.dll HTTP/1.1
400Content-type: text/xml
401Host: 10.1.2.2:80
402Content-Length: 191
403Connection: Keep-Alive
404
405
406<?xml version="1.0" encoding="ISO-8859-1"?>
407<!DOCTYPE NFuseProtocol SYSTEM "NFuse.dtd">
408<NFuseProtocol version="1.1"><RequestServerFarmData><Nil /></RequestServerFarmData></NFuseProtocol>
409
410HTTP/1.1 100 Continue
411Server: Citrix Web PN Server
412Date: Thu, 30 Sep 2004 00:12:40 GMT
413
414
415resp 3
416HTTP/1.1 200 OK
417Server: Citrix Web PN Server
418Date: Thu, 30 Sep 2004 00:12:40 GMT
419Content-type: text/xml
420Content-length: 293
421
422
423<?xml version="1.0" encoding="ISO-8859-1" ?>
424<!DOCTYPE NFuseProtocol SYSTEM "NFuse.dtd">
425<NFuseProtocol version="1.1">
426 <ResponseServerFarmData>
427 <ServerFarmData>
428 <ServerFarmName>FOOFARM01</ServerFarmName>
429 </ServerFarmData>
430 </ResponseServerFarmData>
431</NFuseProtocol>
432
433req 4
434POST /scripts/WPnBr.dll HTTP/1.1
435Content-type: text/xml
436Host: 10.1.2.2:80
437Content-Length: 220
438Connection: Keep-Alive
439
440
441<?xml version="1.0" encoding="ISO-8859-1"?>
442<!DOCTYPE NFuseProtocol SYSTEM "NFuse.dtd">
443<NFuseProtocol version="1.1"><RequestProtocolInfo><ServerAddress addresstype="dns-port" /></RequestProtocolInfo></NFuseProtocol>
444
445HTTP/1.1 100 Continue
446Server: Citrix Web PN Server
447Date: Thu, 30 Sep 2004 00:12:55 GMT
448
449
450resp 5
451HTTP/1.1 200 OK
452Server: Citrix Web PN Server
453Date: Thu, 30 Sep 2004 00:12:55 GMT
454Content-type: text/xml
455Content-length: 253
456
457
458<?xml version="1.0" encoding="ISO-8859-1" ?>
459<!DOCTYPE NFuseProtocol SYSTEM "NFuse.dtd">
460<NFuseProtocol version="1.1">
461 <ResponseProtocolInfo>
462 <ServerAddress addresstype="no-change"></ServerAddress>
463 </ResponseProtocolInfo>
464</NFuseProtocol>
465
466req 6
467POST /scripts/WPnBr.dll HTTP/1.1
468Content-type: text/xml
469Host: 10.1.2.2:80
470Content-Length: 442
471Connection: Keep-Alive
472
473
474<?xml version="1.0" encoding="ISO-8859-1"?>
475<!DOCTYPE NFuseProtocol SYSTEM "NFuse.dtd">
476<NFuseProtocol version="1.1">
477<RequestAddress><Name>i
478 <UnspecifiedName>FOOFARM01*</UnspecifiedName>
479 </Name><ClientName>WS09535</ClientName>
480 <ClientAddress addresstype="dns-port" />
481 <ServerAddress addresstype="dns-port" />
482 <Flags />
483 <Credentials>
484 <UserName>foo-user</UserName>
485 <Domain>some-domain</Domain>
486 </Credentials>
487</RequestAddress></NFuseProtocol>
488
489HTTP/1.1 100 Continue
490Server: Citrix Web PN Server
491Date: Thu, 30 Sep 2004 00:12:56 GMT
492
493
494resp 7
495HTTP/1.1 200 OK
496Server: Citrix Web PN Server
497Date: Thu, 30 Sep 2004 00:12:56 GMT
498Content-type: text/xml
499Content-length: 507
500
501
502<?xml version="1.0" encoding="ISO-8859-1" ?>
503<!DOCTYPE NFuseProtocol SYSTEM "NFuse.dtd">
504<NFuseProtocol version="1.1">
505 <ResponseAddress>
506 <ServerAddress addresstype="dot-port">10.1.2.2:1494</ServerAddress>
507 <ServerType>win32</ServerType>
508 <ConnectionType>tcp</ConnectionType>
509 <ClientType>ica30</ClientType>
510 <TicketTag>10.1.2.2</TicketTag>
511 <SSLRelayAddress addresstype="dns-port">ica_svr01.some.domain:443</SSLRelayAddress>
512 </ResponseAddress>
513</NFuseProtocol>
514
515req 8
516POST /scripts/WPnBr.dll HTTP/1.1
517Content-type: text/xml
518Host: 10.1.2.2:80
519Content-Length: 220
520Connection: Keep-Alive
521
522
523<?xml version="1.0" encoding="ISO-8859-1"?>
524<!DOCTYPE NFuseProtocol SYSTEM "NFuse.dtd">
525<NFuseProtocol version="1.1"><RequestProtocolInfo><ServerAddress addresstype="dns-port" /></RequestProtocolInfo></NFuseProtocol>
526
527HTTP/1.1 100 Continue
528Server: Citrix Web PN Server
529Date: Thu, 30 Sep 2004 00:13:29 GMT
530
531
532resp 9
533HTTP/1.1 200 OK
534Server: Citrix Web PN Server
535Date: Thu, 30 Sep 2004 00:13:29 GMT
536Content-type: text/xml
537Content-length: 253
538
539
540<?xml version="1.0" encoding="ISO-8859-1" ?>
541<!DOCTYPE NFuseProtocol SYSTEM "NFuse.dtd">
542<NFuseProtocol version="1.1">
543 <ResponseProtocolInfo>
544 <ServerAddress addresstype="no-change"></ServerAddress>
545 </ResponseProtocolInfo>
546</NFuseProtocol>
547
548req 10
549POST /scripts/WPnBr.dll HTTP/1.1
550Content-type: text/xml
551Host: 10.1.2.2:80
552Content-Length: 446
553Connection: Keep-Alive
554
555
556<?xml version="1.0" encoding="ISO-8859-1"?>
557<!DOCTYPE NFuseProtocol SYSTEM "NFuse.dtd">
558<NFuseProtocol version="1.1">
559<RequestAddress>i
560 <Name>
561 <UnspecifiedName>EXCEL#32;2003</UnspecifiedName>
562 </Name>
563 <ClientName>WS09535</ClientName>
564 <ClientAddress addresstype="dns-port" />
565 <ServerAddress addresstype="dns-port" />
566 <Flags />
567 <Credentials><UserName>foo-user</UserName>
568 <Domain>some-domain</Domain>
569 </Credentials>
570</RequestAddress>i
571</NFuseProtocol>
572
573HTTP/1.1 100 Continue
574Server: Citrix Web PN Server
575Date: Thu, 30 Sep 2004 00:13:29 GMT
576
577
578resp 11
579HTTP/1.1 200 OK
580Server: Citrix Web PN Server
581Date: Thu, 30 Sep 2004 00:13:29 GMT
582Content-type: text/xml
583Content-length: 509
584
585
586<?xml version="1.0" encoding="ISO-8859-1" ?>
587<!DOCTYPE NFuseProtocol SYSTEM "NFuse.dtd">
588<NFuseProtocol version="1.1">
589 <ResponseAddress>
590 <ServerAddress addresstype="dot-port">10.1.2.14:1494</ServerAddress>
591 <ServerType>win32</ServerType>
592 <ConnectionType>tcp</ConnectionType>
593 <ClientType>ica30</ClientType>
594 <TicketTag>10.1.2.14</TicketTag>
595 <SSLRelayAddress addresstype="dns-port">ica_svr02.some.domain:443</SSLRelayAddress>
596 </ResponseAddress>
597</NFuseProtocol>
598
599** One sees this XML on an error (there may well be other error XML also, but I haven't seen it) **
600
601<?xml version="1.0" encoding="ISO-8859-1" ?>
602<!DOCTYPE NFuseProtocol SYSTEM "NFuse.dtd">
603<NFuseProtocol version="1.1">
604 <ResponseAddress>
605 <ErrorId>unspecified</ErrorId>
606 <BrowserError>0x0000000E</BrowserError>
607 </ResponseAddress>
608</NFuseProtocol>
609
610
611=end comment
612
613=cut
614
615
616# You never know when you may be embedded ...
617
618