1 /* ulogd_PWSNIFF.c, Version $Revision: 5372 $
3 * ulogd logging interpreter for POP3 / FTP like plaintext passwords.
5 * (C) 2000-2003 by Harald Welte <laforge@gnumonks.org>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2
9 * as published by the Free Software Foundation
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 * $Id: ulogd_PWSNIFF.c 5372 2005-05-04 01:22:56Z laforge $
27 #include <sys/socket.h>
28 #include <netinet/ip.h>
29 #include <netinet/in.h>
30 #include <netinet/tcp.h>
32 #include <ulogd/ulogd.h>
35 #define DEBUGP(x) ulogd_log(ULOGD_DEBUG, x)
37 #define DEBUGP(format, args...)
44 static u_int16_t pwsniff_ports[] = {
45 __constant_htons(PORT_POP3),
46 __constant_htons(PORT_FTP),
47 /* feel free to include any other ports here, provided that their
48 * user/password syntax is the same */
51 #define PWSNIFF_MAX_PORTS 2
53 static char *_get_next_blank(char* begp, char *endp)
57 for (ptr = begp; ptr < endp; ptr++) {
58 if (*ptr == ' ' || *ptr == '\n' || *ptr == '\r') {
65 static ulog_iret_t *_interp_pwsniff(ulog_interpreter_t *ip, ulog_packet_msg_t *pkt)
67 struct iphdr *iph = (struct iphdr *) pkt->payload;
68 void *protoh = (u_int32_t *)iph + iph->ihl;
69 struct tcphdr *tcph = protoh;
70 u_int32_t tcplen = ntohs(iph->tot_len) - iph->ihl * 4;
71 unsigned char *ptr, *begp, *pw_begp, *endp, *pw_endp;
72 ulog_iret_t *ret = ip->result;
73 int len, pw_len, i, cont = 0;
76 begp = pw_begp = NULL;
78 if (iph->protocol != IPPROTO_TCP)
81 for (i = 0; i < PWSNIFF_MAX_PORTS; i++)
83 if (tcph->dest == pwsniff_ports[i]) {
91 DEBUGP("----> pwsniff detected, tcplen=%d, struct=%d, iphtotlen=%d, ihl=%d\n", tcplen, sizeof(struct tcphdr), ntohs(iph->tot_len), iph->ihl);
93 for (ptr = (unsigned char *) tcph + sizeof(struct tcphdr);
94 ptr < (unsigned char *) tcph + tcplen; ptr++)
96 if (!strncasecmp((char *)ptr, "USER ", 5)) {
98 endp = (unsigned char *)_get_next_blank((char *)begp, (char *)tcph + tcplen);
100 len = endp - begp + 1;
102 if (!strncasecmp((char *)ptr, "PASS ", 5)) {
104 pw_endp = (unsigned char *)_get_next_blank((char *)pw_begp,
105 (char *)tcph + tcplen);
107 pw_len = pw_endp - pw_begp + 1;
112 ret[0].value.ptr = (char *) malloc(len+1);
113 ret[0].flags |= ULOGD_RETF_VALID;
114 if (!ret[0].value.ptr) {
115 ulogd_log(ULOGD_ERROR, "OOM (size=%u)\n", len);
118 strncpy(ret[0].value.ptr, (char *)begp, len);
119 *((char *)ret[0].value.ptr + len + 1) = '\0';
122 ret[1].value.ptr = (char *) malloc(pw_len+1);
123 ret[1].flags |= ULOGD_RETF_VALID;
124 if (!ret[1].value.ptr){
125 ulogd_log(ULOGD_ERROR, "OOM (size=%u)\n", pw_len);
128 strncpy(ret[1].value.ptr, (char *)pw_begp, pw_len);
129 *((char *)ret[1].value.ptr + pw_len + 1) = '\0';
135 static ulog_iret_t pwsniff_rets[] = {
136 { .type = ULOGD_RET_STRING,
137 .flags = ULOGD_RETF_FREE,
138 .key = "pwsniff.user",
140 { .type = ULOGD_RET_STRING,
141 .flags = ULOGD_RETF_FREE,
142 .key = "pwsniff.pass",
146 static ulog_interpreter_t base_ip[] = {
148 .interp = &_interp_pwsniff,
150 .result = pwsniff_rets },
151 { NULL, "", 0, NULL, 0, NULL },
154 static void _base_reg_ip(void)
156 ulog_interpreter_t *ip = base_ip;
157 ulog_interpreter_t *p;
159 for (p = ip; p->interp; p++)
160 register_interpreter(p);