16 extern char **environ;
18 // don't use before you've authenticated successfully!
19 struct cgi_serialized_session_status session;
21 // when we call this function, we usually leak memory - not an issue
22 static char *session_file_path(char *cookie) {
23 char *file = malloc(strlen(SESSION_FOLDER)+COOKIE_LENGTH+1);
24 memcpy(file, SESSION_FOLDER, strlen(SESSION_FOLDER));
25 memcpy(file+strlen(SESSION_FOLDER), cookie, COOKIE_LENGTH);
26 file[strlen(SESSION_FOLDER)+COOKIE_LENGTH] = '\0';
30 int authenticate_by_cookie(char *cookie) {
31 // check cookie string for conformity
32 if (strlen(cookie) != COOKIE_LENGTH) return 1;
33 if (!checkhex(cookie, COOKIE_LENGTH)) return 2;
36 int fd = open(session_file_path(cookie), O_RDONLY);
38 // verify that the session exists
39 if (fd == -1) return 3;
40 int res = read(fd, &session, sizeof(session));
43 // verify that the session file is valid
44 if (res != sizeof(session)) return 4;
45 session.user_name[32] = 0;
47 // verify that the session is still active
48 time_t cur_time = time(NULL);
49 if (session.start_time + SESSION_LENGTH < cur_time) return 5;
50 if (session.start_time > cur_time) return 6;
52 // verify that the username and the userid still match
53 struct passwd *user_data = getpwuid(session.uid);
54 if (user_data == NULL) return 7;
55 if (strcmp(user_data->pw_name, session.user_name) != 0) return 8;
57 // everything seems fine! :)
61 void persist_session(char *cookie) {
62 char *file = session_file_path(cookie);
63 int fd = open(file, O_RDWR|O_EXCL|O_CREAT, S_IRUSR|S_IWUSR);
64 if (fd == -1) senderr("can't create session file", MYFAULT);
67 int res = write(fd, &session, sizeof(session));
69 if (res != sizeof(session)) {
70 snprintf(errstr, 128, "can't write all session data (%i of %i): %s", (int)res, (int)sizeof(session), strerror(errno));
73 if (res != sizeof(session)) {
75 senderr(errstr, MYFAULT);
79 void senderr(char *errmsg, bool myfault) {
81 puts("Status: 500 CGI error");
83 puts("Status: 400 CGI error");
85 puts("Content-Type: text/plain;charset=utf8");
86 puts("X-Frame-Options: DENY");
88 puts("An error occured while processing your request:");
93 // may send an error response and exit
94 void grabrand(unsigned char *out, size_t len) {
95 int randfd = open(RANDDEV, O_RDONLY);
96 if (randfd == -1) senderr("can't open random device", MYFAULT);
97 if (read(randfd, out, len) != len) senderr("reading random data failed", MYFAULT);
101 void login_and_setup() {
102 char *cookies = getenv("HTTP_COOKIE");
106 // Note that this doesn't validate whether this is actually a cookie name or
107 // part of a value - but that shouldn't be a problem.
108 // Note: Redo if I feel like doing it.
109 if (cookies == NULL) senderr("no cookies sent", NOTMYFAULT);
110 char *session_cookie = strstr(cookies, COOKIE_NAME"=");
111 if (session_cookie == NULL) senderr("session cookie not present", NOTMYFAULT);
112 session_cookie += strlen(COOKIE_NAME"=");
113 if (strlen(session_cookie) < COOKIE_LENGTH) senderr("invalid session cookie (error code 1)", NOTMYFAULT);
114 session_cookie[COOKIE_LENGTH] = '\0';
115 int res = authenticate_by_cookie(session_cookie);
118 snprintf(errstr, 128, "invalid session cookie (error code 2-%i)", res);
119 senderr(errstr, NOTMYFAULT);