From 9b59b50b44cd6e9dbe4dc20b85c214ad010fcb8c Mon Sep 17 00:00:00 2001 From: Alexander Vdolainen Date: Mon, 22 Mar 2021 18:42:26 +0200 Subject: [PATCH] IMAP auth test function; --- src/tests/testimap.c | 167 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 165 insertions(+), 2 deletions(-) diff --git a/src/tests/testimap.c b/src/tests/testimap.c index 896397c..21dacc9 100644 --- a/src/tests/testimap.c +++ b/src/tests/testimap.c @@ -31,11 +31,174 @@ #include #include #include +#include +#include -#include +#include #include +#include -int main(int argc, char **argv) +#define PRG_NAME "ejabberauth imap function test" + +/* + * The idea is stupid simple: take hostname, port, username and password + * move this data to the jabber message manually, connect to the host, + * run the function, check result and disconnect. + * Extra option -e (--expected-result) ok/fail to check the output from + * imap according to the expectations + */ + +static void print_help(const char *cname) +{ + fprintf(stdout, "\n%s - %s\n\n", cname, PRG_NAME); + fprintf(stdout, "USAGE:\n"); + fprintf(stdout, "\t%s -H | --host -p | --port -u | --user " + " -P | --password [ -e | --expected-result ] [ -v | --verbose ]", + cname); + fprintf(stdout, "\n\n\t%s -h | --help\n", cname); + + return; +} + +static int ejda_username_split(char *buf, char **user, char **domain) { + char *u, *d; + + if(!buf) return 1; + + u = strchr(buf, '@'); + if(!u) return 1; + else { + *u = '\0'; + *u++; + d = u; u = buf; + } + + *user = u; *domain = d; + return 0; } + +int main(int argc, char **argv) +{ + char *host, *port, *user, *password; + char *utbuf = NULL; + int verbose = 0, opt, expected = 0; + struct ejabber_msg m; + struct tlsport p; + + host = port = user = password = NULL; + + /* parse options */ + while(1) { + int option_index = 0; + static struct option long_options[] = { + {"help", no_argument, NULL, 'h'}, + {"host", required_argument, NULL, 'H'}, + {"port", required_argument, NULL, 'p'}, + {"user", required_argument, NULL, 'u'}, + {"password", required_argument, NULL, 'P'}, + {"expected-result", required_argument, NULL, 'e'}, + {"verbose", no_argument, NULL, 'v'}, + {NULL, 0, NULL, 0}, + }; + + if((opt = getopt_long(argc, argv, "hH:p:u:P:e:v", long_options, + &option_index)) == -1) break; + switch(opt) { + case 'h': + /* print help information and exit */ + print_help(argv[0]); + return 0; + break; + case 'H': host = optarg; break; + case 'p': port = optarg; break; + case 'u': user = optarg; break; + case 'P': password = optarg; break; + case 'e': + if(!strcmp(optarg, "fail")) expected = 1; + else expected = 0; + break; + case 'v': verbose = 1; break; + default: abort(); break; /* something that's shouldn't ever happen */ + } + } + + if(!host) { + fprintf(stderr, "Error: no hostname given.\n"); + main_einval: + print_help(argv[0]); + return EINVAL; + } + if(!port) { + fprintf(stderr, "Error: no port given.\n"); + goto main_einval; + } + if(!password) { + fprintf(stderr, "Error: no password provided.\n"); + goto main_einval; + } + + /* split user name */ + opt = strlen(user) + sizeof(char); + if((utbuf = malloc(opt)) == NULL) { + fprintf(stderr, "Error: not enough memory\n"); + return ENOMEM; + } else { + memset(utbuf, '\0', opt); + memcpy(utbuf, user, opt - sizeof(char)); + if(ejda_username_split(utbuf, &m.user, &m.domain)) { + fprintf(stderr, "Error: username is invalid.\n"); + free(utbuf); + return EINVAL; + } + } + /* prepare other data in the message */ + m.password = password; + + /* TLS stuff */ + ssllib_init(); + + if(verbose) { + fprintf(stdout, "Connecting to TLS port %s:%s ... ", host, port); + fflush(stdout); + } + + if(tls_connect(host, port, &p)) { + if(!verbose) + fprintf(stderr, "Error: failed to connect TLS port.\n"); + else fprintf(stdout, " failed\n"); + opt = -1; + goto mainmoi; + } + if(verbose) fprintf(stdout, " ok\n"); + + /* IMAP auth */ + if(verbose) { + fprintf(stdout, "IMAP auth u=%s:d=%s:p=%s ... ", m.user, m.domain, m.password); + fflush(stdout); + } + + opt = imap_auth(&p, &m); + /* invert result */ + if(expected && opt) opt = 0; + if(expected && !opt) opt = 1; + + if(opt) { + if(!verbose) fprintf(stderr, "IMAP auth returns not expected result.\n"); + else fprintf(stdout, " failed\n"); + opt = -1; + } else { + opt = 0; + if(verbose) fprintf(stdout, " ok\n"); + } + + tls_close(&p); + + mainmoi: + ssllib_free(); + free(utbuf); + + return opt; +} +