From 26d8dd7e5ef736dd9e78153df037a3de84bbf875 Mon Sep 17 00:00:00 2001 From: Alexander Vdolainen Date: Tue, 6 Apr 2021 00:33:41 +0300 Subject: [PATCH] SMTP test function has been done; --- src/tests/testsmtp.c | 134 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 133 insertions(+), 1 deletion(-) diff --git a/src/tests/testsmtp.c b/src/tests/testsmtp.c index 2a6878a..7fd5302 100644 --- a/src/tests/testsmtp.c +++ b/src/tests/testsmtp.c @@ -40,9 +40,141 @@ #define PRG_NAME "ejabberauth smtp function test" +extern int ejda_username_split(char *buf, char **user, char **domain); + +/* + * 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 " + " [ -e | --expected-result ] [ -v | --verbose ]", cname); + fprintf(stdout, "\n\n\t%s -h | --help\n", cname); + + return; +} + int main(int argc, char **argv) { - return 0; + char *host, *port, *user; + char *utbuf = NULL; + int verbose = 0, opt, expected = 0; + struct ejabber_msg m; + struct tlsport p; + + host = port = user = 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'}, + {"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 '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; + } + + /* 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; + } + } + + /* TLS stuff, init and connect */ + 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"); + opt = 0; + + /* SMTP check user */ + if(verbose) { + fprintf(stdout, "SMTP check user u=%s:d=%s ... ", m.user, m.domain); + fflush(stdout); + } + + opt = smtp_checkuser(&p, &m, host); + /* invert result */ + if(expected && opt) opt = 0; + if(expected && !opt) opt = 1; + + if(opt) { + if(!verbose) fprintf(stderr, "SMTP check user 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; }