1 /*
2 * decode_smb.c
3 *
4 * Microsoft Server Message Block.
5 *
6 * Copyright (c) 2000 Dug Song <dugsong@monkey.org>
7 *
8 * $Id: decode_smb.c,v 1.4 2001/03/15 08:33:02 dugsong Exp $
9 */
10
11 #include "config.h"
12
13 #include <sys/types.h>
14 #include <arpa/nameser.h>
15
16 #include <stdio.h>
17 #include <string.h>
18
19 #include "decode.h"
20
21 struct smbhdr {
22 u_char proto[4];
23 u_char cmd;
24 u_char err[4];
25 u_char flags1;
26 u_short flags2;
27 u_short pad[6];
28 u_short tid, pid, uid, mid;
29 };
30
31 int
decode_smb(u_char * buf,int len,u_char * obuf,int olen)32 decode_smb(u_char *buf, int len, u_char *obuf, int olen)
33 {
34 struct smbhdr *smb;
35 int i, j, k;
36 u_char *p, *q, *end;
37 char *user, *pass;
38
39 obuf[0] = '\0';
40
41 /* Skip NetBIOS session request. */
42 if (len < 4 || buf[0] != 0x81) return (0);
43 buf += 2;
44 GETSHORT(i, buf); len -= 4;
45 if (len < i) return (0);
46 buf += i; len -= i;
47 end = buf + len;
48
49 /* Parse SMBs. */
50 for (p = buf; p < end; p += i) {
51 GETLONG(i, p);
52 if (i > end - p || i < sizeof(*smb) + 32)
53 continue;
54
55 smb = (struct smbhdr *)p;
56 if (memcmp(smb->proto, "\xffSMB", 4) != 0 || smb->cmd != 0x73)
57 continue;
58
59 user = pass = NULL;
60 q = (u_char *)(smb + 1);
61
62 if (*q == 10) { /* Pre NT LM 0.12 */
63 q += 15; j = pletohs(q); q += 2;
64 if (j > i - (sizeof(*smb) + 15 + 6))
65 continue;
66 pass = q + 6;
67 user = pass + j;
68 }
69 else if (*q == 13) { /* NT LM 0.12 */
70 q += 15; j = pletohs(q);
71 q += 2; k = pletohs(q);
72 if (j > i - ((q - p) + 12) || k > i - ((q - p) + 11))
73 continue;
74 pass = q + 12;
75 user = pass + j + k;
76 }
77 else continue;
78
79 /* XXX - skip null IPC sessions, etc. */
80 if (user && pass && strlen(user) &&
81 is_ascii_string(pass, j - 1)) {
82 strlcat(obuf, user, olen);
83 strlcat(obuf, " ", olen);
84 strlcat(obuf, pass, olen);
85 strlcat(obuf, "\n", olen);
86 }
87 }
88 return (strlen(obuf));
89 }
90
91