From 591ee61a6f55ab9bc18c9892e45c03b81eac538a Mon Sep 17 00:00:00 2001 From: Alexander Vdolainen Date: Mon, 19 Apr 2021 22:57:31 +0300 Subject: [PATCH] Tool is complete + wildlife testing is required. --- src/main.c | 142 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) diff --git a/src/main.c b/src/main.c index 25dddc3..861e6d7 100644 --- a/src/main.c +++ b/src/main.c @@ -19,7 +19,25 @@ */ #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include unsigned long djb_hash(const char *s) @@ -33,8 +51,132 @@ unsigned long djb_hash(const char *s) return hash; } +#define MAX_SUPPL_DATA 64 + +#define PRG_NAME "daemon for ejabberd to provide IMAPS/SMTPS auth" + +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 -S | --smtp-host -s | --smtp-port " + "-I | --imap-host -i | --imap-port ", cname); + fprintf(stdout, "\n\n\t%s -h | --help\n", cname); + fprintf(stdout, "\nNOTE: This program is designed to be used from ejabberd only.\n"); + + return; +} + int main(int argc, char **argv) { + char *smtp_host, *smtp_port, *imap_host, *imap_port; + char msgbuf[MAX_USER_LEN + MAX_DOMAIN_LEN + MAX_PASSWORD_LEN + MAX_SUPPL_DATA]; + struct tlsport connection; + struct ejabber_msg m; + int opt, msgbuflen = 0; + + smtp_host = smtp_port = imap_port = imap_host = NULL; + + while(1) { + int option_index = 0; + static struct option long_options[] = { + {"help", no_argument, NULL, 'h'}, + {"smtp-host", required_argument, NULL, 'S'}, + {"smtp-port", required_argument, NULL, 's'}, + {"imap-host", required_argument, NULL, 'I'}, + {"imap-port", required_argument, NULL, 'i'}, + {NULL, 0, NULL, 0}, + }; + + if((opt = getopt_long(argc, argv, "hS:s:I:i:", long_options, &option_index)) == -1) + break; + + switch(opt) { + case 'h': + print_help(argv[0]); + return 0; + break; + case 'S': smtp_host = optarg; break; + case 's': smtp_port = optarg; break; + case 'I': imap_host = optarg; break; + case 'i': imap_port = optarg; break; + default: abort(); break; + } + } + + /* arguments check up */ + if(!smtp_host || !smtp_port) { + fprintf(stderr, "Error: SMTPs information is not complete.\n"); + main_einval_moimoi: + print_help(argv[0]); + return EINVAL; + } + if(!imap_port || !imap_host) { + fprintf(stderr, "Error: IMAPs information is not complete.\n"); + goto main_einval_moimoi; + } + + /* take care about space borrowed from stack */ + msgbuflen = MAX_USER_LEN + MAX_DOMAIN_LEN + MAX_PASSWORD_LEN + MAX_SUPPL_DATA; + memset(msgbuf, 0, msgbuflen); + /* libs init */ + ssllib_init(); + + /* main loop */ + while(eport_read(stdin, msgbuf, msgbuflen) > 0) { + opt = eport_ejabberd_msgread(msgbuf, msgbuflen, &m); + if(opt > 0) { + abort_parsing: + fprintf(stderr, "Error: message isn't valid.\nExiting.\n"); + ssllib_free(); + abort(); + } + + /* deal with message */ + switch(ejabber_msg_event(&m)) { + case EJA_AUTH: + if(opt != 3) goto abort_parsing; + + /* connect to IMAPs */ + if(tls_connect(imap_host, imap_port, &connection)) { + fprintf(stderr, "Error: unable to connect to IMAPs.\n"); + opt = -1; + } else { + opt = imap_auth(&connection, &m); + tls_close(&connection); + } + break; + case EJA_ISUSER: + if(opt != 2) goto abort_parsing; + + /* connect to SMTPs */ + if(tls_connect(smtp_host, smtp_port, &connection)) { + fprintf(stderr, "Error: unable to connect to SMTPs.\n"); + opt = -1; + } else { + opt = smtp_checkuser(&connection, &m, smtp_host); + tls_close(&connection); + } + break; + case EJA_SETPASS: + case EJA_TRYREGISTER: + case EJA_REMOVEUSER: + case EJA_REMOVEUSER3: + /* still aren't supported by the program */ + fprintf(stderr, "Error: This type of message are not supported.\n"); + opt = -1; + break; + case EJA_UNKNOWN: + default: /* something goes wrong with message */ + goto abort_parsing; + break; + } + + /* finally, reply ... */ + eport_write(stdout, (char *)((int16_t *)&opt), sizeof(int16_t)); + } + + ssllib_free(); return 0; }