|
|
@ -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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|