Kagera Session Manager
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

303 Zeilen
7.0KB

  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 wday[4];
  41. char month[4];
  42. switch(utc->tm_wday) {
  43. case 0:
  44. sprintf(wday, "Sun");
  45. break;
  46. case 1:
  47. sprintf(wday, "Mon");
  48. break;
  49. case 2:
  50. sprintf(wday, "Tue");
  51. break;
  52. case 3:
  53. sprintf(wday, "Wed");
  54. break;
  55. case 4:
  56. sprintf(wday, "Thu");
  57. break;
  58. case 5:
  59. sprintf(wday, "Fri");
  60. break;
  61. case 6:
  62. sprintf(wday, "Sat");
  63. break;
  64. }
  65. switch(utc->tm_mon) {
  66. case 0:
  67. sprintf(month, "Jan");
  68. break;
  69. case 1:
  70. sprintf(month, "Feb");
  71. break;
  72. case 2:
  73. sprintf(month, "Mar");
  74. break;
  75. case 3:
  76. sprintf(month, "Apr");
  77. break;
  78. case 4:
  79. sprintf(month, "May");
  80. break;
  81. case 5:
  82. sprintf(month, "Jun");
  83. break;
  84. case 6:
  85. sprintf(month, "Jul");
  86. break;
  87. case 7:
  88. sprintf(month, "Aug");
  89. break;
  90. case 8:
  91. sprintf(month, "Sep");
  92. break;
  93. case 9:
  94. sprintf(month, "Oct");
  95. break;
  96. case 10:
  97. sprintf(month, "Nov");
  98. break;
  99. case 11:
  100. sprintf(month, "Dec");
  101. break;
  102. }
  103. char utc_str[200];
  104. 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);
  105. return safe_strdup(utc_str);
  106. }
  107. int main(int argc, char **argv) {
  108. char *password = NULL;
  109. char *username = NULL;
  110. char *cookie_hash = NULL;
  111. char *cookie_exp = NULL;
  112. char *user_agent = NULL;
  113. char *src_ip = NULL;
  114. char *redirect = NULL;
  115. int timeout_minutes = DEFAULT_SESSION_TIMEOUT;
  116. unsigned long browser_time = 0;
  117. int loggedout = 0;
  118. int next_opt;
  119. int read;
  120. 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) {
  121. switch(next_opt) {
  122. case 'p':
  123. case 'P':
  124. password = safe_strdup(optarg);
  125. break;
  126. case 'u':
  127. case 'U':
  128. username = safe_strdup(optarg);
  129. break;
  130. case 'c':
  131. case 'C':
  132. cookie_hash = safe_strdup(optarg);
  133. break;
  134. case 'e':
  135. case 'E':
  136. cookie_exp = safe_strdup(optarg);
  137. break;
  138. case 'a':
  139. case 'A':
  140. user_agent = safe_strdup(optarg);
  141. break;
  142. case 'i':
  143. case 'I':
  144. src_ip = safe_strdup(optarg);
  145. break;
  146. case 'r':
  147. case 'R':
  148. redirect = safe_strdup(optarg);
  149. break;
  150. case 't':
  151. case 'T':
  152. read = sscanf(optarg, "%d", &timeout_minutes);
  153. if(read > 0) {
  154. timeout_minutes = timeout_minutes > 0 ? timeout_minutes : DEFAULT_SESSION_TIMEOUT;
  155. } else {
  156. timeout_minutes = DEFAULT_SESSION_TIMEOUT;
  157. }
  158. timeout_minutes *= 60;
  159. break;
  160. case 'b':
  161. case 'B':
  162. read = sscanf(optarg, "%ld", &browser_time);
  163. browser_time = read > 0 ? browser_time : 0;
  164. break;
  165. case 'l':
  166. case 'L':
  167. loggedout = 1;
  168. break;
  169. }
  170. }
  171. int expired = 0;
  172. int valid = 0;
  173. char* admin_hash = get_admin_hash(username);
  174. if(loggedout == 1) {
  175. printf("echo \"Set-Cookie:kagera_sid=loggedout;\"; echo \"Set-Cookie:kagera_usr=loggedout;\"; ");
  176. } else if(admin_hash != NULL) {
  177. time_t now;
  178. time(&now);
  179. if(password != NULL) {
  180. valid = strcmp(crypt(password, admin_hash), admin_hash) == 0 ? 1 : 0;
  181. if(valid) {
  182. printf("logger -t webui \"Kagera Administration Interface authorization succeeded from ${REMOTE_ADDR}\"; ");
  183. }
  184. } else if(cookie_hash != NULL && cookie_exp != NULL && user_agent != NULL && src_ip != NULL) {
  185. time_t exp_time;
  186. int read = sscanf(cookie_exp, "%ld", &exp_time);
  187. if(read > 0) {
  188. expired = 1;
  189. if(exp_time > now && (exp_time - (timeout_minutes) - 2) <= now) {
  190. expired = 0;
  191. }
  192. }
  193. char *combined = safe_strcat(4, admin_hash, cookie_exp, user_agent, src_ip);
  194. char* hashed = get_sha256_hash_hex_str(combined);
  195. if(strcmp(hashed, cookie_hash) == 0) {
  196. if(expired == 0 && read > 0) {
  197. valid = 1;
  198. }
  199. } else {
  200. expired = 0;
  201. }
  202. free(hashed);
  203. free(combined);
  204. }
  205. if(valid == 1 && src_ip != NULL && user_agent != NULL) {
  206. char* new_hash;
  207. char* combined;
  208. char new_exp[100] = "";
  209. time_t new_exp_t = now + (timeout_minutes);
  210. sprintf(new_exp, "%ld", new_exp_t);
  211. char* cookie_exp;
  212. if(browser_time > 0 && ((browser_time - now) < (-5*60) || (browser_time - now) > (5*60))) {
  213. time_t cookie_exp_t = browser_time+(timeout_minutes);
  214. cookie_exp = get_cookie_time(cookie_exp_t);
  215. } else {
  216. cookie_exp = get_cookie_time(new_exp_t);
  217. }
  218. combined = safe_strcat(4, admin_hash, new_exp, user_agent, src_ip);
  219. new_hash = get_sha256_hash_hex_str(combined);
  220. if(browser_time == 0) {
  221. 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);
  222. } else {
  223. 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);
  224. }
  225. free(new_hash);
  226. free(combined);
  227. free(cookie_exp);
  228. printf("VALIDSESS=1\n");
  229. }
  230. free(admin_hash);
  231. }
  232. if(redirect != NULL) {
  233. char str[20] = "";
  234. if(expired == 1) {
  235. sprintf(str, "&expired=1");
  236. } else if(loggedout == 1) {
  237. sprintf(str, "&loggedout=1");
  238. }
  239. printf("echo \"HTTP/1.1 301 Moved Permanently;\"; echo \"Location: %s%s\"; exit", redirect, str);
  240. }
  241. return 0;
  242. }
  243. void* safe_malloc(size_t size) {
  244. void* val = malloc(size);
  245. if(val == NULL) {
  246. fprintf(stderr, "ERROR: MALLOC FAILURE!\n");
  247. exit(1);
  248. }
  249. return val;
  250. }
  251. char* safe_strcat(int num_strs, ...) {
  252. va_list strs;
  253. int new_length = 0;
  254. int i;
  255. int next_start;
  256. char* new_str;
  257. va_start(strs, num_strs);
  258. for(i=0; i < num_strs; i++) {
  259. char* next_arg = va_arg(strs, char*);
  260. if(next_arg != NULL) {
  261. new_length = new_length + strlen(next_arg);
  262. }
  263. }
  264. va_end(strs);
  265. new_str = safe_malloc((1 + new_length) * sizeof(char));
  266. va_start(strs, num_strs);
  267. next_start = 0;
  268. for(i=0; i < num_strs; i++) {
  269. char* next_arg = va_arg(strs, char*);
  270. if(next_arg != NULL) {
  271. int next_length = strlen(next_arg);
  272. memcpy(new_str+next_start,next_arg, next_length);
  273. next_start = next_start+next_length;
  274. }
  275. }
  276. new_str[next_start] = '\0';
  277. return new_str;
  278. }
  279. char* safe_strdup(const char* str) {
  280. char* new_str = NULL;
  281. if(str != NULL) {
  282. new_str = strdup(str);
  283. if(new_str == NULL) {
  284. fprintf(stderr, "ERROR: MALLOC FAILURE!\n");
  285. exit(1);
  286. }
  287. }
  288. return new_str;
  289. }