|
|
- /**
- * @PROJECT Session Manager
- * @COPYRIGHT See COPYING in the top level directory
- * @FILE sessmgr.h
- * @PURPOSE WebUI session manager
- * @DEVELOPERS Eric Bishop <eric@gargoyle-router.com>
- * Rafal Kupiec <belliash@asiotec.eu.org>
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include <stdarg.h>
- #include <time.h>
- #include <pwd.h>
- #ifdef USE_SHADOW
- #include <shadow.h>
- #endif
-
- #include "sessmgr.h"
- #include "sha256.h"
-
-
- char* get_admin_hash(const char* username) {
- char* admin_hash = NULL;
-
- if(username) {
- #ifdef USE_SHADOW
- struct spwd* pw;
- if((pw = getspnam(username)) != NULL) {
- admin_hash = strdup(pw->sp_pwdp);
- }
- #else
- struct passwd* pw;
- if((pw = getpwnam(username)) != NULL) {
- admin_hash = strdup(pw->pw_passwd);
- }
- #endif
- }
- return admin_hash;
- }
-
- char* get_cookie_time(time_t t) {
- struct tm* utc = gmtime(&t);
- char wday[4];
- char month[4];
- switch(utc->tm_wday) {
- case 0:
- sprintf(wday, "Sun");
- break;
- case 1:
- sprintf(wday, "Mon");
- break;
- case 2:
- sprintf(wday, "Tue");
- break;
- case 3:
- sprintf(wday, "Wed");
- break;
- case 4:
- sprintf(wday, "Thu");
- break;
- case 5:
- sprintf(wday, "Fri");
- break;
- case 6:
- sprintf(wday, "Sat");
- break;
- }
- switch(utc->tm_mon) {
- case 0:
- sprintf(month, "Jan");
- break;
- case 1:
- sprintf(month, "Feb");
- break;
- case 2:
- sprintf(month, "Mar");
- break;
- case 3:
- sprintf(month, "Apr");
- break;
- case 4:
- sprintf(month, "May");
- break;
- case 5:
- sprintf(month, "Jun");
- break;
- case 6:
- sprintf(month, "Jul");
- break;
- case 7:
- sprintf(month, "Aug");
- break;
- case 8:
- sprintf(month, "Sep");
- break;
- case 9:
- sprintf(month, "Oct");
- break;
- case 10:
- sprintf(month, "Nov");
- break;
- case 11:
- sprintf(month, "Dec");
- break;
- }
- char utc_str[200];
- sprintf(utc_str, "%s, %d %s %d %02d:%02d:%02d UTC", wday, utc->tm_mday, month, (utc->tm_year + 1900), utc->tm_hour, utc->tm_min, utc->tm_sec);
- return safe_strdup(utc_str);
- }
-
- int main(int argc, char **argv) {
- char *password = NULL;
- char *username = NULL;
- char *cookie_hash = NULL;
- char *cookie_exp = NULL;
- char *user_agent = NULL;
- char *src_ip = NULL;
- char *redirect = NULL;
- int timeout_minutes = DEFAULT_SESSION_TIMEOUT;
- unsigned long browser_time = 0;
- int loggedout = 0;
- int next_opt;
- int read;
-
- while((next_opt = getopt(argc, argv, "p:P:u:U:c:C:e:E:a:A:i:I:r:R:t:T:b:B:lL")) != -1) {
- switch(next_opt) {
- case 'p':
- case 'P':
- password = safe_strdup(optarg);
- break;
- case 'u':
- case 'U':
- username = safe_strdup(optarg);
- break;
- case 'c':
- case 'C':
- cookie_hash = safe_strdup(optarg);
- break;
- case 'e':
- case 'E':
- cookie_exp = safe_strdup(optarg);
- break;
- case 'a':
- case 'A':
- user_agent = safe_strdup(optarg);
- break;
- case 'i':
- case 'I':
- src_ip = safe_strdup(optarg);
- break;
- case 'r':
- case 'R':
- redirect = safe_strdup(optarg);
- break;
- case 't':
- case 'T':
- read = sscanf(optarg, "%d", &timeout_minutes);
- if(read > 0) {
- timeout_minutes = timeout_minutes > 0 ? timeout_minutes : DEFAULT_SESSION_TIMEOUT;
- } else {
- timeout_minutes = DEFAULT_SESSION_TIMEOUT;
- }
- timeout_minutes *= 60;
- break;
- case 'b':
- case 'B':
- read = sscanf(optarg, "%ld", &browser_time);
- browser_time = read > 0 ? browser_time : 0;
- break;
- case 'l':
- case 'L':
- loggedout = 1;
- break;
- }
- }
-
- int expired = 0;
- int valid = 0;
- char* admin_hash = get_admin_hash(username);
- if(loggedout == 1) {
- printf("echo \"Set-Cookie:kagera_sid=loggedout;\"; echo \"Set-Cookie:kagera_usr=loggedout;\"; ");
- } else if(admin_hash != NULL) {
- time_t now;
- time(&now);
- if(password != NULL) {
- valid = strcmp(crypt(password, admin_hash), admin_hash) == 0 ? 1 : 0;
- if(valid) {
- printf("logger -t webui \"Kagera Administration Interface authorization succeeded from ${REMOTE_ADDR}\"; ");
- }
- } else if(cookie_hash != NULL && cookie_exp != NULL && user_agent != NULL && src_ip != NULL) {
- time_t exp_time;
- int read = sscanf(cookie_exp, "%ld", &exp_time);
- if(read > 0) {
- expired = 1;
- if(exp_time > now && (exp_time - (timeout_minutes) - 2) <= now) {
- expired = 0;
- }
- }
- char *combined = safe_strcat(4, admin_hash, cookie_exp, user_agent, src_ip);
- char* hashed = get_sha256_hash_hex_str(combined);
- if(strcmp(hashed, cookie_hash) == 0) {
- if(expired == 0 && read > 0) {
- valid = 1;
- }
- } else {
- expired = 0;
- }
- free(hashed);
- free(combined);
- }
- if(valid == 1 && src_ip != NULL && user_agent != NULL) {
- char* new_hash;
- char* combined;
- char new_exp[100] = "";
- time_t new_exp_t = now + (timeout_minutes);
- sprintf(new_exp, "%ld", new_exp_t);
- char* cookie_exp;
- if(browser_time > 0 && ((browser_time - now) < (-5*60) || (browser_time - now) > (5*60))) {
- time_t cookie_exp_t = browser_time+(timeout_minutes);
- cookie_exp = get_cookie_time(cookie_exp_t);
- } else {
- cookie_exp = get_cookie_time(new_exp_t);
- }
- combined = safe_strcat(4, admin_hash, new_exp, user_agent, src_ip);
- new_hash = get_sha256_hash_hex_str(combined);
- if(browser_time == 0) {
- printf("echo \"Set-Cookie:kagera_sid=%s; Path=/;\"; echo \"Set-Cookie:kagera_usr=%s; Path=/;\"; echo \"Set-Cookie:kagera_exp=%s; Path=/;\"; ", new_hash, username, new_exp);
- } else {
- printf("echo \"Set-Cookie:kagera_sid=%s; Expires=%s; Path=/;\"; echo \"Set-Cookie:kagera_usr=%s; Expires=%s; Path=/;\"; echo \"Set-Cookie:kagera_exp=%s; Expires=%s; Path=/;\"; ", new_hash, cookie_exp, username, cookie_exp, new_exp, cookie_exp);
- }
- free(new_hash);
- free(combined);
- free(cookie_exp);
- printf("VALIDSESS=1\n");
- }
- free(admin_hash);
- }
- if(redirect != NULL) {
- char str[20] = "";
- if(expired == 1) {
- sprintf(str, "&expired=1");
- } else if(loggedout == 1) {
- sprintf(str, "&loggedout=1");
- }
- printf("echo \"HTTP/1.1 301 Moved Permanently;\"; echo \"Location: %s%s\"; exit", redirect, str);
- }
- return 0;
- }
-
- void* safe_malloc(size_t size) {
- void* val = malloc(size);
- if(val == NULL) {
- fprintf(stderr, "ERROR: MALLOC FAILURE!\n");
- exit(1);
- }
- return val;
- }
-
- char* safe_strcat(int num_strs, ...) {
- va_list strs;
- int new_length = 0;
- int i;
- int next_start;
- char* new_str;
-
- va_start(strs, num_strs);
- for(i=0; i < num_strs; i++) {
- char* next_arg = va_arg(strs, char*);
- if(next_arg != NULL) {
- new_length = new_length + strlen(next_arg);
- }
- }
- va_end(strs);
- new_str = safe_malloc((1 + new_length) * sizeof(char));
- va_start(strs, num_strs);
- next_start = 0;
- for(i=0; i < num_strs; i++) {
- char* next_arg = va_arg(strs, char*);
- if(next_arg != NULL) {
- int next_length = strlen(next_arg);
- memcpy(new_str+next_start,next_arg, next_length);
- next_start = next_start+next_length;
- }
- }
- new_str[next_start] = '\0';
- return new_str;
- }
-
- char* safe_strdup(const char* str) {
- char* new_str = NULL;
- if(str != NULL) {
- new_str = strdup(str);
- if(new_str == NULL) {
- fprintf(stderr, "ERROR: MALLOC FAILURE!\n");
- exit(1);
- }
- }
- return new_str;
- }
|