在CGI中实现session的想法和实现(ltesting.net)

来源:互联网 发布:淘宝苹果主板哪里来的 编辑:程序博客网 时间:2024/05/22 10:41

对于客户端的每一次登陆,在服务器生成的一个session,作为一个文件存储在服务器上,例如在“/tmp”下。文件命名为sess_开头,在加上一个随机的字符串,这个字符串称之为session_id。

在文件中存储的内容包括:

   1、用户的最后一次活动时间。(用来检查用户是否长时间没有操作,视为已经退出登陆)。

   2、一个随机的字符串。(用来验证客户端的身份,这个字符串同时作为cookie发往客户端)。

   3、客户端的IP.

   4、实际要存储的数据。例如用户的ID,密码等。

   在用户登陆时,生成这个文件,并且,将那个随机字符串发到客户端的cookie.  

   在以后的每个页面的超连接,或是FORM中的要跟入session_id.

   每个页面开始,要:

   1、检查是否超时。

   2、对比cookie中的字符串和session文件中的,验证客户身份。

   3、对比客户端IPsession文件中的IP,验证客户身份。

   4、读出数据,供下面程序使用

   5、刷新最后活动时间

   6、生成新的随机字符串,刷新session中对应部分,并将其作为cookie发往客户端。

   因为我正在做的项目要求比较高的安全性,所以我在这方面考虑的比较多些,下面是我的部分实现代码:

   set_session()在登陆是调用。

   start_session()在每个页面的前面调用。

   kill_session()在退出登陆是调用。

   clean_session() 用来删除过期的session文件。

#include <stdio.h>

#include <stdlib.h>

#include <time.h>

#include <unistd.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <dirent.h>

#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 creat 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 temp[64];

   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_array[3] = sess_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<strlen(buffer);i++)

  {

     if( buffer[i] == '\n'  )

     {

        temp[j] = '\0';

        strcpy(str_array[k],temp);

        j = 0;

        k ++;

     }

     else

     {

       temp[j++] = buffer[i];

     }

  }

/**

  * check active time

  */

  time(&now);

  if( now - atoi(str_time) > atoi(parse_config_file("session_live_time")) )

  {

     print_session_error("2");

     exit(1);

  }

/**

  * compare client hash_key to session hash_key

  */

  if( HTTP_COOKIE == "" || strcmp( HTTP_COOKIE+9 , str_hash_key ) != 0 )

  {

     print_session_error("3");

     exit(1);

  }

/**

  * 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",now);

  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;

  path = "/tmp";

  pdir = opendir(path);

  if(pdir != NULL)

  {

    while( ent =readdir(pdir) )

    {

       filename = ent->d_name;

       if( strncmp(filename,"sess_",5)==0 )

       {

          strcpy(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")) )

          {

            remove(filepath);

          }

          close(fd);

       }

    }

  }

  closedir(pdir);

}

void print_session_error(char *n)

{

   printf("Content-type:text/html\n\n");

   printf("<html><head>";

   print_title("请重新登陆!");

   printf("</head>\n");

   printf("<body>\n");

   printf("对不起,请重新登陆。<p>\n");

   printf("你长时间没有操作,登陆已经超时。或者是系统发生了错误。<p>\n");

   printf("如果是后者,请与管理人员联系。\n");

   printf("<!--%s-->",n);

   printf("</body>");

   printf("</html>\n");

}

                                                                                                                                                                                                        ——领测国际
0 0
原创粉丝点击