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