4
0

check_ica_program_neigbourhood.pl 16 KB

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