1 /*
2  * decode.c
3  *
4  * Copyright (c) 2000 Dug Song <dugsong@monkey.org>
5  *
6  * $Id: decode.c,v 1.13 2001/03/15 08:32:59 dugsong Exp $
7  */
8 
9 #include "config.h"
10 
11 #include <sys/types.h>
12 #include <arpa/telnet.h>
13 #include <rpc/rpc.h>
14 
15 #include <stdio.h>
16 #include <string.h>
17 #include <ctype.h>
18 
19 #include "decode.h"
20 
21 extern int decode_hex(u_char *, int, u_char *, int);
22 extern int decode_ftp(u_char *, int, u_char *, int);
23 extern int decode_telnet(u_char *, int, u_char *, int);
24 extern int decode_smtp(u_char *, int, u_char *, int);
25 extern int decode_pptp(u_char *, int, u_char *, int);
26 extern int decode_http(u_char *, int, u_char *, int);
27 extern int decode_ospf(u_char *, int, u_char *, int);
28 extern int decode_poppass(u_char *, int, u_char *, int);
29 extern int decode_pop(u_char *, int, u_char *, int);
30 extern int decode_nntp(u_char *, int, u_char *, int);
31 extern int decode_smb(u_char *, int, u_char *, int);
32 extern int decode_imap(u_char *, int, u_char *, int);
33 extern int decode_snmp(u_char *, int, u_char *, int);
34 extern int decode_ldap(u_char *, int, u_char *, int);
35 extern int decode_mmxp(u_char *, int, u_char *, int);
36 extern int decode_rlogin(u_char *, int, u_char *, int);
37 extern int decode_rip(u_char *, int, u_char *, int);
38 extern int decode_socks(u_char *, int, u_char *, int);
39 extern int decode_citrix(u_char *, int, u_char *, int);
40 extern int decode_oracle(u_char *, int, u_char *, int);
41 extern int decode_tds(u_char *, int, u_char *, int);
42 extern int decode_sniffer(u_char *, int, u_char *, int);
43 extern int decode_cvs(u_char *, int, u_char *, int);
44 extern int decode_icq(u_char *, int, u_char *, int);
45 extern int decode_napster(u_char *, int, u_char *, int);
46 extern int decode_aim(u_char *, int, u_char *, int);
47 extern int decode_postgresql(u_char *, int, u_char *, int);
48 extern int decode_pcanywhere(u_char *, int, u_char *, int);
49 extern int decode_x11(u_char *, int, u_char *, int);
50 extern int decode_irc(u_char *, int, u_char *, int);
51 extern int decode_portmap(u_char *, int, u_char *, int);
52 extern int decode_mountd(u_char *, int, u_char *, int);
53 extern int decode_vrrp(u_char *, int, u_char *, int);
54 extern int decode_ypserv(u_char *, int, u_char *, int);
55 extern int decode_yppasswd(u_char *, int, u_char *, int);
56 
57 static struct decode decodes[] = {
58 	{ "hex",	decode_hex },
59 	{ "ftp",	decode_ftp },
60 	{ "telnet",	decode_telnet },
61 	{ "smtp",	decode_smtp },
62 	{ "pptp",	decode_pptp },
63 	{ "http",	decode_http },
64 	{ "ospf",	decode_ospf },
65 	{ "poppass",	decode_poppass },
66 	{ "pop",	decode_pop },
67 	{ "nntp",	decode_nntp },
68 	{ "smb",	decode_smb },
69 	{ "imap",	decode_imap },
70 	{ "snmp",	decode_snmp },
71 	{ "ldap",	decode_ldap },
72 	{ "mmxp",	decode_mmxp },
73 	{ "rlogin",	decode_rlogin },
74 	{ "rip",	decode_rip },
75 	{ "socks",	decode_socks },
76 	{ "citrix",	decode_citrix },
77 	{ "oracle",	decode_oracle },
78 	{ "tds",	decode_tds },
79 	{ "sniffer",	decode_sniffer },
80 	{ "cvs",	decode_cvs },
81 	{ "icq",	decode_icq },
82 	{ "napster",	decode_napster },
83 	{ "aim",	decode_aim },
84 	{ "postgresql",	decode_postgresql },
85 	{ "pcanywhere", decode_pcanywhere },
86 	{ "vrrp",	decode_vrrp },
87 	{ "x11",	decode_x11 },
88 	{ "irc",	decode_irc },
89 	{ "portmap",	decode_portmap },
90 	{ "mountd",	decode_mountd },
91 	{ "ypserv",	decode_ypserv },
92 	{ "yppasswd",	decode_yppasswd },
93 	{ NULL }
94 };
95 
96 struct decode *
getdecodebyname(const char * name)97 getdecodebyname(const char *name)
98 {
99 	struct decode *dc;
100 
101 	for (dc = decodes; dc->dc_name != NULL; dc++) {
102 		if (strcasecmp(dc->dc_name, name) == 0)
103 			return (dc);
104 	}
105 	return (NULL);
106 }
107 
108 /* Strip telnet options, as well as suboption data. */
109 int
strip_telopts(u_char * buf,int len)110 strip_telopts(u_char *buf, int len)
111 {
112 	int i, j, subopt = 0;
113 	char *p, *q;
114 
115 	for (i = j = 0; i < len; i++) {
116 		if (buf[i] == IAC) {
117 			if (++i >= len) break;
118 			else if (buf[i] > SB)
119 				i++;
120 			else if (buf[i] == SB) {
121 				/* XXX - check for autologin username. */
122 				p = buf + i + 1;
123 				if ((q = bufbuf(p, len - i, "\xff", 1))
124 				    != NULL) {
125 					if ((p = bufbuf(p, q - p, "USER\x01",
126 							5)) != NULL) {
127 						p += 5;
128 						buf[j++] = '[';
129 						memcpy(buf + j, p, q - p);
130 						j += q - p;
131 						buf[j++] = ']';
132 						buf[j++] = '\n';
133 					}
134 				}
135 				subopt = 1;
136 			}
137 			else if (buf[i] == SE) {
138 				if (!subopt) j = 0;
139 				subopt = 0;
140 			}
141 		}
142 		else if (!subopt) {
143 			/* XXX - convert isolated returns to newlines. */
144 			if (buf[i] == '\r' && i + 1 < len &&
145 			    buf[i + 1] != '\n')
146 				buf[j++] = '\n';
147 			/* XXX - strip binary nulls. */
148 			else if (buf[i] != '\0')
149 				buf[j++] = buf[i];
150 		}
151 	}
152 	buf[j] = '\0';
153 
154 	return (j);
155 }
156 
157 /* Strip a string buffer down to a maximum number of lines. */
158 int
strip_lines(char * buf,int max_lines)159 strip_lines(char *buf, int max_lines)
160 {
161 	char *p;
162 	int lines, nonascii;
163 
164 	if (!buf) return (0);
165 
166 	lines = nonascii = 0;
167 
168 	for (p = buf; *p && lines < max_lines; p++) {
169 		if (*p == '\n') lines++;
170 		if (!isascii(*p)) nonascii++;
171 	}
172 	if (*p) *p = '\0';
173 
174 	/* XXX - lame ciphertext heuristic */
175 	if (nonascii * 3 > p - buf)
176 		return (0);
177 
178 	return (lines);
179 }
180 
181 int
is_ascii_string(char * buf,int len)182 is_ascii_string(char *buf, int len)
183 {
184 	int i;
185 
186 	for (i = 0; i < len; i++)
187 		if (!isascii(buf[i])) return (0);
188 
189 	return (1);
190 }
191 
192 u_char *
bufbuf(u_char * big,int blen,u_char * little,int llen)193 bufbuf(u_char *big, int blen, u_char *little, int llen)
194 {
195 	u_char *p;
196 
197          for (p = big; p <= big + blen - llen; p++) {
198 		 if (memcmp(p, little, llen) == 0)
199 			 return (p);
200 	 }
201 	 return (NULL);
202 }
203