Kagera Session Manager
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. /**
  2. * @PROJECT Session Manager
  3. * @COPYRIGHT See COPYING in the top level directory
  4. * @FILE sessmgr.h
  5. * @PURPOSE WebUI session manager
  6. * @DEVELOPERS Eric Bishop <eric@gargoyle-router.com>
  7. * Rafal Kupiec <belliash@asiotec.eu.org>
  8. */
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <unistd.h>
  13. #include <stdarg.h>
  14. #include <time.h>
  15. #include <pwd.h>
  16. #ifdef USE_SHADOW
  17. #include <shadow.h>
  18. #endif
  19. #include "sessmgr.h"
  20. #include "sha256.h"
  21. char* get_admin_hash(const char* username) {
  22. char* admin_hash = NULL;
  23. if(username) {
  24. #ifdef USE_SHADOW
  25. struct spwd* pw;
  26. if((pw = getspnam(username)) != NULL) {
  27. admin_hash = strdup(pw->sp_pwdp);
  28. }
  29. #else
  30. struct passwd* pw;
  31. if((pw = getpwnam(username)) != NULL) {
  32. admin_hash = strdup(pw->pw_passwd);
  33. }
  34. #endif
  35. }
  36. return admin_hash;
  37. }
  38. char* get_cookie_time(time_t t) {
  39. struct tm* utc = gmtime(&t);
  40. char *wdays[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
  41. char *months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
  42. char utc_str[200];
  43. sprintf(utc_str, "%s, %d %s %d %02d:%02d:%02d UTC", wdays[utc->tm_wday], utc->tm_mday, months[utc->tm_mon], (utc->tm_year + 1900), utc->tm_hour, utc->tm_min, utc->tm_sec);
  44. return safe_strdup(utc_str);
  45. }
  46. int main(int argc, char **argv) {
  47. char *password = NULL;
  48. char *username = NULL;
  49. char *cookie_hash = NULL;
  50. char *cookie_exp = NULL;
  51. char *user_agent = NULL;
  52. char *src_ip = NULL;
  53. char *redirect = NULL;
  54. int timeout_minutes = DEFAULT_SESSION_TIMEOUT;
  55. unsigned long browser_time = 0;
  56. int loggedout = 0;
  57. int next_opt;
  58. int read;
  59. 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) {
  60. switch(next_opt) {
  61. case 'p':
  62. case 'P':
  63. password = safe_strdup(optarg);
  64. break;
  65. case 'u':
  66. case 'U':
  67. username = safe_strdup(optarg);
  68. break;
  69. case 'c':
  70. case 'C':
  71. cookie_hash = safe_strdup(optarg);
  72. break;
  73. case 'e':
  74. case 'E':
  75. cookie_exp = safe_strdup(optarg);
  76. break;
  77. case 'a':
  78. case 'A':
  79. user_agent = safe_strdup(optarg);
  80. break;
  81. case 'i':
  82. case 'I':
  83. src_ip = safe_strdup(optarg);
  84. break;
  85. case 'r':
  86. case 'R':
  87. redirect = safe_strdup(optarg);
  88. break;
  89. case 't':
  90. case 'T':
  91. read = sscanf(optarg, "%d", &timeout_minutes);
  92. if(read > 0) {
  93. timeout_minutes = timeout_minutes > 0 ? timeout_minutes : DEFAULT_SESSION_TIMEOUT;
  94. } else {
  95. timeout_minutes = DEFAULT_SESSION_TIMEOUT;
  96. }
  97. timeout_minutes *= 60;
  98. break;
  99. case 'b':
  100. case 'B':
  101. read = sscanf(optarg, "%ld", &browser_time);
  102. browser_time = read > 0 ? browser_time : 0;
  103. break;
  104. case 'l':
  105. case 'L':
  106. loggedout = 1;
  107. break;
  108. }
  109. }
  110. int expired = 0;
  111. int valid = 0;
  112. char* admin_hash = get_admin_hash(username);
  113. if(loggedout == 1) {
  114. printf("echo \"Set-Cookie:kagera_sid=loggedout;\"; echo \"Set-Cookie:kagera_usr=loggedout;\"; ");
  115. } else if(admin_hash != NULL) {
  116. time_t now;
  117. time(&now);
  118. if(password != NULL) {
  119. valid = strcmp(crypt(password, admin_hash), admin_hash) == 0 ? 1 : 0;
  120. if(valid) {
  121. printf("logger -t webui \"Kagera Administration Interface authorization succeeded from ${REMOTE_ADDR}\"; ");
  122. }
  123. } else if(cookie_hash != NULL && cookie_exp != NULL && user_agent != NULL && src_ip != NULL) {
  124. time_t exp_time;
  125. int read = sscanf(cookie_exp, "%ld", &exp_time);
  126. if(read > 0) {
  127. expired = 1;
  128. if(exp_time > now && (exp_time - (timeout_minutes) - 2) <= now) {
  129. expired = 0;
  130. }
  131. }
  132. char *combined = safe_strcat(4, admin_hash, cookie_exp, user_agent, src_ip);
  133. char* hashed = get_sha256_hash_hex_str(combined);
  134. if(strcmp(hashed, cookie_hash) == 0) {
  135. if(expired == 0 && read > 0) {
  136. valid = 1;
  137. }
  138. } else {
  139. expired = 0;
  140. }
  141. free(hashed);
  142. free(combined);
  143. }
  144. if(valid == 1 && src_ip != NULL && user_agent != NULL) {
  145. char* new_hash;
  146. char* combined;
  147. char new_exp[100] = "";
  148. time_t new_exp_t = now + (timeout_minutes);
  149. sprintf(new_exp, "%ld", new_exp_t);
  150. char* cookie_exp;
  151. if(browser_time > 0 && ((browser_time - now) < (-5*60) || (browser_time - now) > (5*60))) {
  152. time_t cookie_exp_t = browser_time+(timeout_minutes);
  153. cookie_exp = get_cookie_time(cookie_exp_t);
  154. } else {
  155. cookie_exp = get_cookie_time(new_exp_t);
  156. }
  157. combined = safe_strcat(4, admin_hash, new_exp, user_agent, src_ip);
  158. new_hash = get_sha256_hash_hex_str(combined);
  159. if(browser_time == 0) {
  160. 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);
  161. } else {
  162. 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);
  163. }
  164. free(new_hash);
  165. free(combined);
  166. free(cookie_exp);
  167. printf("VALIDSESS=1\n");
  168. }
  169. free(admin_hash);
  170. }
  171. if(redirect != NULL) {
  172. char str[20] = "";
  173. if(expired == 1) {
  174. sprintf(str, "&expired=1");
  175. } else if(loggedout == 1) {
  176. sprintf(str, "&loggedout=1");
  177. }
  178. printf("echo \"HTTP/1.1 301 Moved Permanently;\"; echo \"Location: %s%s\"; exit", redirect, str);
  179. }
  180. return 0;
  181. }
  182. void* safe_malloc(size_t size) {
  183. void* val = malloc(size);
  184. if(val == NULL) {
  185. fprintf(stderr, "ERROR: MALLOC FAILURE!\n");
  186. exit(1);
  187. }
  188. return val;
  189. }
  190. char* safe_strcat(int num_strs, ...) {
  191. va_list strs;
  192. int new_length = 0;
  193. int i;
  194. int next_start;
  195. char* new_str;
  196. va_start(strs, num_strs);
  197. for(i=0; i < num_strs; i++) {
  198. char* next_arg = va_arg(strs, char*);
  199. if(next_arg != NULL) {
  200. new_length = new_length + strlen(next_arg);
  201. }
  202. }
  203. va_end(strs);
  204. new_str = safe_malloc((1 + new_length) * sizeof(char));
  205. va_start(strs, num_strs);
  206. next_start = 0;
  207. for(i=0; i < num_strs; i++) {
  208. char* next_arg = va_arg(strs, char*);
  209. if(next_arg != NULL) {
  210. int next_length = strlen(next_arg);
  211. memcpy(new_str+next_start,next_arg, next_length);
  212. next_start = next_start+next_length;
  213. }
  214. }
  215. new_str[next_start] = '\0';
  216. return new_str;
  217. }
  218. char* safe_strdup(const char* str) {
  219. char* new_str = NULL;
  220. if(str != NULL) {
  221. new_str = strdup(str);
  222. if(new_str == NULL) {
  223. fprintf(stderr, "ERROR: MALLOC FAILURE!\n");
  224. exit(1);
  225. }
  226. }
  227. return new_str;
  228. }