Tool is complete + wildlife testing is required.

master
Alexander Vdolainen 4 years ago
parent 51e43425ce
commit 591ee61a6f

@ -19,7 +19,25 @@
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/select.h>
#include <errno.h>
#include <netdb.h>
#include <string.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <stdarg.h>
#include <getopt.h>
#include <ejabbermsg.h>
#include <tlsport.h>
#include <imapf.h>
#include <smtpf.h>
#include <eport.h> #include <eport.h>
unsigned long djb_hash(const char *s) unsigned long djb_hash(const char *s)
@ -33,8 +51,132 @@ unsigned long djb_hash(const char *s)
return hash; 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 <SMTP hostname> -s | --smtp-port <port> "
"-I | --imap-host <IMAP hostname> -i | --imap-port <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) 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; return 0;
} }

Loading…
Cancel
Save