Compare commits
10 Commits
1aff05ea29
...
923a4aaf6f
Author | SHA1 | Date | |
---|---|---|---|
|
923a4aaf6f | ||
|
b833c9891e | ||
|
1facc7f484 | ||
|
cbfc031438 | ||
591ee61a6f | |||
51e43425ce | |||
c0f4b10721 | |||
d737e5f836 | |||
109d071fed | |||
5e009b70d3 |
1
src/.gitignore
vendored
1
src/.gitignore
vendored
@ -2,3 +2,4 @@ ejabberdauth
|
||||
.deps
|
||||
testimap
|
||||
testsmtp
|
||||
testeport
|
||||
|
@ -10,7 +10,7 @@ AM_CPPFLAGS = \
|
||||
AM_CFLAGS = -Wall -g
|
||||
|
||||
if BUILD_TESTS
|
||||
bin_PROGRAMS = ejabberdauth testimap testsmtp
|
||||
bin_PROGRAMS = ejabberdauth testimap testsmtp testeport
|
||||
else
|
||||
bin_PROGRAMS = ejabberdauth
|
||||
endif
|
||||
@ -27,5 +27,9 @@ testimap_LDADD = $(LIBS) $(OPENSSL_LIBS)
|
||||
testsmtp_SOURCES = tls.c smtp.c tests/misc.c tests/testsmtp.c
|
||||
|
||||
testsmtp_LDADD = $(LIBS) $(OPENSSL_LIBS)
|
||||
|
||||
testeport_SOURCES = eport.c tests/misc.c tests/testeport.c
|
||||
|
||||
testeport_LDADD = $(LIBS)
|
||||
endif
|
||||
|
||||
|
@ -55,7 +55,7 @@ ssize_t eport_read(FILE *stream, char *buffer, size_t buffer_size)
|
||||
ssize_t eport_write(FILE *stream, char *buffer, size_t buffer_size)
|
||||
{
|
||||
int fd = fileno(stream);
|
||||
int16_t port_msg_len = (buffer_size << 8) | ((buffer_size >> 8) & 0xFF);
|
||||
int16_t port_msg_len = ((int16_t)buffer_size << 8) | (((int16_t)buffer_size >> 8) & 0xFF);
|
||||
ssize_t wr = 0;
|
||||
struct iovec msg[2];
|
||||
|
||||
@ -90,7 +90,7 @@ int eport_ejabberd_msgread(char *buffer, size_t buffer_size,
|
||||
if(!m) goto ieinval;
|
||||
|
||||
/* calc hash for first message word till the end or till the ':' */
|
||||
while(((c = *buffer++) != '\0') || (*buffer == ':'))
|
||||
while(((c = *buffer++) != '\0') && (c != ':'))
|
||||
hash = ((hash << 5) + hash) + c;
|
||||
|
||||
switch(hash) {
|
||||
@ -108,7 +108,7 @@ int eport_ejabberd_msgread(char *buffer, size_t buffer_size,
|
||||
m->msg_data = orig_buffer;
|
||||
m->user = m->domain = m->password = NULL;
|
||||
/* shift a pointer */
|
||||
c = *buffer++; orig_buffer = buffer;
|
||||
c = *buffer; orig_buffer = buffer;
|
||||
|
||||
while((buffer = strchr(buffer, ':')) != NULL) {
|
||||
switch(t) {
|
||||
|
20
src/imap.c
20
src/imap.c
@ -42,15 +42,15 @@ int imap_auth(struct tlsport *p, struct ejabber_msg *m)
|
||||
int len = 0, mlen = 0;
|
||||
|
||||
/* sanity check */
|
||||
if(!m || !m->user) return -1;
|
||||
if(!m->domain || !m->password) return -1;
|
||||
if(!p || !p->ssl) return -1;
|
||||
if(!m || !m->user) return 0;
|
||||
if(!m->domain || !m->password) return 0;
|
||||
if(!p || !p->ssl) return 0;
|
||||
|
||||
/* read welcome message */
|
||||
memset(buf, '\0', IMAPLINE_LENGTH);
|
||||
len = tls_io(p, buf, IMAPLINE_LENGTH - sizeof(char), TLSIO_READ);
|
||||
if(len < 5) return -1;
|
||||
else if(strncmp(buf, "* OK", 4)) return -1;
|
||||
if(len < 5) return 0;
|
||||
else if(strncmp(buf, "* OK", 4)) return 0;
|
||||
/* check the leftovers in TLS channel */
|
||||
if(len == IMAPLINE_LENGTH - sizeof(char)) {
|
||||
do {
|
||||
@ -62,19 +62,19 @@ int imap_auth(struct tlsport *p, struct ejabber_msg *m)
|
||||
/* try to login with provided credentials */
|
||||
mlen = strlen(m->user) + strlen(m->domain) + strlen(m->password);
|
||||
mlen += 16; /* "a login 11 22" */
|
||||
if(mlen > IMAPLINE_LENGTH - sizeof(char)) return -1; /* too long */
|
||||
if(mlen > IMAPLINE_LENGTH - sizeof(char)) return 0; /* too long */
|
||||
/* create a message */
|
||||
snprintf(buf, mlen, "a login \"%s@%s\" \"%s\"\n", m->user, m->domain,
|
||||
m->password);
|
||||
len = tls_io(p, buf, mlen - sizeof(char), TLSIO_WRITE);
|
||||
if(len < 0) return -1;
|
||||
if(len < 0) return 0;
|
||||
else memset(buf, '\0', mlen);
|
||||
|
||||
/* read */
|
||||
len = tls_io(p, buf, IMAPLINE_LENGTH - sizeof(char), TLSIO_READ);
|
||||
if(len < 5) return -1;
|
||||
if(len < 5) return 0;
|
||||
|
||||
if(strncmp(buf, "a OK", 4)) return -1;
|
||||
if(strncmp(buf, "a OK", 4)) return 0;
|
||||
|
||||
/* check for leftovers */
|
||||
if(len == IMAPLINE_LENGTH - sizeof(char)) {
|
||||
@ -88,5 +88,5 @@ int imap_auth(struct tlsport *p, struct ejabber_msg *m)
|
||||
snprintf(buf, IMAPLINE_LENGTH - sizeof(char), "a logout");
|
||||
len = tls_io(p, buf, 9, TLSIO_WRITE);
|
||||
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
145
src/main.c
145
src/main.c
@ -19,7 +19,25 @@
|
||||
*/
|
||||
|
||||
#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>
|
||||
|
||||
unsigned long djb_hash(const char *s)
|
||||
@ -33,8 +51,135 @@ 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 <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)
|
||||
{
|
||||
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 = 0;
|
||||
} 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 = 0;
|
||||
} 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 = 0;
|
||||
break;
|
||||
case EJA_UNKNOWN:
|
||||
default: /* something goes wrong with message */
|
||||
goto abort_parsing;
|
||||
break;
|
||||
}
|
||||
|
||||
/* finally, reply ... */
|
||||
opt = ((int16_t)opt << 8) | (((int16_t)opt >> 8) & 0xff);
|
||||
eport_write(stdout, (char *)(&opt), sizeof(int16_t));
|
||||
/* clear the buffer */
|
||||
memset(msgbuf, 0, msgbuflen);
|
||||
}
|
||||
|
||||
ssllib_free();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
39
src/smtp.c
39
src/smtp.c
@ -42,62 +42,63 @@ int smtp_checkuser(struct tlsport *p, struct ejabber_msg *m, const char *host)
|
||||
int len, mlen, r;
|
||||
|
||||
/* sanity check */
|
||||
if(!m || !m->user) return -1;
|
||||
if(!m->domain || !m->password) return -1;
|
||||
if(!p || !p->ssl) return -1;
|
||||
if(!host) return -1;
|
||||
if(!m || !m->user) return 0;
|
||||
if(!m->domain || !m->password) return 0;
|
||||
if(!p || !p->ssl) return 0;
|
||||
if(!host) return 0;
|
||||
|
||||
/* clear stack buffers */
|
||||
len = mlen = r = 0;
|
||||
len = mlen = 0;
|
||||
memset(buf, 0, SMTPLINE_LENGTH);
|
||||
r = 1;
|
||||
|
||||
/* read greetings, shall be 220 for error code */
|
||||
len = tls_io(p, buf, SMTPLINE_LENGTH - sizeof(char), TLSIO_READ);
|
||||
if(len < 3) return -1;
|
||||
else if(strncmp(buf, "220", 3)) return -1;
|
||||
if(len < 3) return 0;
|
||||
else if(strncmp(buf, "220", 3)) return 0;
|
||||
memset(buf, 0, len + sizeof(char));
|
||||
|
||||
/* start with hello */
|
||||
mlen = strlen(host) + sizeof(char)*6;
|
||||
if(mlen > SMTPLINE_LENGTH - sizeof(char)) return -1; /* too long message */
|
||||
if(mlen > SMTPLINE_LENGTH - sizeof(char)) return 0; /* too long message */
|
||||
snprintf(buf, mlen + sizeof(char), "HELO %s\n", host);
|
||||
len = tls_io(p, buf, mlen, TLSIO_WRITE);
|
||||
|
||||
if(len < 0) return -1;
|
||||
if(len < 0) return 0;
|
||||
else memset(buf, 0, mlen);
|
||||
|
||||
/* check the reply if any */
|
||||
len = tls_io(p, buf, SMTPLINE_LENGTH - sizeof(char), TLSIO_READ);
|
||||
if(len < 4) return -1;
|
||||
else if(strncmp(buf, "250 ", 4)) return -1;
|
||||
if(len < 4) return 0;
|
||||
else if(strncmp(buf, "250 ", 4)) return 0;
|
||||
memset(buf, 0, len + sizeof(char));
|
||||
|
||||
/* set mail from */
|
||||
mlen = strlen(m->user) + strlen(m->domain) + 14*sizeof(char);
|
||||
if(mlen > SMTPLINE_LENGTH - sizeof(char)) return -1; /* too long message */
|
||||
if(mlen > SMTPLINE_LENGTH - sizeof(char)) return 0; /* too long message */
|
||||
snprintf(buf, mlen + sizeof(char), "mail from:<%s@%s>\n", m->user, m->domain);
|
||||
len = tls_io(p, buf, mlen, TLSIO_WRITE);
|
||||
|
||||
if(len < 0) return -1;
|
||||
if(len < 0) return 0;
|
||||
else memset(buf, 0, mlen);
|
||||
/* check the reply if any */
|
||||
len = tls_io(p, buf, SMTPLINE_LENGTH - sizeof(char), TLSIO_READ);
|
||||
if(len < 4) return -1;
|
||||
else if(strncmp(buf, "250 ", 4)) return -1;
|
||||
if(len < 4) return 0;
|
||||
else if(strncmp(buf, "250 ", 4)) return 0;
|
||||
memset(buf, 0, len + sizeof(char));
|
||||
|
||||
/* set recepient, if it's ok - user exists, if it's not - no such user */
|
||||
mlen = strlen(m->user) + strlen(m->domain) + 12*sizeof(char);
|
||||
if(mlen > SMTPLINE_LENGTH - sizeof(char)) return -1; /* too long message */
|
||||
if(mlen > SMTPLINE_LENGTH - sizeof(char)) return 0; /* too long message */
|
||||
snprintf(buf, mlen + sizeof(char), "rcpt to:<%s@%s>\n", m->user, m->domain);
|
||||
len = tls_io(p, buf, mlen, TLSIO_WRITE);
|
||||
if(len < 0) return -1;
|
||||
if(len < 0) return 0;
|
||||
else memset(buf, 0, mlen);
|
||||
|
||||
/* check the reply if any */
|
||||
len = tls_io(p, buf, SMTPLINE_LENGTH - sizeof(char), TLSIO_READ);
|
||||
if(len < 4) return -1;
|
||||
else if(strncmp(buf, "250 ", 4)) r = -1;
|
||||
if(len < 4) return 0;
|
||||
else if(strncmp(buf, "250 ", 4)) r = 0;
|
||||
|
||||
/* gracefully end smtp session */
|
||||
mlen = strlen("quit\n");
|
||||
|
277
src/tests/testeport.c
Normal file
277
src/tests/testeport.c
Normal file
@ -0,0 +1,277 @@
|
||||
/*
|
||||
* ejabberd external authentication program
|
||||
*
|
||||
* (c) Alexander Vdolainen 2013, 2018, 2019, 2021 <alex@vapaa.xyz>
|
||||
*
|
||||
* this is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published
|
||||
* by the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* this is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.";
|
||||
*
|
||||
*/
|
||||
|
||||
#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 <eport.h>
|
||||
|
||||
#define PRG_NAME "ejabberauth erlang port function test"
|
||||
|
||||
extern int ejda_username_split(char *buf, char **user, char **domain);
|
||||
|
||||
/*
|
||||
* Test is simple - create a pipe, write a message with eport interface
|
||||
* read it, reply with erport interface.
|
||||
* for supported commands replies ok, fail otherwise
|
||||
*/
|
||||
|
||||
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 -u | --user <username>"
|
||||
" -P | --password <password> [ -v | --verbose ]",
|
||||
cname);
|
||||
fprintf(stdout, "\n\n\t%s -h | --help\n", cname);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const char *tfmt[] = {
|
||||
"auth:%s:%s:%s",
|
||||
"isuser:%s:%s",
|
||||
"setpass:%s:%s:%s",
|
||||
"tryregister:%s:%s:%s",
|
||||
"removeuser:%s:%s",
|
||||
"removeuser3:%s:%s:%s",
|
||||
"weird-stuff",
|
||||
};
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *domain, *user, *password;
|
||||
char *utbuf = NULL, *msgbuf = NULL;
|
||||
int verbose = 0, opt, msgbuf_len = 0, items = 0;
|
||||
FILE *inp, *outp;
|
||||
int pfd[2];
|
||||
struct ejabber_msg m;
|
||||
|
||||
domain = user = password = NULL;
|
||||
inp = outp = NULL;
|
||||
|
||||
/* parse options */
|
||||
while(1) {
|
||||
int option_index = 0;
|
||||
static struct option long_options[] = {
|
||||
{"help", no_argument, NULL, 'h'},
|
||||
{"user", required_argument, NULL, 'u'},
|
||||
{"password", required_argument, NULL, 'P'},
|
||||
{"verbose", no_argument, NULL, 'v'},
|
||||
{NULL, 0, NULL, 0},
|
||||
};
|
||||
|
||||
if((opt = getopt_long(argc, argv, "hu:P:v", long_options,
|
||||
&option_index)) == -1) break;
|
||||
switch(opt) {
|
||||
case 'h':
|
||||
/* print help information and exit */
|
||||
print_help(argv[0]);
|
||||
return 0;
|
||||
break;
|
||||
case 'u': user = optarg; break;
|
||||
case 'P': password = optarg; break;
|
||||
case 'v': verbose = 1; break;
|
||||
default: abort(); break; /* something that's shouldn't ever happen */
|
||||
}
|
||||
}
|
||||
|
||||
if(!user) {
|
||||
fprintf(stderr, "Error: no username is given.\n");
|
||||
main_einval:
|
||||
print_help(argv[0]);
|
||||
return 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, &user, &domain)) {
|
||||
fprintf(stderr, "Error: username is invalid.\n");
|
||||
free(utbuf);
|
||||
return EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
/* allocate a message buffer */
|
||||
msgbuf_len = strlen("removeuser3") + strlen(user) + strlen(domain) +
|
||||
strlen(password) + sizeof(uint16_t) + sizeof(char)*4;
|
||||
if((msgbuf = malloc(msgbuf_len)) == NULL) {
|
||||
fprintf(stderr, "Error: not enough memory\n");
|
||||
free(utbuf);
|
||||
return ENOMEM;
|
||||
} else memset(msgbuf, 0, msgbuf_len);
|
||||
|
||||
if(pipe(pfd) == -1) {
|
||||
fprintf(stderr, "Error: cannot create pipe\n");
|
||||
opt = -1;
|
||||
goto finit0;
|
||||
} else {
|
||||
opt = -1;
|
||||
inp = fdopen(pfd[0], "r"); /* port to read from */
|
||||
outp = fdopen(pfd[1], "w"); /* port to write to */
|
||||
if(!inp || !outp) {
|
||||
fprintf(stderr, "Cannot create file stream.\n");
|
||||
goto finit1;
|
||||
} else opt = 0;
|
||||
}
|
||||
|
||||
do {
|
||||
/* do the message write */
|
||||
switch(opt) {
|
||||
case 0:
|
||||
case 2:
|
||||
case 3:
|
||||
case 5:
|
||||
snprintf(msgbuf, msgbuf_len, tfmt[opt], user, domain, password);
|
||||
break;
|
||||
case 1:
|
||||
case 4:
|
||||
snprintf(msgbuf, msgbuf_len, tfmt[opt], user, domain);
|
||||
break;
|
||||
case 6:
|
||||
snprintf(msgbuf, msgbuf_len, tfmt[opt]);
|
||||
break;
|
||||
default:
|
||||
opt = -1;
|
||||
break;
|
||||
};
|
||||
if(verbose) {
|
||||
fprintf(stdout, "Push (%s) ... ", msgbuf);
|
||||
fflush(stdout);
|
||||
}
|
||||
if(eport_write(outp, msgbuf, strlen(msgbuf)) < 0) {
|
||||
opt = -1;
|
||||
if(verbose) fprintf(stdout, "fail\n");
|
||||
else fprintf(stderr, "Error write to out port.\n");
|
||||
} else {
|
||||
if(verbose) fprintf(stdout, "ok\n");
|
||||
/* try to read */
|
||||
if(verbose) {
|
||||
fprintf(stdout, "Pull ... ");
|
||||
fflush(stdout);
|
||||
}
|
||||
if(eport_read(inp, msgbuf, msgbuf_len) < 0) {
|
||||
opt = -1;
|
||||
if(verbose) fprintf(stdout, "fail\n");
|
||||
else fprintf(stderr, "Error on reading in port.\n");
|
||||
} else if((items = eport_ejabberd_msgread(msgbuf, msgbuf_len, &m)) == -1) {
|
||||
if(verbose) fprintf(stdout, "fail on parsing\n");
|
||||
else fprintf(stderr, "Error on parsing data from in port.\n");
|
||||
opt = -1;
|
||||
}
|
||||
if(opt != -1) {
|
||||
if(verbose) {
|
||||
fprintf(stdout, "ok, has been parsed\n");
|
||||
fprintf(stdout, "Checking data ... ");
|
||||
fflush(stdout);
|
||||
}
|
||||
/* check the data first */
|
||||
switch(items) {
|
||||
case 3:
|
||||
if(strcmp(m.password, password)) {
|
||||
opt = -1;
|
||||
if(verbose) fprintf(stdout, "password data is incorrect\n");
|
||||
else fprintf(stderr, "Password data is invalid.\n");
|
||||
}
|
||||
case 2:
|
||||
if(strcmp(m.user, user)) {
|
||||
opt = -1;
|
||||
if(verbose) fprintf(stdout, "user data is incorrect\n");
|
||||
else fprintf(stderr, "User data is invalid.\n");
|
||||
}
|
||||
if(strcmp(m.domain, domain)) {
|
||||
opt = -1;
|
||||
if(verbose) fprintf(stdout, "domain data is incorrect\n");
|
||||
else fprintf(stderr, "Domain data is invalid.\n");
|
||||
}
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
if(opt != 6) opt = -1;
|
||||
break;
|
||||
}
|
||||
if(opt != -1) { /* check command */
|
||||
if(verbose) {
|
||||
fprintf(stdout, "ok\n");
|
||||
fprintf(stdout, "Check event ... ");
|
||||
fflush(stdout);
|
||||
}
|
||||
switch(opt) {
|
||||
case 0: if(m.aev != EJA_AUTH) opt = -1; break;
|
||||
case 1: if(m.aev != EJA_ISUSER) opt = -1; break;
|
||||
case 2: if(m.aev != EJA_SETPASS) opt = -1; break;
|
||||
case 3: if(m.aev != EJA_TRYREGISTER) opt = -1; break;
|
||||
case 4: if(m.aev != EJA_REMOVEUSER) opt = -1; break;
|
||||
case 5: if(m.aev != EJA_REMOVEUSER3) opt = -1; break;
|
||||
default:
|
||||
opt = -1;
|
||||
}
|
||||
if(opt == -1) {
|
||||
if(verbose) fprintf(stdout, "fail\n");
|
||||
else fprintf(stderr, "Event cmd invalid.\n");
|
||||
} else {
|
||||
if(verbose) fprintf(stdout, "ok\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
memset(msgbuf, 0, msgbuf_len);
|
||||
|
||||
if(opt != -1) opt++;
|
||||
} while((opt < 6) && (opt != -1));
|
||||
|
||||
if(opt > 0) opt = 0;
|
||||
|
||||
finit1:
|
||||
if(!inp) close(pfd[0]);
|
||||
else fclose(inp);
|
||||
if(!outp) close(pfd[1]);
|
||||
else fclose(outp);
|
||||
finit0:
|
||||
free(utbuf);
|
||||
free(msgbuf);
|
||||
|
||||
return opt;
|
||||
}
|
@ -84,7 +84,7 @@ int main(int argc, char **argv)
|
||||
{NULL, 0, NULL, 0},
|
||||
};
|
||||
|
||||
if((opt = getopt_long(argc, argv, "hH:p:u:P:e:v", long_options,
|
||||
if((opt = getopt_long(argc, argv, "hH:p:u:e:v", long_options,
|
||||
&option_index)) == -1) break;
|
||||
switch(opt) {
|
||||
case 'h':
|
||||
|
Loading…
x
Reference in New Issue
Block a user