dsniff  2.4b2
About: A collection of tools for network auditing
  Fossies Dox: dsniff-2.4b2.tar.gz  ("inofficial" and yet experimental doxygen-generated source code documentation)  

decode_http.c
Go to the documentation of this file.
1 /*
2  * decode_http.c
3  *
4  * Hypertext Transfer Protocol.
5  *
6  * Copyright (c) 2000 Dug Song <dugsong@monkey.org>
7  *
8  * $Id: decode_http.c,v 1.17 2001/03/15 08:32:59 dugsong Exp $
9  */
10 
11 #include "config.h"
12 
13 #include <sys/types.h>
14 
15 #include <stdio.h>
16 #include <string.h>
17 #include <stdlib.h>
18 #include <regex.h>
19 #include <libgen.h>
20 #include <err.h>
21 
22 #include "base64.h"
23 #include "buf.h"
24 #include "decode.h"
25 
26 #define USER_REGEX ".*account.*|.*acct.*|.*domain.*|.*login.*|" \
27  ".*member.*|.*user.*|.*name|.*email|.*_id|" \
28  "id|uid|mn|mailaddress"
29 
30 #define PASS_REGEX ".*pass.*|.*pw|pw.*|additional_info"
31 
32 #define REGEX_FLAGS (REG_EXTENDED | REG_ICASE | REG_NOSUB)
33 
34 static regex_t *user_regex, *pass_regex;
35 
36 static int
38 {
39  char *p, *q, *tmp;
40  int user, pass;
41 
42  user = pass = 0;
43 
44  if ((tmp = strdup(buf)) == NULL)
45  return (0);
46 
47  for (p = strtok(tmp, "&"); p != NULL; p = strtok(NULL, "&")) {
48  if ((q = strchr(p, '=')) == NULL)
49  continue;
50  *q = '\0';
51 
52  if (!user) {
53  if (regexec(user_regex, p, 0, NULL, 0) == 0) {
54  user = 1;
55  continue;
56  }
57  }
58  if (!pass) {
59  if (regexec(pass_regex, p, 0, NULL, 0) == 0)
60  pass = 1;
61  }
62  if (user && pass) break;
63  }
64  free(tmp);
65 
66  return (user && pass);
67 }
68 
69 static char *
70 http_req_dirname(char *req)
71 {
72  char *uri, *vers;
73 
74  if ((uri = strchr(req, ' ')) == NULL)
75  return (req);
76 
77  if ((vers = strrchr(uri, ' ')) == uri) {
78  vers = NULL;
79  }
80  else if (vers[-1] == '/') {
81  return (req);
82  }
83  else *vers++ = '\0';
84 
85  strcpy(req, dirname(req));
86  strcat(req, "/");
87 
88  if (vers) {
89  strcat(req, " ");
90  strcat(req, vers);
91  }
92  return (req);
93 }
94 
95 int
96 decode_http(u_char *buf, int len, u_char *obuf, int olen)
97 {
98  struct buf *msg, inbuf, outbuf;
99  char *p, *req, *auth, *pauth, *query, *host;
100  int i;
101 
102  buf_init(&inbuf, buf, len);
103  buf_init(&outbuf, obuf, olen);
104 
105  if (user_regex == NULL || pass_regex == NULL) {
106  if ((user_regex = malloc(sizeof(*user_regex))) == NULL ||
107  (pass_regex = malloc(sizeof(*pass_regex))) == NULL)
108  err(1, "malloc");
109 
110  if (regcomp(user_regex, USER_REGEX, REGEX_FLAGS) ||
111  regcomp(pass_regex, PASS_REGEX, REGEX_FLAGS))
112  errx(1, "regcomp failed");
113  }
114  while ((i = buf_index(&inbuf, "\r\n\r\n", 4)) >= 0) {
115  msg = buf_tok(&inbuf, NULL, i);
116  msg->base[msg->end] = '\0';
117  buf_skip(&inbuf, 4);
118 
119  if ((req = strtok(buf_ptr(msg), "\r\n")) == NULL)
120  continue;
121 
122  if (strncmp(req, "GET ", 4) != 0 &&
123  strncmp(req, "POST ", 5) != 0 &&
124  strncmp(req, "CONNECT ", 8) != 0)
125  continue;
126 
127  auth = pauth = query = host = NULL;
128 
129  if ((query = strchr(req, '?')) != NULL)
130  query++;
131 
132  while ((p = strtok(NULL, "\r\n")) != NULL) {
133  if (strncasecmp(p, "Authorization: Basic ", 21) == 0) {
134  auth = p;
135  }
136  else if (strncasecmp(p, "Proxy-authorization: "
137  "Basic ", 27) == 0) {
138  pauth = p;
139  }
140  else if (strncasecmp(p, "Host: ", 6) == 0) {
141  host = p;
142  }
143  else if (req[0] == 'P') {
144  if (strncmp(p, "Content-type: ", 14) == 0) {
145  if (strncmp(p + 14, "application/"
146  "x-www-form-urlencoded",
147  33) != 0) {
148  query = NULL;
149  }
150  }
151  else if (strncmp(p, "Content-length: ", 16) == 0) {
152  p += 16;
153  i = atoi(p);
154  if ((msg = buf_tok(&inbuf, NULL, i)) == NULL)
155  continue;
156  msg->base[msg->end] = '\0';
157  query = buf_ptr(msg);
158  }
159  }
160  }
161  if (auth || pauth || (query && grep_query_auth(query))) {
162  if (buf_tell(&outbuf) > 0)
163  buf_putf(&outbuf, "\n");
164 
165  if (req[0] == 'G' && auth)
166  req = http_req_dirname(req);
167 
168  buf_putf(&outbuf, "%s\n", req);
169 
170  if (host)
171  buf_putf(&outbuf, "%s\n", host);
172 
173  if (pauth) {
174  buf_putf(&outbuf, "%s", pauth);
175  p = pauth + 27;
176  i = base64_pton(p, p, strlen(p));
177  p[i] = '\0';
178  buf_putf(&outbuf, " [%s]\n", p);
179  }
180  if (auth) {
181  buf_putf(&outbuf, "%s", auth);
182  p = auth + 21;
183  i = base64_pton(p, p, strlen(p));
184  p[i] = '\0';
185  buf_putf(&outbuf, " [%s]\n", p);
186  }
187  else if (req[0] == 'P' && query) {
188  buf_putf(&outbuf,
189  "Content-type: application/"
190  "x-www-form-urlencoded\n"
191  "Content-length: %d\n%s\n",
192  strlen(query), query);
193  }
194  }
195  }
196  buf_end(&outbuf);
197 
198  return (buf_len(&outbuf));
199 }
pass_regex
static regex_t * pass_regex
Definition: decode_http.c:34
buf_putf
int buf_putf(buf_t buf, const char *fmt,...)
Definition: buf.c:106
PASS_REGEX
#define PASS_REGEX
Definition: decode_http.c:30
buf_init
void buf_init(buf_t buf, u_char *data, int len)
Definition: buf.c:24
buf_end
void buf_end(buf_t buf)
Definition: buf.c:121
libgen.h
buf::base
u_char * base
Definition: buf.h:15
buf_tell
#define buf_tell(b)
Definition: buf.h:43
user_regex
static regex_t * user_regex
Definition: decode_http.c:34
decode.h
buf.h
USER_REGEX
#define USER_REGEX
Definition: decode_http.c:26
decode_http
int decode_http(u_char *buf, int len, u_char *obuf, int olen)
Definition: decode_http.c:96
host
u_int32_t host
Definition: webspy.c:39
err.h
buf
Definition: buf.h:14
err
void err(int eval, const char *fmt,...)
Definition: err.c:47
base64.h
buf_tok
buf_t buf_tok(buf_t buf, void *sep, int len)
Definition: buf.c:167
buf_ptr
#define buf_ptr(b)
Definition: buf.h:31
errx
void errx(int eval, const char *fmt,...)
Definition: err.c:76
dirname
char * dirname(char *path) const
Definition: dirname.c:36
base64_pton
int base64_pton(char const *src, u_char *target, size_t targsize)
Definition: base64.c:128
buf_skip
#define buf_skip(b, l)
Definition: buf.h:47
buf::end
int end
Definition: buf.h:18
config.h
obuf
static char obuf[4096]
Definition: trigger.c:43
REGEX_FLAGS
#define REGEX_FLAGS
Definition: decode_http.c:32
buf_len
#define buf_len(b)
Definition: buf.h:34
http_req_dirname
static char * http_req_dirname(char *req)
Definition: decode_http.c:70
grep_query_auth
static int grep_query_auth(char *buf)
Definition: decode_http.c:37
buf_index
int buf_index(buf_t buf, void *ptr, int len)
Definition: buf.c:128