/*
* vQadmin Virtual Administration Interface
* Copyright (C) 2000-2002 Inter7 Internet Technologies, Inc.
*
* This program 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 program 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* vol@inter7.com
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "global.h"
struct var_t {
char *name,
*data;
struct var_t *next;
};
struct env_t {
char *name,
*data;
struct env_t *next;
};
extern char **environ;
extern char vqa_user[],
vqa_group[];
unsigned int content_length = 0;
char *gdata = NULL;
struct var_t *varlist = NULL;
struct env_t *envlist = NULL;
/*
Determine what user is trying to do based on variables supplied
*/
void cgi_nav(void)
{
char *r = NULL, i = 0;
i = 0;
r = cgi_is_var("nav");
if (r) {
if (!(strcasecmp(r, "add_domain"))) {
add_domain();
} else if (!(strcasecmp(r, "del_domain"))) {
del_domain();
} else if (!(strcasecmp(r, "view_domain"))) {
view_domain();
} else if (!(strcasecmp(r, "add_user"))) {
add_user();
} else if (!(strcasecmp(r, "del_user"))) {
del_user();
} else if (!(strcasecmp(r, "view_user"))) {
view_user();
} else if (!(strcasecmp(r, "mod_user"))) {
mod_user();
} else if (!(strcasecmp(r, "show_users"))) {
show_users();
} else if (!(strcasecmp(r, "show_controls"))) {
show_controls();
} else if (!(strcasecmp(r, "mod_domain"))) {
mod_domain();
} else if (!(strcasecmp(r, "list_domains"))) {
list_domains();
} else if (!(strcasecmp(r, "add_alias_domain"))) {
add_alias_domain();
} else if (!(strcasecmp(r, "display_file"))) {
display_file();
} else if (!(strcasecmp(r, "modify_file"))) {
modify_file();
} else if (!(strcasecmp(r, "delete_file"))) {
delete_file();
}
#ifdef ENABLE_MYSQL
else if (!(strcasecmp(r, "display_add_domain"))) {
display_add_domain();
}
#endif
}
t_open(T_MAIN, 1);
}
/*
Parse out information in stdin, if any
gdata contains parsed out data, which is pointed to by
the var_t linked list.
*/
void cgi_var(void)
{
struct var_t *v = NULL, *vt = NULL;
char *h = NULL, *t = NULL, *n = NULL, *d = NULL;
cgi_parse_hex();
varlist = (struct var_t *)malloc(sizeof(struct var_t));
varlist->next = NULL;
vt = varlist;
for (n = NULL, d = NULL, h = t = gdata;;) {
if ((*h == '=') && (n == NULL)) {
*h++ = '\0';
n = t;
t = h;
} else if (((*h == '&') && (n != NULL) && (d == NULL)) ||
((!(*h)) && (n != NULL) && (d == NULL))) {
if (*h) *h++ = '\0';
else h = NULL;
d = t;
t = h;
v = (struct var_t *)malloc(sizeof(struct var_t));
if (v == NULL) global_error("Out of memory", 1, 0);
v->name = n;
v->data = d;
v->next = NULL;
vt->next = v;
vt = v;
n = d = NULL;
if (h == NULL) break;
} else {
h++;
}
}
}
/*
Convert all hex codes in content to ascii
*/
void cgi_parse_hex(void)
{
unsigned int len = 0;
unsigned char r = 0;
char *p = NULL;
len = content_length;
for (p = gdata; *p; p++) {
len--;
if (*p == '%') {
if ((*(p + 1)) && (*(p + 2))) {
r = hex2asc(*(p + 1), *(p + 2));
*p = r;
memcpy((char *)(p + 1), (char *)(p + 3), (len - 2));
*(p + len - 1) = '\0';
}
}
}
}
/*
Fetch HTTP environment variables
*/
void cgi_env(void)
{
int i = 0;
struct env_t *et = NULL, *e = NULL;
char *t = NULL, *n = NULL, *v = NULL;
int elen = 0, nlen = 0, vlen = 0;
envlist = (struct env_t *)malloc(sizeof(struct env_t));
if (envlist == NULL) global_error("Out of memory", 1, 0);
envlist->next = NULL;
et = envlist;
for (i = 0; environ[i]; i++) {
for (t = environ[i]; *t != '='; t++);
elen = strlen(environ[i]);
nlen = (elen - strlen(t));
vlen = (elen - nlen);
e = (struct env_t *)malloc(sizeof(struct env_t));
if (e == NULL) global_error("Out of memory", 1, 0);
n = (char *)malloc(nlen + 1);
if (n == NULL) global_error("Out of memory", 1, 0);
v = (char *)malloc(vlen + 1);
if (v == NULL) global_error("Out of memory", 1, 0);
e->name = n;
e->data = v;
e->next = NULL;
memset(n, 0, (nlen + 1));
memset(v, 0, (vlen + 1));
memcpy(n, environ[i], nlen);
memcpy(v, (++t), vlen);
et->next = e;
et = e;
}
}
void cgi_init(void)
{
int val = 0;
char *env = NULL;
int ret;
cgi_env();
env = cgi_is_env("REMOTE_USER");
if (!env) {
global_error("Username unknown", 0, 1);
t_open(T_AUTH_FAILED, 1);
}
memcpy((char *)vqa_user, (char *)env, MAX_GLOBAL_LENGTH);
acl_init();
env = cgi_is_env("REQUEST_METHOD");
if (env == NULL) global_error("Unknown request method", 1, 0);
if (strcasecmp(env, "POST")==0) {
env = cgi_is_env("CONTENT_LENGTH");
if (env == NULL) global_error("Unknown content", 1, 0);
val = atoi(env);
if (val < 1) global_error("Invalid content length", 1, 0);
if (val > MAX_CONTENT_LENGTH) val = (MAX_CONTENT_LENGTH - 1);
content_length = val;
gdata = malloc(content_length + 1);
if (gdata == NULL) global_error("Out of memory", 1, 0);
memset((unsigned char *)gdata, 0, (content_length + 1));
ret = read(0, (unsigned char *)gdata, content_length);
if (ret != content_length) global_error("Invalid content length", 1, 0);
cgi_var();
} else if (strcasecmp(env, "GET") == 0 ) {
env = getenv("QUERY_STRING");
if (env == NULL) global_error("No Query String", 1, 0);
content_length = strlen(env);
gdata = env;
cgi_var();
/*t_open(T_MAIN);*/
} else {
global_error("Unsupported request method", 1, 0);
t_open(T_MAIN, 1);
}
}
char *cgi_is_env(char *name)
{
struct env_t *e = NULL;
for (e = envlist; e->next; e = e->next) {
if (!(strcmp(e->next->name, name))) return e->next->data;
}
return NULL;
}
char *cgi_is_var(char *name)
{
struct var_t *v = NULL;
for (v = varlist; v->next; v = v->next) {
if (!(strcmp(v->next->name, name))) return v->next->data;
}
return NULL;
}
char matoh(char x)
{
char ret = 0;
switch(x) {
case '0':
ret = 0;
break;
case '1':
ret = 1;
break;
case '2':
ret = 2;
break;
case '3':
ret = 3;
break;
case '4':
ret = 4;
break;
case '5':
ret = 5;
break;
case '6':
ret = 6;
break;
case '7':
ret = 7;
break;
case '8':
ret = 8;
break;
case '9':
ret = 9;
break;
case 'A':
ret = 10;
break;
case 'B':
ret = 11;
break;
case 'C':
ret = 12;
break;
case 'D':
ret = 13;
break;
case 'E':
ret = 14;
break;
case 'F':
ret = 15;
break;
default:
ret = -1;
break;
}
return ret;
}
unsigned char hex2asc(char s, char f)
{
char ret = 0;
unsigned char val1 = 0, val2 = 0, val3 = 0;
ret = matoh(f);
if (ret == -1) return 0;
val1 = ret;
ret = matoh(s);
if (ret == -1) return 0;
val2 = ret;
val3 = val1 + (val2 * 15) + val2;
return val3;
}
syntax highlighted by Code2HTML, v. 0.9.1