1 /*
2  * decode_citrix.c
3  *
4  * Citrix ICA.
5  *
6  * http://www.securityfocus.com/templates/archive.pike?list=1&date=200 \
7  * 0-04-15&msg=Pine.BSO.4.20.0003290949280.2640-100000@naughty.monkey.org
8  *
9  * Thanks to Jeremie Kass <jeremie@monkey.org> for providing me with
10  * traffic traces.
11  *
12  * Copyright (c) 2000 Dug Song <dugsong@monkey.org>
13  *
14  * $Id: decode_citrix.c,v 1.5 2001/03/15 08:32:59 dugsong Exp $
15  */
16 
17 #include "config.h"
18 
19 #include <sys/types.h>
20 
21 #include <stdio.h>
22 #include <string.h>
23 
24 #include "buf.h"
25 #include "decode.h"
26 
27 static u_char ica_magic[] = { 0x32, 0x26, 0x85, 0x92, 0x58 };
28 
29 int
decode_citrix(u_char * buf,int len,u_char * obuf,int olen)30 decode_citrix(u_char *buf, int len, u_char *obuf, int olen)
31 {
32 	struct buf inbuf, outbuf;
33 	u_char key, c, t[2];
34 	int i;
35 
36 	buf_init(&inbuf, buf, len);
37 	buf_init(&outbuf, obuf, olen);
38 
39 	while ((i = buf_index(&inbuf, ica_magic, sizeof(ica_magic))) >= 0) {
40 		buf_skip(&inbuf, i);
41 
42 		if (buf_len(&inbuf) < 60)
43 			break;
44 
45 		buf_skip(&inbuf, 17);
46 
47 		if (buf_get(&inbuf, &key, 1) != 1)
48 			break;
49 
50 		buf_skip(&inbuf, 42);
51 
52 		if (buf_get(&inbuf, &c, 1) != 1)
53 			break;
54 
55 		c ^= ('C' | key);
56 
57 		buf_put(&outbuf, &c, 1);
58 
59 		i = 0;
60 		while (buf_get(&inbuf, t, 2) == 2) {
61 			c = t[0] ^ t[1] ^ key;
62 
63 			if (c == '\0') {
64 				buf_put(&outbuf, "\n", 1);
65 				if (++i > 2) break;
66 			}
67 			buf_put(&outbuf, &c, 1);
68 		}
69 	}
70 	buf_end(&outbuf);
71 
72 	return (buf_len(&outbuf));
73 }
74