For every login of the client, generate a session in the server, as a file is stored on the server, for example under "/ TMP". The file is named sess_ start, plus a random string, which is called session_id. The content stored in the file includes: 1, the last event time of the user. (Used to check if the user has no operation for a long time, it is considered to have exited landing). 2, a random string. (Used to verify the identity of the client, this string is simultaneously sent to the client as a cookie). 3, the client's IP. 4, the actual stored data. For example, the user's ID, password, etc.
When the user logs in, this file is generated, and the random string is sent to the client's cookie. In the subsequent connection of each page, or to keep the session_id in the Form. Each page begins, you want: 1 , Check if it is timeout. 2, compare the character string in cookies and the session file, verify the customer identity. 3, compare the IP in the client IP and the session file, verify the identity of the customer. 4, read data for use by the following procedure
5, refresh the last activity time 6, generate a new random string, refresh the corresponding part in the session, and send it as a cookie to the client.
Because the project I am doing is relatively high, I think about it in this regard, but I know that this is not completely safe. If anyone discovered what loophole, trouble tells me.
Below is my part of the implementation code: set_session () is called in the login. Start_session () calls in front of each page. Kill_Session () is called in exit landing. Clean_Session () is used to delete an expired session file.
#include
#define remote_addr1 GetENV ("remote_addr") # define http_cookie getenv ("http_cookie")
CHAR * sess_user_name; char * sess_user_pwd;
Static void print_session_error (char *); static void clean_session_file ();
Char * set_session (char * name, char * pwd) {char str_now [11]; char hash_key [17]; char * session_id; time_t now;
File * sf; char sfp [32];
INT I, TEMP, R;
Time (& now); / ** * Clean time out session file * / clean_session_file (); / ** * get str_now * / sprintf (STR_NOW, "% 10D", NOW);
/ ** * get random hash_key * / srand (now); r = rand (); for (i = 0; i <16; i ) {SRAND (R); r = rand (); hash_key [i] = r % 26 'a';} Hash_key [16] = '/ 0'; / ** * Get more random session_id; * / temp = rand (); srand (temp); r = rand (); session_id = (char *) Malloc (17 * sizeof (char)); for (i = 0; i <16; i ) {srand (r); r = rand (); session_id [i] = R% 26 a ';} Session_id [16] = '/ 0'; / ** * Create session file * / strcpy (SFP, "/ TMP"); STRCAT (SFP, "/ SESS_"); STRCAT (SFP, SESSION_ID); sf = fopen SFP, "W"); chmod (SFP, 06777);
IF (sf == null) {tc_error_page ("can't create session file";}
/ ** * fputs session file * / fputs (STR_NOW, SF); FPUTS ("/ n", sf); fputs (hash_key, sf); FPUTS ("/ n", sf); FPUTS (Remote_Addr1, sf); FPUTS ("/ n", sf); FPUTS (Name, sf); // sess_user_name fputs ("/ n", sf); FPUTS (PWD, SF); // sess_user_pwd_ fputs ("/ n", sf); Fclose (sf);
/ ** * set cookie * / printf ("set-cookie: hash_key =% s / n", hash_key; return session_id;}
Void start_Session () {INT I, J, K;
Char * session_id; file * sf; char sfp [32]; time_t now; int R;
Char buffer [256]; char str_time [16]; char str_hash_key [20]; char STR_CLIENT_IP [20]; char * STR_ARRAY [6]; sess_user_name = (char *) malloc (32 * sizeof (char ))); Sess_user_pwd = (char *) Malloc (32 * sizeof (char));
STR_ARRAY [0] = STR_TIME; STR_ARRAY [1] = STR_HASH_KEY; STR_ARRAY [2] = STR_CLIENT_IP; STR_ARR_AME; STR_ASER_USER_NAME; STR_ARRAY [4] = sess_user_pwd;
Session_id = cgi_val (Entries, "Session_ID"); / ** * Open session file * / strcpy (sfp, "/ tmp"); strcat (sfp, "/ sess_"); strcat (sfp, session_id); sf = fopen (SFP, "RB "); if (sf == null) / ** can't open session file, maybe session HAS TIME OUT ** / {Print_SESSION_ERROR ("1"); exit (1);} / ** * Read session var * / bzero (buffer, 256); FREAD (Buffer, 1,256, sf); for (i = 0, j = 0, k = 0; K <5 && i
/ ** * Compare Client IP to session ip * / if (strcmp (remote_addr, str_client_ip)! = 0) {Print_Session_ERROR ("4"); exit (1);}
/ ** * refresh session active time * / time (& now); sprintf (str_time, "% 10d / n", count; fseek (sf, 0, seek_set); FPUTS (Str_Time, sf);
/ ** * get new hash_key * / srand (now); r = rand (); for (i = 0; i <16; i ) {SRAND (R); r = rand (); str_hash_key [i] = r % 26 'a';} str_hash_key [16] = '/ n'; str_hash_key [17] = '/ 0';
/ ** * refresh session hash_key * / fseek (sf, 11, seek_set); FPUTS (Str_Hash_Key, SF); Fclose (sf);
/ ** * send cookie refresh client hash_key * / printf ("set-cookie: hash_key =% s", str_hash_key);}
Void Kill_Session () {char * session_id; char * session_path; char sfp [128];
Session_id = CGI_VAL (Entries, "Session_ID");
STRCPY (SFP, "/ TMP"); STRCAT (SFP, "/ SESS_"); STRCAT (SFP, SESSION_ID);
REMOVE (SFP);
Void Clean_Session_File () {DIR * PDIR; Struct Dirent * Ent; char * path; char * filename; char filepath [64]; int fd; char str_time [11]; time_t now; TIME_T NOW;
PATH = "/ TMP"; PDIR = OPENDIR (PATH); if (PDIR! = null) {while (ent = readir (pdir)) {filename = ent-> d_name; if (Strncmp (FileName, "SESS _", 5 ) == 0) {struct (filepath, path); strcat (filepath, "/"); strcat (filepath, filename);
FD = Open (filepath, o_rdonly); Read (FD, STR_TIME, 10); TIME (& NOW); if (now - atoi (str_time)> ATOI (PARSE_CONFIG_FILE ("session_live_time")) {transove (filepath);} close (fd);}}} closedir (PDIR);
Void Print_Session_ERROR (Char * N) {Printf ("Content-Type: Text / HTML / N / N); Printf ("
"; Print_title (" Please re-landlish! "); Printf (" < / HEAD> / N ");Printf ("
/ n"); Printf ("Sorry, please re-land./ n"); Printf ("You have no operation for a long time, login has timeout. Or the system has an error.
/ n "); Printf (" If it is the latter, please contact the manager ./N "); Printf (" / n");}