thc-hydra/hydra-pop3.c
2017-07-05 08:48:00 +02:00

784 lines
22 KiB
C

#include "hydra-mod.h"
#include "sasl.h"
//openssl s_client -starttls pop3 -crlf -connect 192.168.0.10:110
typedef struct pool_str {
char ip[36];
/* int32_t port;*/// not needed
int32_t pop3_auth_mechanism;
int32_t disable_tls;
struct pool_str *next;
} pool;
extern char *HYDRA_EXIT;
char *buf;
char apop_challenge[300] = "";
pool *plist = NULL, *p = NULL;
/* functions */
int32_t service_pop3_init(char *ip, int32_t sp, unsigned char options, char *miscptr, FILE * fp, int32_t port, char *hostname);
pool *list_create(pool data) {
pool *p;
if (!(p = malloc(sizeof(pool))))
return NULL;
memcpy(p->ip, data.ip, 36);
//p->port = data.port;
p->pop3_auth_mechanism = data.pop3_auth_mechanism;
p->disable_tls = data.disable_tls;
p->next = NULL;
return p;
}
pool *list_insert(pool data) {
pool *newnode;
newnode = list_create(data);
newnode->next = plist;
plist = newnode->next; // to be sure!
return newnode;
}
pool *list_find(char *ip) {
pool *node = plist;
while (node != NULL) {
if (memcmp(node->ip, ip, 36) == 0)
return node;
node = node->next;
}
return NULL;
}
/* how to know when to release the mem ?
-> well, after _start has determined which pool number it is */
int32_t list_remove(pool * node) {
pool *save, *list = plist;
int32_t ok = -1;
if (list == NULL || node == NULL)
return -2;
do {
save = list->next;
if (list != node)
free(list);
else
ok = 0;
list = save;
} while (list != NULL);
return ok;
}
char *pop3_read_server_capacity(int32_t sock) {
char *ptr = NULL;
int32_t resp = 0;
char *buf = NULL;
do {
if (buf != NULL)
free(buf);
ptr = buf = hydra_receive_line(sock);
if (buf != NULL) {
/*
exchange capa:
+OK
UIDL
STLS
*/
if (strstr(buf, "\r\n.\r\n") != NULL && buf[0] == '+') {
resp = 1;
/* we got the capability info then get the completed warning info from server */
while (hydra_data_ready(sock)) {
free(buf);
buf = hydra_receive_line(sock);
}
} else {
if (buf[strlen(buf) - 1] == '\n')
buf[strlen(buf) - 1] = 0;
if (buf[strlen(buf) - 1] == '\r')
buf[strlen(buf) - 1] = 0;
if (*(ptr) == '.' || *(ptr) == '-')
resp = 1;
}
}
} while (buf != NULL && resp == 0);
return buf;
}
int32_t start_pop3(int32_t s, char *ip, int32_t port, unsigned char options, char *miscptr, FILE * fp) {
char *empty = "\"\"";
char *login, *pass, buffer[500], buffer2[500], *fooptr;
if (strlen(login = hydra_get_next_login()) == 0)
login = empty;
if (strlen(pass = hydra_get_next_password()) == 0)
pass = empty;
while (hydra_data_ready(s) > 0) {
if ((buf = hydra_receive_line(s)) == NULL)
return 4;
free(buf);
}
switch (p->pop3_auth_mechanism) {
#ifdef LIBOPENSSL
case AUTH_APOP:{
MD5_CTX c;
unsigned char md5_raw[MD5_DIGEST_LENGTH];
int32_t i;
char *pbuffer = buffer2;
MD5_Init(&c);
MD5_Update(&c, apop_challenge, strlen(apop_challenge));
MD5_Update(&c, pass, strlen(pass));
MD5_Final(md5_raw, &c);
for (i = 0; i < MD5_DIGEST_LENGTH; i++) {
sprintf(pbuffer, "%02x", md5_raw[i]);
pbuffer += 2;
}
sprintf(buffer, "APOP %s %s\r\n", login, buffer2);
}
break;
#endif
case AUTH_LOGIN:{
sprintf(buffer, "AUTH LOGIN\r\n");
if (hydra_send(s, buffer, strlen(buffer), 0) < 0) {
return 1;
}
if ((buf = hydra_receive_line(s)) == NULL)
return 4;
if (buf[0] != '+') {
hydra_report(stderr, "[ERROR] POP3 LOGIN AUTH : %s\n", buf);
free(buf);
return 3;
}
free(buf);
strcpy(buffer2, login);
hydra_tobase64((unsigned char *) buffer2, strlen(buffer2), sizeof(buffer2));
sprintf(buffer, "%.250s\r\n", buffer2);
if (hydra_send(s, buffer, strlen(buffer), 0) < 0) {
return 1;
}
if ((buf = hydra_receive_line(s)) == NULL)
return 4;
if (buf[0] != '+') {
hydra_report(stderr, "[ERROR] POP3 LOGIN AUTH : %s\n", buf);
free(buf);
return 3;
}
free(buf);
strcpy(buffer2, pass);
hydra_tobase64((unsigned char *) buffer2, strlen(buffer2), sizeof(buffer2));
sprintf(buffer, "%.250s\r\n", buffer2);
}
break;
case AUTH_PLAIN:{
sprintf(buffer, "AUTH PLAIN\r\n");
if (hydra_send(s, buffer, strlen(buffer), 0) < 0) {
return 1;
}
if ((buf = hydra_receive_line(s)) == NULL)
return 4;
if (buf[0] != '+') {
hydra_report(stderr, "[ERROR] POP3 PLAIN AUTH : %s\n", buf);
free(buf);
return 3;
}
free(buf);
memset(buffer, 0, sizeof(buffer));
sasl_plain(buffer, login, pass);
char tmp_buffer[sizeof(buffer)];
sprintf(tmp_buffer, "%.250s\r\n", buffer);
strcpy(buffer, tmp_buffer);
}
break;
#ifdef LIBOPENSSL
case AUTH_CRAMMD5:
case AUTH_CRAMSHA1:
case AUTH_CRAMSHA256:{
int32_t rc = 0;
char *preplogin;
rc = sasl_saslprep(login, SASL_ALLOW_UNASSIGNED, &preplogin);
if (rc) {
return 3;
}
switch (p->pop3_auth_mechanism) {
case AUTH_CRAMMD5:
sprintf(buffer, "AUTH CRAM-MD5\r\n");
break;
case AUTH_CRAMSHA1:
sprintf(buffer, "AUTH CRAM-SHA1\r\n");
break;
case AUTH_CRAMSHA256:
sprintf(buffer, "AUTH CRAM-SHA256\r\n");
break;
}
if (hydra_send(s, buffer, strlen(buffer), 0) < 0) {
return 1;
}
//get the one-time BASE64 encoded challenge
if ((buf = hydra_receive_line(s)) == NULL)
return 4;
if (buf[0] != '+') {
switch (p->pop3_auth_mechanism) {
case AUTH_CRAMMD5:
hydra_report(stderr, "[ERROR] POP3 CRAM-MD5 AUTH : %s\n", buf);
break;
case AUTH_CRAMSHA1:
hydra_report(stderr, "[ERROR] POP3 CRAM-SHA1 AUTH : %s\n", buf);
break;
case AUTH_CRAMSHA256:
hydra_report(stderr, "[ERROR] POP3 CRAM-SHA256 AUTH : %s\n", buf);
break;
}
free(buf);
return 3;
}
memset(buffer, 0, sizeof(buffer));
from64tobits((char *) buffer, buf + 2);
free(buf);
memset(buffer2, 0, sizeof(buffer2));
switch (p->pop3_auth_mechanism) {
case AUTH_CRAMMD5:{
sasl_cram_md5(buffer2, pass, buffer);
sprintf(buffer, "%s %.250s", preplogin, buffer2);
}
break;
case AUTH_CRAMSHA1:{
sasl_cram_sha1(buffer2, pass, buffer);
sprintf(buffer, "%s %.250s", preplogin, buffer2);
}
break;
case AUTH_CRAMSHA256:{
sasl_cram_sha256(buffer2, pass, buffer);
sprintf(buffer, "%s %.250s", preplogin, buffer2);
}
break;
}
hydra_tobase64((unsigned char *) buffer, strlen(buffer), sizeof(buffer));
char tmp_buffer[sizeof(buffer)];
sprintf(tmp_buffer, "%.250s\r\n", buffer);
strcpy(buffer, tmp_buffer);
free(preplogin);
}
break;
case AUTH_DIGESTMD5:{
sprintf(buffer, "AUTH DIGEST-MD5\r\n");
if (hydra_send(s, buffer, strlen(buffer), 0) < 0)
return 1;
//receive
if ((buf = hydra_receive_line(s)) == NULL)
return 4;
if (buf[0] != '+') {
hydra_report(stderr, "[ERROR] POP3 DIGEST-MD5 AUTH : %s\n", buf);
free(buf);
return 3;
}
memset(buffer, 0, sizeof(buffer));
from64tobits((char *) buffer, buf);
free(buf);
if (debug)
hydra_report(stderr, "[DEBUG] S: %s\n", buffer);
fooptr = buffer2;
sasl_digest_md5(fooptr, login, pass, buffer, miscptr, "pop", NULL, 0, NULL);
if (fooptr == NULL)
return 3;
if (debug)
hydra_report(stderr, "[DEBUG] C: %s\n", buffer2);
hydra_tobase64((unsigned char *) buffer2, strlen(buffer2), sizeof(buffer2));
sprintf(buffer, "%s\r\n", buffer2);
}
break;
#endif
case AUTH_NTLM:{
unsigned char buf1[4096];
unsigned char buf2[4096];
//Send auth request
sprintf(buffer, "AUTH NTLM\r\n");
if (hydra_send(s, buffer, strlen(buffer), 0) < 0)
return 1;
//receive
if ((buf = hydra_receive_line(s)) == NULL)
return 4;
if (buf[0] != '+') {
hydra_report(stderr, "[ERROR] POP3 NTLM AUTH : %s\n", buf);
free(buf);
return 3;
}
free(buf);
//send auth and receive challenge
//send auth request: lst the server send it's own hostname and domainname
buildAuthRequest((tSmbNtlmAuthRequest *) buf2, 0, NULL, NULL);
to64frombits(buf1, buf2, SmbLength((tSmbNtlmAuthRequest *) buf2));
sprintf(buffer, "%s\r\n", buf1);
if (hydra_send(s, buffer, strlen(buffer), 0) < 0)
return 1;
if ((buf = hydra_receive_line(s)) == NULL || strlen(buf) < 6)
return 4;
//recover challenge
from64tobits((char *) buf1, buf + 2);
free(buf);
//Send response
buildAuthResponse((tSmbNtlmAuthChallenge *) buf1, (tSmbNtlmAuthResponse *) buf2, 0, login, pass, NULL, NULL);
to64frombits(buf1, buf2, SmbLength((tSmbNtlmAuthResponse *) buf2));
sprintf(buffer, "%s\r\n", buf1);
}
break;
default:
sprintf(buffer, "USER %.250s\r\n", login);
if (hydra_send(s, buffer, strlen(buffer), 0) < 0) {
return 1;
}
if ((buf = hydra_receive_line(s)) == NULL)
return 4;
if (buf[0] != '+') {
hydra_report(stderr, "[ERROR] POP3 protocol or service shutdown: %s\n", buf);
free(buf);
return (3);
}
free(buf);
sprintf(buffer, "PASS %.250s\r\n", pass);
}
if (hydra_send(s, buffer, strlen(buffer), 0) < 0) {
return 1;
}
if ((buf = hydra_receive_line(s)) == NULL) {
return 4;
}
if (buf[0] == '+') {
hydra_report_found_host(port, ip, "pop3", fp);
hydra_completed_pair_found();
free(buf);
if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0)
return 3;
return 1;
}
/* special AS/400 hack */
if (strstr(buf, "CPF2204") != NULL || strstr(buf, "CPF22E3") != NULL || strstr(buf, "CPF22E4") != NULL || strstr(buf, "CPF22E5") != NULL) {
if (verbose)
printf("[INFO] user %s does not exist, skipping\n", login);
hydra_completed_pair_skip();
free(buf);
if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0)
return 3;
return 1;
}
free(buf);
hydra_completed_pair();
if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0)
return 3;
return 2;
}
void service_pop3(char *ip, int32_t sp, unsigned char options, char *miscptr, FILE * fp, int32_t port, char *hostname) {
int32_t run = 1, next_run = 1, sock = -1;
char *ptr = NULL;
//extract data from the pool, ip is the key
if (plist == NULL)
if (service_pop3_init(ip, sp, options, miscptr, fp, port, hostname) != 0)
hydra_child_exit(2);
p = list_find(ip);
if (p == NULL) {
hydra_report(stderr, "[ERROR] Could not find ip %s in pool\n", hydra_address2string(ip));
return;
}
if (list_remove(p) != 0)
hydra_report(stderr, "[ERROR] Could not find ip %s in pool to free memory\n", hydra_address2string(ip));
hydra_register_socket(sp);
if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0)
return;
while (1) {
switch (run) {
case 1: /* connect and service init function */
if (sock >= 0)
sock = hydra_disconnect(sock);
// usleepn(300);
if ((options & OPTION_SSL) == 0) {
sock = hydra_connect_tcp(ip, port);
} else {
sock = hydra_connect_ssl(ip, port, hostname);
}
if (sock < 0) {
if (verbose || debug)
hydra_report(stderr, "[ERROR] Child with pid %d terminating, can not connect\n", (int32_t) getpid());
hydra_child_exit(1);
}
buf = hydra_receive_line(sock);
if (buf == NULL || buf[0] != '+') { /* check the first line */
if (verbose || debug)
hydra_report(stderr, "[ERROR] Not an POP3 protocol or service shutdown: %s\n", buf);
hydra_child_exit(2);
}
ptr = strstr(buf, "<");
if (ptr != NULL && buf[0] == '+') {
if (ptr[strlen(ptr) - 1] == '\n')
ptr[strlen(ptr) - 1] = 0;
if (ptr[strlen(ptr) - 1] == '\r')
ptr[strlen(ptr) - 1] = 0;
strcpy(apop_challenge, ptr);
}
free(buf);
#ifdef LIBOPENSSL
if (!p->disable_tls) {
/* check for STARTTLS, if available we may have access to more basic auth methods */
hydra_send(sock, "STLS\r\n", strlen("STLS\r\n"), 0);
buf = hydra_receive_line(sock);
if (buf[0] != '+') {
hydra_report(stderr, "[ERROR] TLS negotiation failed, no answer received from STARTTLS request\n");
} else {
free(buf);
if ((hydra_connect_to_ssl(sock, hostname) == -1)) {
if (verbose)
hydra_report(stderr, "[ERROR] Can't use TLS\n");
p->disable_tls = 1;
} else {
if (verbose)
hydra_report(stderr, "[VERBOSE] TLS connection done\n");
}
}
}
#endif
next_run = 2;
break;
case 2: /* run the cracking function */
next_run = start_pop3(sock, ip, port, options, miscptr, fp);
break;
case 3: /* clean exit */
if (sock >= 0)
sock = hydra_disconnect(sock);
hydra_child_exit(0);
return;
case 4: /* clean exit */
if (sock >= 0)
sock = hydra_disconnect(sock);
hydra_child_exit(2);
return;
default:
hydra_report(stderr, "[ERROR] Caught unknown return code, exiting!\n");
hydra_child_exit(0);
}
run = next_run;
}
}
int32_t service_pop3_init(char *ip, int32_t sp, unsigned char options, char *miscptr, FILE * fp, int32_t port, char *hostname) {
int32_t myport = PORT_POP3, mysslport = PORT_POP3_SSL;
char *ptr = NULL;
int32_t sock = -1;
char *capa_str = "CAPA\r\n";
char *quit_str = "QUIT\r\n";
pool p;
p.pop3_auth_mechanism = AUTH_CLEAR;
p.disable_tls = 1;
memcpy(p.ip, ip, 36);
if ((options & OPTION_SSL) == 0) {
if (port != 0)
myport = port;
sock = hydra_connect_tcp(p.ip, myport);
} else {
if (port != 0)
mysslport = port;
sock = hydra_connect_ssl(p.ip, mysslport, hostname);
}
if (sock < 0) {
if (verbose || debug)
hydra_report(stderr, "[ERROR] pid %d terminating, can not connect\n", (int32_t) getpid());
return -1;
}
buf = hydra_receive_line(sock);
if (buf == NULL || buf[0] != '+') { /* check the first line */
if (verbose || debug)
hydra_report(stderr, "[ERROR] Not an POP3 protocol or service shutdown: %s\n", buf);
return -1;
}
ptr = strstr(buf, "<");
if (ptr != NULL && buf[0] == '+') {
if (ptr[strlen(ptr) - 1] == '\n')
ptr[strlen(ptr) - 1] = 0;
if (ptr[strlen(ptr) - 1] == '\r')
ptr[strlen(ptr) - 1] = 0;
strcpy(apop_challenge, ptr);
}
free(buf);
/* send capability request */
if (hydra_send(sock, capa_str, strlen(capa_str), 0) < 0) {
if (verbose || debug)
hydra_report(stderr, "[ERROR] Can not send the CAPABILITY request\n");
return -1;
}
buf = pop3_read_server_capacity(sock);
if (buf == NULL) {
hydra_report(stderr, "[ERROR] No answer from CAPABILITY request\n");
return -1;
}
if ((miscptr != NULL) && (strlen(miscptr) > 0)) {
int32_t i;
for (i = 0; i < strlen(miscptr); i++)
miscptr[i] = (char) toupper((int32_t) miscptr[i]);
if (strstr(miscptr, "TLS") || strstr(miscptr, "SSL") || strstr(miscptr, "STARTTLS")) {
p.disable_tls = 0;
}
}
#ifdef LIBOPENSSL
if (!p.disable_tls) {
/* check for STARTTLS, if available we may have access to more basic auth methods */
if (strstr(buf, "STLS") != NULL) {
hydra_send(sock, "STLS\r\n", strlen("STLS\r\n"), 0);
free(buf);
buf = hydra_receive_line(sock);
if (buf[0] != '+') {
hydra_report(stderr, "[ERROR] TLS negotiation failed, no answer received from STARTTLS request\n");
} else {
free(buf);
if ((hydra_connect_to_ssl(sock, hostname) == -1)) {
if (verbose)
hydra_report(stderr, "[ERROR] Can't use TLS\n");
p.disable_tls = 1;
} else {
if (verbose)
hydra_report(stderr, "[VERBOSE] TLS connection done\n");
}
if (!p.disable_tls) {
/* ask again capability request but in TLS mode */
if (hydra_send(sock, capa_str, strlen(capa_str), 0) < 0) {
if (verbose || debug)
hydra_report(stderr, "[ERROR] Can not send the CAPABILITY request\n");
return -1;
}
buf = pop3_read_server_capacity(sock);
if (buf == NULL) {
hydra_report(stderr, "[ERROR] No answer from CAPABILITY request\n");
return -1;
}
}
}
} else
hydra_report(stderr, "[ERROR] option to use TLS/SSL failed as it is not supported by the server\n");
}
#endif
if (hydra_send(sock, quit_str, strlen(quit_str), 0) < 0) {
//we dont care if the server is not receiving the quit msg
}
hydra_disconnect(sock);
if (verbose)
hydra_report(stderr, "[VERBOSE] CAPABILITY: %s", buf);
/* example:
+OK Capability list follows:
TOP
LOGIN-DELAY 180
UIDL
USER
SASL PLAIN LOGIN
*/
/* according to rfc 2449:
The POP3 AUTH command [POP-AUTH] permits the use of [SASL]
authentication mechanisms with POP3. The SASL capability
indicates that the AUTH command is available and that it supports
an optional base64 encoded second argument for an initial client
response as described in the SASL specification. The argument to
the SASL capability is a space separated list of SASL mechanisms
which are supported.
*/
/* which mean threre will *always* have a space before the LOGIN auth keyword */
if ((strstr(buf, " LOGIN") == NULL) && (strstr(buf, "NTLM") != NULL)) {
p.pop3_auth_mechanism = AUTH_NTLM;
}
#ifdef LIBOPENSSL
if ((strstr(buf, " LOGIN") == NULL) && (strstr(buf, "DIGEST-MD5") != NULL)) {
p.pop3_auth_mechanism = AUTH_DIGESTMD5;
}
if ((strstr(buf, " LOGIN") == NULL) && (strstr(buf, "CRAM-SHA256") != NULL)) {
p.pop3_auth_mechanism = AUTH_CRAMSHA256;
}
if ((strstr(buf, " LOGIN") == NULL) && (strstr(buf, "CRAM-SHA1") != NULL)) {
p.pop3_auth_mechanism = AUTH_CRAMSHA1;
}
if ((strstr(buf, " LOGIN") == NULL) && (strstr(buf, "CRAM-MD5") != NULL)) {
p.pop3_auth_mechanism = AUTH_CRAMMD5;
}
#endif
if ((strstr(buf, " LOGIN") == NULL) && (strstr(buf, "PLAIN") != NULL)) {
p.pop3_auth_mechanism = AUTH_PLAIN;
}
if (strstr(buf, " LOGIN") != NULL) {
p.pop3_auth_mechanism = AUTH_LOGIN;
}
if (strstr(buf, "SASL") == NULL) {
#ifdef LIBOPENSSL
if (strlen(apop_challenge) == 0) {
p.pop3_auth_mechanism = AUTH_CLEAR;
} else {
p.pop3_auth_mechanism = AUTH_APOP;
}
#else
p.pop3_auth_mechanism = AUTH_CLEAR;
#endif
}
free(buf);
if ((miscptr != NULL) && (strlen(miscptr) > 0)) {
if (strstr(miscptr, "CLEAR"))
p.pop3_auth_mechanism = AUTH_CLEAR;
if (strstr(miscptr, "LOGIN"))
p.pop3_auth_mechanism = AUTH_LOGIN;
if (strstr(miscptr, "PLAIN"))
p.pop3_auth_mechanism = AUTH_PLAIN;
#ifdef LIBOPENSSL
if (strstr(miscptr, "APOP"))
p.pop3_auth_mechanism = AUTH_APOP;
if (strstr(miscptr, "CRAM-MD5"))
p.pop3_auth_mechanism = AUTH_CRAMMD5;
if (strstr(miscptr, "CRAM-SHA1"))
p.pop3_auth_mechanism = AUTH_CRAMSHA1;
if (strstr(miscptr, "CRAM-SHA256"))
p.pop3_auth_mechanism = AUTH_CRAMSHA256;
if (strstr(miscptr, "DIGEST-MD5"))
p.pop3_auth_mechanism = AUTH_DIGESTMD5;
#endif
if (strstr(miscptr, "NTLM"))
p.pop3_auth_mechanism = AUTH_NTLM;
}
if (verbose) {
switch (p.pop3_auth_mechanism) {
case AUTH_CLEAR:
hydra_report(stderr, "[VERBOSE] using POP3 CLEAR LOGIN mechanism\n");
break;
case AUTH_LOGIN:
hydra_report(stderr, "[VERBOSE] using POP3 LOGIN AUTH mechanism\n");
break;
case AUTH_PLAIN:
hydra_report(stderr, "[VERBOSE] using POP3 PLAIN AUTH mechanism\n");
break;
case AUTH_APOP:
#ifdef LIBOPENSSL
if (strlen(apop_challenge) == 0) {
hydra_report(stderr, "[VERBOSE] APOP not supported by server, using clear login\n");
p.pop3_auth_mechanism = AUTH_CLEAR;
} else {
hydra_report(stderr, "[VERBOSE] using POP3 APOP AUTH mechanism\n");
}
#else
p.pop3_auth_mechanism = AUTH_CLEAR;
#endif
break;
#ifdef LIBOPENSSL
case AUTH_CRAMMD5:
hydra_report(stderr, "[VERBOSE] using POP3 CRAM-MD5 AUTH mechanism\n");
break;
case AUTH_CRAMSHA1:
hydra_report(stderr, "[VERBOSE] using POP3 CRAM-SHA1 AUTH mechanism\n");
break;
case AUTH_CRAMSHA256:
hydra_report(stderr, "[VERBOSE] using POP3 CRAM-SHA256 AUTH mechanism\n");
break;
case AUTH_DIGESTMD5:
hydra_report(stderr, "[VERBOSE] using POP3 DIGEST-MD5 AUTH mechanism\n");
break;
#endif
case AUTH_NTLM:
hydra_report(stderr, "[VERBOSE] using POP3 NTLM AUTH mechanism\n");
break;
}
}
if (!plist)
plist = list_create(p);
else
plist = list_insert(p);
return 0;
}
void usage_pop3(const char* service) {
printf("Module pop3 is optionally taking one authentication type of:\n"
" CLEAR (default), LOGIN, PLAIN, CRAM-MD5, CRAM-SHA1,\n"
" CRAM-SHA256, DIGEST-MD5, NTLM.\n" "Additionally TLS encryption via STLS can be enforced with the TLS option.\n\n" "Example: pop3://target/TLS:PLAIN\n");
}