summaryrefslogtreecommitdiff
path: root/src/remoteadmin.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/remoteadmin.c')
-rw-r--r--src/remoteadmin.c375
1 files changed, 330 insertions, 45 deletions
diff --git a/src/remoteadmin.c b/src/remoteadmin.c
index 4e777c1..c2ada6e 100644
--- a/src/remoteadmin.c
+++ b/src/remoteadmin.c
@@ -18,11 +18,51 @@
*
*/
+#include <config.h>
+
#include "remoteadmin.h"
static char newmessage;
static int
+parse_int(unsigned char* buff, int* ret)
+{
+ int intarg, i;
+ char guard;
+ if (((i = sscanf((char*) &buff[*ret], "%d%c", &intarg, &guard)) == 2) || (i == 1)) {
+ if (i == 1) {
+ guard = ' ';
+ }
+ if (!isspace(guard)) {
+ return -1;
+ }
+ guard = 0;
+ i = (*ret);
+ while (buff[i] != 0) {
+ if (guard == 0) {
+ if (isspace(buff[i])) {
+ guard = 1;
+ }
+ }
+ else {
+ if (!isspace(buff[i])) {
+ break;
+ }
+ }
+ ++i;
+ }
+ if (buff[i] == '.') {
+ ++i;
+ }
+ (*ret) = i;
+ return intarg;
+ }
+ else {
+ return -1;
+ }
+}
+
+static int
parse_cmd(unsigned char* buff, int* ret)
{
int i, j, state;
@@ -70,6 +110,12 @@ parse_cmd(unsigned char* buff, int* ret)
if (strcmp(cmd, "cshow") == 0) { return 5; }
if (strcmp(cmd, "ushow") == 0) { return 6; }
if (strcmp(cmd, "quit") == 0) { return 7; }
+ if (strcmp(cmd, "timeout") == 0) { return 8; }
+ if (strcmp(cmd, "audit") == 0) { return 9; }
+ if (strcmp(cmd, "dnslookups") == 0) { return 10; }
+ if (strcmp(cmd, "dateformat") == 0) { return 11; }
+ if (strcmp(cmd, "kuser") == 0) { return 12; }
+ if (strcmp(cmd, "kclient") == 0) { return 13; }
return 0;
}
@@ -134,12 +180,16 @@ serve_admin(ConfigurationT* config, int realm, int client, unsigned char* buff)
{
int length, n, i, j, ret;
time_t now, tmp;
+ llnodeT* llptr;
+ alnodeT* alptr;
+ char olddf[51], newdf[51];
char type = config->realmtable[realm].type | TYPE_SSL | TYPE_ZLIB;
clifd master = config->realmtable[realm].raclitable[client].cliconn;
+ olddf[50] = newdf[50] = 0;
length = buff[3];
length = length << 8;
- length += buff[4]; /* this is length of message */
+ length += buff[4]; /* this is the length of a message */
time(&now);
@@ -147,19 +197,26 @@ serve_admin(ConfigurationT* config, int realm, int client, unsigned char* buff)
case AF_RA_CMD: {
n = get_message(type, master, buff, length);
buff[n] = 0;
- aflog(2, " realm[%s]: admin: message length = %d [%s]",
+ aflog(LOG_T_MANAGE, LOG_I_INFO,
+ "realm[%s]: admin: message length = %d [%s]",
get_realmname(config, realm), n, buff);
switch (parse_cmd(buff, &ret)) {
case 1: { /* help */
add_to_message(buff, AF_VER("AFSERVER"));
add_to_message(buff, "\nValid commands are:");
- add_to_message(buff, " help display help");
- add_to_message(buff, " lcmd lists available commands");
- add_to_message(buff, " info prints info about server");
- add_to_message(buff, " rshow display realms");
- add_to_message(buff, " cshow X display clients in X realm");
- add_to_message(buff, " ushow X display users in X realm");
- add_to_message(buff, " quit quit connection");
+ add_to_message(buff, " help display help");
+ add_to_message(buff, " lcmd lists available commands");
+ add_to_message(buff, " info prints info about server");
+ add_to_message(buff, " rshow display realms");
+ add_to_message(buff, " cshow X display clients in X realm");
+ add_to_message(buff, " ushow X display users in X realm");
+ add_to_message(buff, " quit quit connection");
+ add_to_message(buff, " timeout N X set timeout value in X realm");
+ add_to_message(buff, " audit {0|1} X set audit mode in X realm");
+ add_to_message(buff, " dnslookups {0|1} X set dnslookups mode in X realm");
+ add_to_message(buff, " dateformat S set dateformat");
+ add_to_message(buff, " kuser S kick user named S");
+ add_to_message(buff, " kclient N kick client with number N");
send_adm_message(type, master, buff, AF_RA_STATUS_OK);
break;
}
@@ -171,6 +228,12 @@ serve_admin(ConfigurationT* config, int realm, int client, unsigned char* buff)
add_to_message(buff, "cshow");
add_to_message(buff, "ushow");
add_to_message(buff, "quit");
+ add_to_message(buff, "timeout");
+ add_to_message(buff, "audit");
+ add_to_message(buff, "dnslookups");
+ add_to_message(buff, "dateformat");
+ add_to_message(buff, "kuser");
+ add_to_message(buff, "kclient");
send_adm_message(type, master, buff, AF_RA_STATUS_OK);
break;
}
@@ -179,23 +242,17 @@ serve_admin(ConfigurationT* config, int realm, int client, unsigned char* buff)
add_to_message(buff, "Realms: %d", config->size);
add_to_message(buff, "Certificate: %s", config->certif);
add_to_message(buff, "Key: %s", config->keys);
- if (config->logging) {
- add_to_message(buff, "logfile: %s (verbosity:%d)",
- config->logfnam, config->logging);
- }
- else {
- add_to_message(buff, "no logfile");
- }
- if (config->socklogging) {
- add_to_message(buff, "logsocket: %s (verbosity:%d)",
- config->logsport, config->socklogging);
- }
- else {
- add_to_message(buff, "no logsocket");
+ llptr = getloglisthead();
+ i = 0;
+ while (llptr) {
+ add_to_message(buff, "log[%d]: %s", i, llptr->cmdline);
+ llptr = llptr->next;
+ ++i;
}
tmp = now - config->starttime;
add_uptime_to_message(buff, "Uptime", tmp);
add_to_message(buff, "Cg: %ld B", getcg());
+ add_to_message(buff, "Dateformat: %s", getdateformat());
send_adm_message(type, master, buff, AF_RA_STATUS_OK);
break;
}
@@ -219,13 +276,30 @@ serve_admin(ConfigurationT* config, int realm, int client, unsigned char* buff)
config->realmtable[i].usrclitable[j].manportnum);
}
add_to_message(buff, "climode: %s", config->realmtable[i].clim);
- add_to_message(buff, "timeout: %s", config->realmtable[i].timeout);
+ add_to_message(buff, "timeout: %d", config->realmtable[i].tmout);
add_to_message(buff, "baseport: %s", config->realmtable[i].baseport ?
"yes" : "no");
+ add_to_message(buff, "audit: %s", config->realmtable[i].audit ?
+ "yes" : "no");
+ add_to_message(buff, "dnslookups: %s", config->realmtable[i].dnslookups ?
+ "yes" : "no");
add_to_message(buff, "ssl: %s, zlib: %s, mode: %s",
(TYPE_IS_SSL(config->realmtable[i].type))?"yes":"no",
(TYPE_IS_ZLIB(config->realmtable[i].type))?"yes":"no",
(TYPE_IS_TCP(config->realmtable[i].type))?"tcp":"udp");
+ switch (config->realmtable[i].tunneltype) {
+ case 0: {
+ add_to_message(buff, "tunneltype: direct");
+ break;
+ }
+ case 1: {
+ add_to_message(buff, "tunneltype: http proxy");
+ break;
+ }
+ default: {
+ add_to_message(buff, "tunneltype: UNKNOWN");
+ }
+ }
}
send_adm_message(type, master, buff, AF_RA_STATUS_OK);
break;
@@ -264,15 +338,45 @@ serve_admin(ConfigurationT* config, int realm, int client, unsigned char* buff)
add_to_message(buff, "Id: %s",
(config->realmtable[n].clitable[i].clientid == NULL)?"":
config->realmtable[n].clitable[i].clientid);
+ add_to_message(buff, "Number: %d",
+ config->realmtable[n].clitable[i].clientnum);
add_to_message(buff, "IP: %s, port: %s",
config->realmtable[n].clitable[i].namebuf,
config->realmtable[n].clitable[i].portbuf);
+ switch (config->realmtable[n].clitable[i].tunneltype) {
+ case 0: {
+ add_to_message(buff, "tunneltype: direct");
+ break;
+ }
+ case 1: {
+ add_to_message(buff, "tunneltype: http proxy");
+ break;
+ }
+ default: {
+ add_to_message(buff, "tunneltype: UNKNOWN");
+ }
+ }
+ if (config->realmtable[n].audit) {
+ add_to_message(buff, "auditlog:");
+ alptr = config->realmtable[n].clitable[i].head;
+ while (alptr) {
+ add_to_message(buff,
+ "userid: %d ip: %s port: %s connected: %s duration: %s",
+ alptr->userid,
+ alptr->namebuf,
+ alptr->portbuf,
+ localdate(&(alptr->connecttime)),
+ timeperiod(alptr->duration));
+ alptr = alptr->next;
+ }
+ }
}
}
send_adm_message(type, master, buff, AF_RA_STATUS_OK);
break;
}
add_to_message(buff, "Wrong realm name");
+ add_to_message(buff, "Usage: cshow X , X - realm name");
send_adm_message(type, master, buff, AF_RA_FAILED);
break;
}
@@ -318,18 +422,179 @@ serve_admin(ConfigurationT* config, int realm, int client, unsigned char* buff)
break;
}
add_to_message(buff, "Wrong realm name");
+ add_to_message(buff, "Usage: ushow X , X - realm name");
send_adm_message(type, master, buff, AF_RA_FAILED);
break;
}
case 7: { /* quit */
- aflog(1, " realm[%s]: Client[%s] (ra): commfd: CLOSED",
+ aflog(LOG_T_MANAGE, LOG_I_INFO,
+ "realm[%s]: Client[%s] (ra): commfd: CLOSED",
get_realmname(config, realm),
get_raclientname(&(config->realmtable[realm]), client));
send_adm_message(type, master, buff, AF_RA_KICKED);
return 1;
}
+ case 8: { /* timeout */
+ i = parse_int(buff, &ret);
+ if (i <= 0) {
+ add_to_message(buff, "Invalid timeout value");
+ add_to_message(buff,
+ "Usage: timeout N X , N - new timeout value, X - realm name");
+ send_adm_message(type, master, buff, AF_RA_FAILED);
+ break;
+ }
+ n = get_realmnumber(config, (char*) &buff[ret]);
+ if ((n >= 0) && (n < config->size)) {
+ add_to_message(buff, "changed timeout: %d --> %d",
+ config->realmtable[n].tmout, i);
+ config->realmtable[n].tmout = i;
+ send_adm_message(type, master, buff, AF_RA_STATUS_OK);
+ break;
+ }
+ add_to_message(buff, "Wrong realm name");
+ add_to_message(buff,
+ "Usage: timeout N X , N - new timeout value, X - realm name");
+ send_adm_message(type, master, buff, AF_RA_FAILED);
+ break;
+ }
+ case 9: { /* audit */
+ i = parse_int(buff, &ret);
+ if ((i != 0) && (i != 1)) {
+ add_to_message(buff, "Invalid audit value");
+ add_to_message(buff,
+ "Usage: audit {0|1} X , N=0 off, N=1 on, X - realm name");
+ send_adm_message(type, master, buff, AF_RA_FAILED);
+ break;
+ }
+ n = get_realmnumber(config, (char*) &buff[ret]);
+ if ((n >= 0) && (n < config->size)) {
+ add_to_message(buff, "changed audit: %s --> %s",
+ config->realmtable[n].audit ? "yes" : "no", i ? "yes" : "no");
+ config->realmtable[n].audit = i;
+ if (i == 0) {
+ for (i = 0; i < config->realmtable[n].clinum; ++i) {
+ freeauditlist(&(config->realmtable[n].clitable[i].head));
+ }
+ }
+ send_adm_message(type, master, buff, AF_RA_STATUS_OK);
+ break;
+ }
+ add_to_message(buff, "Wrong realm name");
+ add_to_message(buff,
+ "Usage: audit {0|1} X , N=0 off, N=1 on, X - realm name");
+ send_adm_message(type, master, buff, AF_RA_FAILED);
+ break;
+ }
+ case 10: { /* dnslookups */
+ i = parse_int(buff, &ret);
+ if ((i != 0) && (i != 1)) {
+ add_to_message(buff, "Invalid dnslookups value");
+ add_to_message(buff,
+ "Usage: dnslookups {0|1} X , N=0 off, N=1 on, X - realm name");
+ send_adm_message(type, master, buff, AF_RA_FAILED);
+ break;
+ }
+ n = get_realmnumber(config, (char*) &buff[ret]);
+ if ((n >= 0) && (n < config->size)) {
+ add_to_message(buff, "changed dnslookups: %s --> %s",
+ config->realmtable[n].dnslookups ? "yes" : "no", i ? "yes" : "no");
+ config->realmtable[n].dnslookups = i;
+ send_adm_message(type, master, buff, AF_RA_STATUS_OK);
+ break;
+ }
+ add_to_message(buff, "Wrong realm name");
+ add_to_message(buff,
+ "Usage: dnslookups {0|1} X , N=0 off, N=1 on, X - realm name");
+ send_adm_message(type, master, buff, AF_RA_FAILED);
+ break;
+ }
+ case 11: { /* dateformat */
+ strncpy(olddf, getdateformat(), 50);
+ strncpy(newdf, (char*) &buff[ret], 50);
+ add_to_message(buff, "changed dateformat: %s --> %s",
+ olddf, newdf);
+ setdateformat(newdf);
+ send_adm_message(type, master, buff, AF_RA_STATUS_OK);
+ break;
+ }
+ case 12: { /* kuser */
+ i = parse_int(buff, &ret);
+ if (buff[ret] != 0) {
+ add_to_message(buff, "Invalid user name");
+ add_to_message(buff,
+ "Usage: kuser S , S - user name");
+ send_adm_message(type, master, buff, AF_RA_FAILED);
+ break;
+ }
+ j = -1;
+ for (n = 0; n < config->size; ++n) {
+ j = get_usernumber(&(config->realmtable[n]), i);
+ if (j != (-1)) {
+ if ((config->realmtable[n].contable[j].state == S_STATE_OPEN) ||
+ (config->realmtable[n].contable[j].state == S_STATE_STOPPED)) {
+ add_to_message(buff, "kicked: realm[%s] user[%d]",
+ get_realmname(config, n), get_username(&(config->realmtable[n]), i));
+ close(config->realmtable[n].contable[j].connfd);
+ send_adm_message(type, master, buff, AF_RA_STATUS_OK);
+ }
+ else {
+ add_to_message(buff, "Invalid user");
+ add_to_message(buff,
+ "Usage: kuser S , S - user name");
+ send_adm_message(type, master, buff, AF_RA_FAILED);
+ }
+ break;
+ }
+ }
+ if (j == (-1)) {
+ add_to_message(buff, "Invalid user name");
+ add_to_message(buff,
+ "Usage: kuser S , S - user name");
+ send_adm_message(type, master, buff, AF_RA_FAILED);
+ }
+ break;
+ }
+ case 13: { /* kclient */
+ i = parse_int(buff, &ret);
+ if (buff[ret] != 0) {
+ add_to_message(buff, "Invalid client number");
+ add_to_message(buff,
+ "Usage: kclient N , N - client number");
+ send_adm_message(type, master, buff, AF_RA_FAILED);
+ break;
+ }
+ j = -1;
+ for (n = 0; n < config->size; ++n) {
+ j = get_clientnumber(&(config->realmtable[n]), i);
+ if (j != (-1)) {
+ if (config->realmtable[n].clitable[j].ready) {
+ add_to_message(buff, "kicked: realm[%s] client[%s]",
+ get_realmname(config, n),
+ get_clientname(&(config->realmtable[n]), j));
+ send_adm_message(type, master, buff, AF_RA_STATUS_OK);
+ return (i+2);
+ }
+ else {
+ add_to_message(buff, "Invalid client");
+ add_to_message(buff,
+ "Usage: kclient N , N - client number");
+ send_adm_message(type, master, buff, AF_RA_FAILED);
+ }
+ break;
+ }
+ }
+ if (j == (-1)) {
+ add_to_message(buff, "Invalid client number");
+ add_to_message(buff,
+ "Usage: kclient N , N - client number");
+ send_adm_message(type, master, buff, AF_RA_FAILED);
+ }
+ break;
+
+ }
default: {
- aflog(2, " realm[%s]: admin: cmd ignored", get_realmname(config, realm));
+ aflog(LOG_T_MANAGE, LOG_I_WARNING,
+ "realm[%s]: admin: cmd ignored", get_realmname(config, realm));
send_adm_message(type, master, buff, AF_RA_UNDEFINED);
}
}
@@ -339,7 +604,8 @@ serve_admin(ConfigurationT* config, int realm, int client, unsigned char* buff)
break;
}
default: {
- aflog(1, "Unrecognized message from remote admin --> closing");
+ aflog(LOG_T_MANAGE, LOG_I_ERR,
+ "Unrecognized message from remote admin --> closing");
return 1;
}
}
@@ -359,24 +625,29 @@ client_admin(char type, clifd master, unsigned char* buff, int connectfd, char*
get_message(type, master, buff, -5);
if ( buff[0] == 0 ) {
- aflog(0, "Wrong password");
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Wrong password");
return 1;
}
if ( buff[0] == AF_S_CANT_OPEN ) {
- aflog(0, "Server is full");
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Server is full");
return 1;
}
if ( buff[0] != AF_S_ADMIN_LOGIN ) {
- aflog(0, "Incompatible server type or server full");
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Incompatible server type or server full");
return 1;
}
- aflog(1, "CLIENT STARTED mode: remote administration");
+ aflog(LOG_T_MAIN, LOG_I_INFO,
+ "CLIENT STARTED mode: remote administration");
if (connectfd > 0) {
outfp = fdopen(connectfd, "w");
if (outfp == NULL) {
- aflog(0, "Error in opening file descriptor for writing");
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Error in opening file descriptor for writing");
return 1;
}
infd = connectfd;
@@ -387,7 +658,8 @@ client_admin(char type, clifd master, unsigned char* buff, int connectfd, char*
}
infp = fdopen(infd, "r");
if (infp == NULL) {
- aflog(0, "Error in opening file descriptor for reading");
+ aflog(LOG_T_INIT, LOG_I_CRIT,
+ "Error in opening file descriptor for reading");
return 1;
}
@@ -414,7 +686,8 @@ client_admin(char type, clifd master, unsigned char* buff, int connectfd, char*
buff[3] = n >> 8; /* high bits of message length */
buff[4] = n; /* low bits of message length */
send_message(type, master, buff, n+5);
- aflog(1, "ID SENT: %s", id);
+ aflog(LOG_T_MANAGE, LOG_I_INFO,
+ "ID SENT: %s", id);
}
while (1) {
@@ -422,10 +695,12 @@ client_admin(char type, clifd master, unsigned char* buff, int connectfd, char*
select(maxfdp1, &rset, NULL, NULL, NULL);
if (FD_ISSET(master.commfd, &rset)) {
- aflog(3, " masterfd: FD_ISSET");
+ aflog(LOG_T_MANAGE, LOG_I_DEBUG,
+ "masterfd: FD_ISSET");
n = get_message(type, master, buff, 5);
if (n != 5) {
- aflog(2, " FATAL ERROR! (%d)", n);
+ aflog(LOG_T_MANAGE, LOG_I_ERR,
+ "FATAL ERROR! (%d)", n);
if (n == -1) {
if (TYPE_IS_SSL(type)) {
get_ssl_error(&master, "FE", n);
@@ -436,15 +711,18 @@ client_admin(char type, clifd master, unsigned char* buff, int connectfd, char*
return 1;
}
if (n == 0) { /* server quits -> we do the same... */
- aflog(0, " SERVER: premature quit --> exiting...");
+ aflog(LOG_T_MANAGE, LOG_I_CRIT,
+ "SERVER: premature quit --> exiting...");
return 1;
}
if (buff[0] == AF_S_CLOSING) {
- aflog(0, " SERVER: CLOSED -> exiting... cg: %ld bytes", getcg());
+ aflog(LOG_T_MANAGE, LOG_I_CRIT,
+ "SERVER: CLOSED -> exiting... cg: %ld bytes", getcg());
return 0;
}
if (buff[0] != AF_S_ADMIN_CMD) {
- aflog(0, " SERVER: wrong message --> exiting");
+ aflog(LOG_T_MANAGE, LOG_I_CRIT,
+ "SERVER: wrong message --> exiting");
return 1;
}
length = buff[3];
@@ -453,16 +731,19 @@ client_admin(char type, clifd master, unsigned char* buff, int connectfd, char*
switch (buff[1]) {
case AF_RA_STATUS_OK: {
- aflog(1, " SERVER: cmd successful");
+ aflog(LOG_T_MANAGE, LOG_I_INFO,
+ "SERVER: cmd successful");
}
case AF_RA_FAILED: {
if (buff[1] == AF_RA_FAILED) {
- aflog(1, " SERVER: cmd failed");
+ aflog(LOG_T_MANAGE, LOG_I_INFO,
+ "SERVER: cmd failed");
}
}
case AF_RA_UNDEFINED: {
if (buff[1] == AF_RA_UNDEFINED) {
- aflog(1, " SERVER: unknown cmd");
+ aflog(LOG_T_MANAGE, LOG_I_WARNING,
+ "SERVER: unknown cmd");
}
n = get_message(type, master, buff, length);
buff[n] = 0;
@@ -471,21 +752,25 @@ client_admin(char type, clifd master, unsigned char* buff, int connectfd, char*
break;
}
case AF_RA_KICKED: {
- aflog(0, " SERVER: kicked us -> exiting... cg: %ld bytes", getcg());
+ aflog(LOG_T_MANAGE, LOG_I_ERR,
+ "SERVER: kicked us -> exiting... cg: %ld bytes", getcg());
return 1;
break;
}
default: {
- aflog(0, " SERVER: unrecognized message -> exiting... cg: %ld bytes", getcg());
+ aflog(LOG_T_MANAGE, LOG_I_ERR,
+ "SERVER: unrecognized message -> exiting... cg: %ld bytes", getcg());
return 1;
}
}
}
if (FD_ISSET(infd, &rset)) {
- aflog(3, " infd: FD_ISSET");
+ aflog(LOG_T_MANAGE, LOG_I_DEBUG,
+ "infd: FD_ISSET");
if (fgets((char*) &buff[5], 8091, infp) == NULL) { /* client quits --> exiting */
- aflog(0, " CLIENT CLOSED cg: %ld bytes", getcg());
+ aflog(LOG_T_MANAGE, LOG_I_NOTICE,
+ "CLIENT CLOSED cg: %ld bytes", getcg());
return 0;
}
n = strlen((char*) &buff[5]);