static void telnet_parse( const struct Banner1 *banner1, void *banner1_private, struct ProtocolState *pstate, const unsigned char *px, size_t length, struct BannerOutput *banout, struct InteractiveData *more) { unsigned state = pstate->state; unsigned i; UNUSEDPARM(banner1_private); UNUSEDPARM(banner1); UNUSEDPARM(more); for (i=0; i<length; i++) switch (state) { case 0: if (px[i] == '\r') continue; if (px[i] == '\n' || px[i] == '\0' || !isprint(px[i])) { state++; tcp_close(more); continue; } banout_append_char(banout, PROTO_SSH2, px[i]); break; default: i = (unsigned)length; break; } pstate->state = state; }
static void imap4_parse( const struct Banner1 *banner1, void *banner1_private, struct ProtocolState *pstate, const unsigned char *px, size_t length, struct BannerOutput *banout, struct InteractiveData *more) { unsigned state = pstate->state; unsigned i; UNUSEDPARM(banner1_private); UNUSEDPARM(banner1); for (i=0; i<length; i++) { if (px[i] == '\r') continue; switch (state) { case 0: banout_append_char(banout, PROTO_IMAP4, px[i]); if (px[i] == '*') state++; else state = STATE_DONE; break; case 1: if (px[i] == ' ') { banout_append_char(banout, PROTO_IMAP4, px[i]); continue; } else state++; /* fall through */ case 2: banout_append_char(banout, PROTO_IMAP4, px[i]); if (px[i] == 'O') state++; else state = STATE_DONE; break; case 3: banout_append_char(banout, PROTO_IMAP4, px[i]); if (px[i] == 'K') state++; else state = STATE_DONE; break; case 4: if (px[i] == ' ') { banout_append_char(banout, PROTO_IMAP4, px[i]); state++; break; } else if (px[i] != '\n') { banout_append_char(banout, PROTO_IMAP4, px[i]); /* no transition */ break; } else { state++; /* fall through */ } case 5: banout_append_char(banout, PROTO_IMAP4, px[i]); if (px[i] == '\n') { tcp_transmit(more, "a001 CAPABILITY\r\n", 17); state = 100; } break; case 100: case 300: banout_append_char(banout, PROTO_IMAP4, px[i]); if (px[i] == '*') state += 100; else if (px[i] == 'a') state++; else state = STATE_DONE; break; case 101: case 301: banout_append_char(banout, PROTO_IMAP4, px[i]); if (px[i] == '0') state++; else state = STATE_DONE; break; case 102: case 302: banout_append_char(banout, PROTO_IMAP4, px[i]); if (px[i] == '0') state++; else state = STATE_DONE; break; case 103: banout_append_char(banout, PROTO_IMAP4, px[i]); if (px[i] == '1') state++; else state = STATE_DONE; break; case 303: banout_append_char(banout, PROTO_IMAP4, px[i]); if (px[i] == '2') state++; else state = STATE_DONE; break; case 104: case 304: banout_append_char(banout, PROTO_IMAP4, px[i]); if (px[i] == ' ') state++; else state = STATE_DONE; break; case 105: banout_append_char(banout, PROTO_IMAP4, px[i]); if (px[i] == '\n') { tcp_transmit(more, "a002 STARTTLS\r\n", 15); state = 300; } break; case 200: case 400: banout_append_char(banout, PROTO_IMAP4, px[i]); if (px[i] == '\n') state -= 100; break; case 305: if (px[i] == '\n') { /* change the state here to SSL */ unsigned port = pstate->port; memset(pstate, 0, sizeof(*pstate)); pstate->app_proto = PROTO_SSL3; pstate->is_sent_sslhello = 1; pstate->port = (unsigned short)port; state = 0; more->payload = banner_ssl.hello; more->length = (unsigned)banner_ssl.hello_length; break; } break; default: i = (unsigned)length; break; } } pstate->state = state; }
static void smtp_parse( const struct Banner1 *banner1, void *banner1_private, struct ProtocolState *pstate, const unsigned char *px, size_t length, struct BannerOutput *banout, struct InteractiveData *more) { unsigned state = pstate->state; unsigned i; struct SMTPSTUFF *smtp = &pstate->sub.smtp; UNUSEDPARM(banner1_private); UNUSEDPARM(banner1); for (i=0; i<length; i++) { switch (state) { case 0: case 100: case 200: smtp->code = 0; state++; /* fall through */ case 1: case 2: case 3: case 101: case 102: case 103: case 201: case 202: case 203: if (!isdigit(px[i]&0xFF)) { state = STATE_DONE; } else { smtp->code *= 10; smtp->code += (px[i] - '0'); state++; banout_append_char(banout, PROTO_SMTP, px[i]); } break; case 4: case 104: case 204: if (px[i] == ' ') { smtp->is_last = 1; state++; banout_append_char(banout, PROTO_SMTP, px[i]); } else if (px[i] == '-') { smtp->is_last = 0; state++; banout_append_char(banout, PROTO_SMTP, px[i]); } else { state = STATE_DONE; } break; case 5: if (px[i] == '\r') continue; else if (px[i] == '\n') { if (smtp->is_last) { more->payload = "EHLO masscan\r\n"; more->length = 14; state = 100; banout_append_char(banout, PROTO_SMTP, px[i]); } else { banout_append_char(banout, PROTO_SMTP, px[i]); state = 0; } } else if (px[i] == '\0' || !isprint(px[i])) { state = STATE_DONE; continue; } else { banout_append_char(banout, PROTO_SMTP, px[i]); } break; case 105: if (px[i] == '\r') continue; else if (px[i] == '\n') { if (smtp->is_last) { more->payload = "STARTTLS\r\n"; more->length = 10; state = 200; banout_append_char(banout, PROTO_SMTP, px[i]); } else { banout_append_char(banout, PROTO_SMTP, px[i]); state = 100; } } else if (px[i] == '\0' || !isprint(px[i])) { state = STATE_DONE; continue; } else { banout_append_char(banout, PROTO_SMTP, px[i]); } break; case 205: if (px[i] == '\r') continue; else if (px[i] == '\n') { if (smtp->code == 220) { /* change the state here to SSL */ unsigned port = pstate->port; memset(pstate, 0, sizeof(*pstate)); pstate->app_proto = PROTO_SSL3; pstate->is_sent_sslhello = 1; pstate->port = (unsigned short)port; state = 0; more->payload = banner_ssl.hello; more->length = (unsigned)banner_ssl.hello_length; } else { state = STATE_DONE; } } else if (px[i] == '\0' || !isprint(px[i])) { state = STATE_DONE; continue; } else { banout_append_char(banout, PROTO_SMTP, px[i]); } break; default: i = (unsigned)length; break; } } pstate->state = state; }
static void pop3_parse( const struct Banner1 *banner1, void *banner1_private, struct ProtocolState *pstate, const unsigned char *px, size_t length, struct BannerOutput *banout, struct InteractiveData *more) { unsigned state = pstate->state; unsigned i; UNUSEDPARM(banner1_private); UNUSEDPARM(banner1); for (i=0; i<length; i++) { if (px[i] == '\r') continue; switch (state) { case 0: case 1: case 2: banout_append_char(banout, PROTO_POP3, px[i]); if ("+OK"[state] != px[i]) state = STATE_DONE; else state++; break; case 3: banout_append_char(banout, PROTO_POP3, px[i]); if (px[i] == '\n') { tcp_transmit(more, "CAPA\r\n", 6); state++; } break; case 4: case 204: banout_append_char(banout, PROTO_POP3, px[i]); if (px[i] == '-') state = 100; else if (px[i] == '+') state++; else { state = STATE_DONE; } break; case 5: case 205: banout_append_char(banout, PROTO_POP3, px[i]); if (px[i] == 'O') state++; else state = STATE_DONE; break; case 6: case 206: banout_append_char(banout, PROTO_POP3, px[i]); if (px[i] == 'K') state += 2; /* oops, I had too many states here */ else state = STATE_DONE; break; case 8: if (px[i] == '\r') continue; banout_append_char(banout, PROTO_POP3, px[i]); if (px[i] == '\n') state++; break; case 9: if (px[i] == '\r') continue; banout_append_char(banout, PROTO_POP3, px[i]); if (px[i] == '.') state++; else if (px[i] == '\n') continue; else state--; break; case 10: if (px[i] == '\r') continue; banout_append_char(banout, PROTO_POP3, px[i]); if (px[i] == '\n') { tcp_transmit(more, "STLS\r\n", 6); state = 204; } else { state = 8; } break; case 208: if (px[i] == '\r') continue; banout_append_char(banout, PROTO_POP3, px[i]); if (px[i] == '\n') { /* change the state here to SSL */ unsigned port = pstate->port; memset(pstate, 0, sizeof(*pstate)); pstate->app_proto = PROTO_SSL3; pstate->is_sent_sslhello = 1; pstate->port = (unsigned short)port; state = 0; more->payload = banner_ssl.hello; more->length = (unsigned)banner_ssl.hello_length; break; } break; case 100: if (px[i] == '\r') continue; banout_append_char(banout, PROTO_POP3, px[i]); if (px[i] == '\n') state = STATE_DONE; break; default: i = (unsigned)length; break; } } pstate->state = state; }