在CGI中实现session的想法和实现

原创 2001年09月15日 14:40:00


   对于客户端的每一次登陆,在服务器生成一个session,作为一个文件存储在服务器上,例如在“/tmp”下。
文件命名为sess_开头,在加上一个随机的字符串,这个字符串称之为session_id。
   在文件中存储的内容包括:
   1、用户的最后一次活动时间。(用来检查用户是否长时间没有操作,视为已经退出登陆)。
   2、一个随机的字符串。(用来验证客户端的身份,这个字符串同时作为cookie发往客户端)。
   3、客户端的IP.
   4、实际要存储的数据。例如用户的ID,密码等。

   在用户登陆时,生成这个文件,并且,将那个随机字符串发到客户端的cookie.  
   在以后的每个页面的超连接,或是FORM中的要跟入session_id.
   每个页面开始,要:
   1、检查是否超时。
   2、对比cookie中的字符串和session文件中的,验证客户身份。
   3、对比客户端IP和session文件中的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");
}

 

用c编写CGI,如何实现用户登录的session问题

我的web程序是     html+c语言cgi+boa服务器,以后要放到嵌入式板子里面     但是用户登录的session怎么处理?     javascript没有办法吧?     那只好通过c...
  • gerryzhu
  • gerryzhu
  • 2010年03月25日 18:34
  • 5895

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

对于客户端的每一次登陆,在服务器生成一个session,作为一个文件存储在服务器上,例如在“/tmp”下。 文件命名为sess_开头,在加上一个随机的字符串,这个字符串称之为session_id。 ...
  • marysa
  • marysa
  • 2014年04月21日 14:51
  • 409

session 的cgi 简单实现

http://blog.csdn.net/wybing/archive/2004/12/29/233621.aspx
  • fanlix
  • fanlix
  • 2005年04月20日 11:25
  • 526

关于CGI编程时的各cgi关联问题:同属一个用户的cgi:session与cookie

我们在一些留言本、BBS讨论区发贴时常会出现这种现象:当进入发贴界面时 在要求填写用户名和密码的地方就已经自动地填上了你的资料。这是什么会事呢?这是因为程序中引入了COOKIE技术的缘故。原来在你第一...
  • xiaoshun123
  • xiaoshun123
  • 2010年05月17日 19:04
  • 1192

从想法到实现的关键五步

俗话说得好,良好的开端等于成功的一半,对于一个想法丰富的人来说再重要不过,至今已经不知道拟好了多少个好的点子,有的还停留在草稿纸上的涂涂画画,有些已经有好几份策划案以及设计的图纸,但是作为程序员的我还...
  • jackyanjiaqi
  • jackyanjiaqi
  • 2014年06月18日 13:55
  • 470

Servlet——Session(3)之实现原理的深入讨论

本文介绍了Session的实现机制,深入讨论了其实现原理,最后介绍了用户禁用Cookie之后的处理Session的URL重写方法。...
  • ggGavin
  • ggGavin
  • 2016年05月11日 17:20
  • 6727

CGI接口原理及实现

CGI接口原理及实现   CGI接口原理及实现(2012-12-7 Over)      1.CGI定义:   CGI(CommonGateway Interface)是H...
  • chuanzhilong
  • chuanzhilong
  • 2016年10月20日 08:46
  • 2529

[Java开发] cookie、session及实现记住密码,自动登录思路

在登录帐号、密码框下,有三种帐号登录模式可供选择,用户可根据自己的具体情况选择其中一种适合自己的模式。                                          1、网吧...
  • a137268431
  • a137268431
  • 2015年09月17日 11:27
  • 2672

写一个CGI程序并运行

准备Linux和Apache 我在/var/www/cgi-bin/下建一个文件get.c #include #include int main(void) { char *d...
  • luyaran
  • luyaran
  • 2016年11月17日 13:57
  • 418

单点登录实现(spring session+redis完成session共享

v一、前言   项目中用到的SSO,使用开源框架cas做的。简单的了解了一下cas,并学习了一下 单点登录的原理,有兴趣的同学也可以学习一下,写个demo玩一玩。 v二、工程结构      我...
  • u014386474
  • u014386474
  • 2017年09月25日 20:01
  • 493
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:在CGI中实现session的想法和实现
举报原因:
原因补充:

(最多只允许输入30个字)