int decode_imap(u_char *buf, int len, u_char *obuf, int olen) { struct buf *line, inbuf, outbuf; int i; buf_init(&inbuf, buf, len); buf_init(&outbuf, obuf, olen); while ((i = buf_index(&inbuf, "\r\n", 2)) != -1) { line = buf_tok(&inbuf, NULL, i); buf_skip(&inbuf, 2); if ((i = buf_index(line, " ", 1)) != -1) { buf_skip(line, i + 1); if (buf_cmp(line, "LOGIN ", 6) == 0) { buf_putf(&outbuf, "%.*s\n", buf_len(line), buf_ptr(line)); } } } buf_end(&outbuf); return (buf_len(&outbuf)); }
static int process_smtp_client(struct smtp_info *smtp, char *data, int len) { struct buf *line, *body, buf; char *p; int i; buf_init(&buf, data, len); if (smtp->state != SMTP_DATA) { while ((i = buf_index(&buf, "\r\n", 2)) >= 0) { line = buf_tok(&buf, NULL, i + 2); line->base[line->end-1] = '\0'; p = buf_ptr(line); if (strncasecmp(p, "RSET", 4) == 0) { smtp->state = SMTP_HELO; } else if (smtp->state == SMTP_NONE && (strncasecmp(p, "HELO", 4) == 0 || strncasecmp(p, "EHLO", 4) == 0)) { smtp->state = SMTP_HELO; } else if (smtp->state == SMTP_HELO && (strncasecmp(p, "MAIL ", 5) == 0 || strncasecmp(p, "SEND ", 5) == 0 || strncasecmp(p, "SAML ", 5) == 0)) { smtp->from = grep_mail_address(p); smtp->state = SMTP_MAIL; } else if (smtp->state == SMTP_MAIL && strncasecmp(p, "RCPT ", 5) == 0) { smtp->state = SMTP_RCPT; } else if (smtp->state == SMTP_RCPT && strncasecmp(p, "DATA", 4) == 0) { smtp->state = SMTP_DATA; break; } } } if (smtp->state == SMTP_DATA) { if ((i = buf_index(&buf, "\r\n.\r\n", 5)) >= 0) { body = buf_tok(&buf, NULL, i); buf_skip(&buf, 5); body->base[body->end] = '\0'; if (regex_match(buf_ptr(body))) print_mbox_msg(smtp->from, buf_ptr(body)); if (smtp->from) { free(smtp->from); smtp->from = NULL; } smtp->state = SMTP_HELO; } } return (len - buf_len(&buf)); }
buf_t buf_tok(buf_t buf, void *sep, int len) { static struct buf *savebuf, tokbuf; int off; if (buf != NULL) savebuf = buf; if (sep == NULL && buf_len(savebuf) >= len) { tokbuf.base = buf_ptr(savebuf); tokbuf.offset = 0; tokbuf.size = tokbuf.end = len; buf_skip(savebuf, len); } else if ((off = buf_index(savebuf, sep, len)) != -1) { tokbuf.base = buf_ptr(savebuf); tokbuf.offset = 0; tokbuf.size = tokbuf.end = off; buf_skip(savebuf, off + len); } else if (buf_len(savebuf) > 0) { tokbuf.base = buf_ptr(savebuf); tokbuf.offset = 0; tokbuf.size = tokbuf.end = buf_len(savebuf); savebuf->offset = savebuf->end; } else return (NULL); return (&tokbuf); }
static int process_pop_server(struct pop_info *pop, char *data, int len) { struct buf *line, *body, buf; int i; buf_init(&buf, data, len); if (pop->state == POP_NONE) return (len); if (pop->state == POP_RETR) { if ((i = buf_index(&buf, "\r\n", 2)) < 0) return (0); line = buf_tok(&buf, NULL, i + 2); if (buf_cmp(line, "+OK", 3) == 0) { pop->state = POP_DATA; } else pop->state = POP_NONE; } if (pop->state == POP_DATA) { if ((i = buf_index(&buf, "\r\n.\r\n", 5)) >= 0) { body = buf_tok(&buf, NULL, i); buf_skip(&buf, 5); body->base[body->end] = '\0'; if (regex_match(buf_ptr(body))) print_mbox_msg(NULL, buf_ptr(body)); pop->state = POP_NONE; } } return (len - buf_len(&buf)); }
buf_t buf_getword(buf_t buf, void *sep, int len) { buf_t b; int off; if ((off = buf_index(buf, sep, len)) < 0) return (NULL); if ((b = buf_new(off)) != NULL) { buf_put(b, buf_ptr(buf), off); buf_end(b); buf_skip(buf, off + len); } return (b); }
int decode_citrix(u_char *buf, int len, u_char *obuf, int olen) { struct buf inbuf, outbuf; u_char key, c, t[2]; int i; buf_init(&inbuf, buf, len); buf_init(&outbuf, obuf, olen); while ((i = buf_index(&inbuf, ica_magic, sizeof(ica_magic))) >= 0) { buf_skip(&inbuf, i); if (buf_len(&inbuf) < 60) break; buf_skip(&inbuf, 17); if (buf_get(&inbuf, &key, 1) != 1) break; buf_skip(&inbuf, 42); if (buf_get(&inbuf, &c, 1) != 1) break; c ^= ('C' | key); buf_put(&outbuf, &c, 1); i = 0; while (buf_get(&inbuf, t, 2) == 2) { c = t[0] ^ t[1] ^ key; if (c == '\0') { buf_put(&outbuf, "\n", 1); if (++i > 2) break; } buf_put(&outbuf, &c, 1); } } buf_end(&outbuf); return (buf_len(&outbuf)); }
static int process_pop_client(struct pop_info *pop, char *data, int len) { struct buf *line, buf; int i; buf_init(&buf, data, len); while ((i = buf_index(&buf, "\r\n", 2)) >= 0) { line = buf_tok(&buf, NULL, i + 2); line->base[line->end] = '\0'; if (strncasecmp(buf_ptr(line), "RETR ", 5) == 0) { pop->state = POP_RETR; } else pop->state = POP_NONE; } return (len - buf_len(&buf)); }
int decode_ftp(u_char *buf, int len, u_char *obuf, int olen) { struct buf *line, inbuf, outbuf; int i, n; if ((len = strip_telopts(buf, len)) == 0) return (0); buf_init(&inbuf, buf, len); buf_init(&outbuf, obuf, olen); if (!buf_isascii(&inbuf)) return (0); n = 0; while ((i = buf_index(&inbuf, "\n", 1)) != -1) { line = buf_tok(&inbuf, NULL, i); buf_skip(&inbuf, 1); if (i > 0 && line->base[i - 1] == '\r') line->end--; line->base[line->end] = '\0'; if (strncasecmp(buf_ptr(line), "USER ", 5) == 0 || strncasecmp(buf_ptr(line), "ACCT ", 5) == 0 || strncasecmp(buf_ptr(line), "PASS ", 5) == 0) { buf_putf(&outbuf, "%s\n", buf_ptr(line)); n++; } } if (n < 2) return (0); buf_end(&outbuf); return (buf_len(&outbuf)); }
int decode_mmxp(u_char *buf, int len, u_char *obuf, int olen) { struct buf inbuf, outbuf; u_char *p, c; u_int32_t i; int encrypt; buf_init(&inbuf, buf, len); buf_init(&outbuf, obuf, len); while ((i = buf_index(&inbuf, "\x00\x00\x24\x55", 4)) != -1) { buf_skip(&inbuf, i + 4); if (buf_cmp(&inbuf, "\x7f\xff", 2) == 0) encrypt = 1; else if (buf_cmp(&inbuf, "\xff\xff", 2) == 0) encrypt = 0; else continue; buf_skip(&inbuf, 4); /* LPPPg? */ if (buf_get(&inbuf, &i, sizeof(i)) < 0) break; i = ntohl(i); if (buf_skip(&inbuf, i + 4 + 4) < 0) continue; /* Server. */ if (buf_get(&inbuf, &c, 1) != 1) break; if (buf_len(&inbuf) < c) break; buf_put(&outbuf, buf_ptr(&inbuf), c); buf_put(&outbuf, "\n", 1); buf_skip(&inbuf, c + 4); /* Username. */ if (buf_get(&inbuf, &c, 1) != 1) break; if (buf_len(&inbuf) < c) break; buf_put(&outbuf, buf_ptr(&inbuf), c); buf_put(&outbuf, "\n", 1); buf_skip(&inbuf, c + 4); /* Password. */ if (buf_get(&inbuf, &c, 1) != 1) break; if (buf_len(&inbuf) < c) break; p = buf_ptr(&inbuf); if (encrypt) { for (i = 0; i < c; i++) p[i] ^= mm_xor[i % (sizeof(MM_SECRET) - 1)]; } buf_put(&outbuf, p, c); buf_put(&outbuf, "\n", 1); } buf_end(&outbuf); return (buf_len(&outbuf)); }
int process_http_request(struct tuple4 *addr, u_char *data, int len) { struct buf *msg, buf; char *p, *req, *uri, *user, *vhost, *referer, *agent; int i; buf_init(&buf, data, len); while ((i = buf_index(&buf, "\r\n\r\n", 4)) >= 0) { msg = buf_tok(&buf, NULL, i); msg->base[msg->end] = '\0'; buf_skip(&buf, 4); if (!regex_match(buf_ptr(msg))) continue; if ((req = strtok(buf_ptr(msg), "\r\n")) == NULL) continue; if (strncmp(req, "GET ", 4) != 0 && strncmp(req, "POST ", 5) != 0 && strncmp(req, "CONNECT ", 8) != 0) continue; if ((uri = strchr(req, ' ')) == NULL) continue; *uri++ = '\0'; user = vhost = referer = agent = NULL; while ((p = strtok(NULL, "\r\n")) != NULL) { if (strncasecmp(p, "Authorization: Basic ", 21) == 0) { p += 21; i = base64_pton(p, p, strlen(p)); p[i] = '\0'; user = p; if ((p = strchr(p, ':')) != NULL) *p = '\0'; } else if (strncasecmp(p, "Host: ", 6) == 0) { vhost = p + 6; } else if (strncasecmp(p, "Referer: ", 9) == 0) { referer = p + 9; } else if (strncasecmp(p, "User-Agent: ", 12) == 0) { agent = p + 12; } else if (strncasecmp(p, "Content-length: ", 16) == 0) { i = atoi(p + 16); buf_tok(NULL, NULL, i); } } if (user == NULL) user = "******"; if (vhost == NULL) vhost = "none";// libnet_host_lookup(addr->daddr, Opt_dns); if (referer == NULL) referer = "-"; if (agent == NULL) agent = "-"; printf("%s - %s [%s] \"%s http://%s%s\" - - \"%s\" \"%s\"\n", //"0.0.0.0", libnet_addr2name4(addr->saddr, Opt_dns), user, timestamp(), req, vhost, uri, referer, agent); } fflush(stdout); return (len - buf_len(&buf)); }
hale_internal void insert_non_crit_branch(FixedGapArena *arena, memi offset, const ch8 *data, memi size, Buf *it0) { requirement_check_buf(it0); Buf *it1 = NULL; // TODO: Merge the `it` with next and previous buffers. // [...**] // ^^----suffix----vv // [..+++] [+++++] [+++**] // ^^^ ^^^^^ ^^^ // +++ +++++ +++** // p0 p1 p2 ^-sx // http://cpp.sh/9yp22 // Copy to first (possible split) memi p0 = hale_minimum(buf_capacity - offset, size); // Copy to new buffers (full) memi p1 = (size-p0) & ~buf_align_mask; // Copy to last (partial) memi p2 = (size-p0) & buf_align_mask; // same as (data_size - r.p1 - r.p0); // Split size (won't underflow, as offset must be within the block (or == buf_length)) memi sx = buf_length(it0) - offset; hale_assert(p0 + p1 + p2 == size); // TODO: Check if we can put part of `p1`, `p2` into sx. // - `p1` probably makes no sense to be merged with sx, as it's already calculated to be full. memi n = 0; // if (p0 && sx) { n += 1; } n += p0 && sx; // if (p1) { n += p1 >> buf_capacity_shift; } n += p1 >> buf_align_shift; // if (p2) { n += 1; } n += !!p2; if (n) { it1 = allocate_buffers(arena, buf_index(arena, it0) + 1, n); // TODO: This wouldn't be needed if allocate_buffers wouldn't // invalidate the pointers. (deque?) it0 = it1 - 1; } if (p0) { if (sx) { hale_assert_requirement(n != 0) buf_move_suffix(it0, offset, it0 + n); // same as `it1 + n - 1` } buf_insert(it0, offset, data, p0); // `data` and `size` is used in `p1` and `p2`, // so we update he right away. data += p0; size -= p0; } if (p1) { hale_assert_debug(it1); while (size != p2) { // TODO: buf_set buf_insert(it1, 0, data, buf_capacity); data += buf_capacity; size -= buf_capacity; ++it1; } } if (p2) { hale_assert_requirement(it1); hale_assert_requirement(p2 == size); // TODO: buf_set buf_insert(it1, 0, data, p2); } }