Libevent实例之系统密码保护程序实现

程序设计

#define MAXSIZE 1024
#define PATH  "/home/heey/libevent_code/" //程序的全局路径

char pawd[MAXSIZE];                       //存放root密码
FILE *logfd;                              //存放日志文件
int isloop = 1;                           //程序是否还在循环监控/etc/shadow文件
struct event_base *base;                    //所有的event事件注册到base中


/*进程守护化*/
static void daemonize(void) {
    int i, fd0, fd1, fd2,pid;
    struct rlimit rl;
  struct sigaction sa;

    umask(0);

    if (getrlimit(RLIMIT_NOFILE, &rl) < 0) {
        fprintf(stderr, "getrlimit(RLIMIT_NOFILE, &rl) failed.\n");
        exit(0);
    }

//  signal(SIGTTOU, SIG_IGN);
//  signal(SIGTTIN, SIG_IGN);
//  signal(SIGTSTP, SIG_IGN);

    if((pid = fork())<0)
    {
        fprintf(stderr, "can not fork\n");
        exit(0);
    }
    else if(pid != 0 )
        exit(0);
    setsid();

    sa.sa_handler = SIG_IGN;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;
    if(sigaction(SIGHUP,&sa,NULL) < 0)
    {
        fprintf(stderr, "can not ignore SIGHUO\n");
        exit(0);
    }
    if((pid = fork()) < 0)
    {
        fprintf(stderr, "can not fork\n");
        exit(0);
    }
    else if(pid != 0 )
        exit(0);


    if ( chdir(PATH) < 0)
        exit(0);

    if (rl.rlim_max == RLIM_INFINITY) {
        rl.rlim_max = 1024;
    }
    for (i = 0; i < rl.rlim_max; i++)
        close(i);

    fd0 = open("/dev/null", O_RDWR|O_CREAT|O_TRUNC);
    fd1 = dup(0);
    fd2 = dup(0);
    if (fd0 != 0 || fd1 != 1 || fd2 != 2) {
        fprintf(stderr, "fd0!=0 || fd1!=1 || fd2!=2\n");
        exit(0);
    }
}
void getime(char * s)
{
    time_t rawtime;
    struct tm * timeinfo;
    time(&rawtime);
    timeinfo = localtime(&rawtime);
    sprintf(s,"%d/%d/%d  %d:%d:%d",timeinfo->tm_year+1900,timeinfo->tm_mon+1,timeinfo->tm_mday,timeinfo->tm_hour,timeinfo->tm_min,timeinfo->tm_sec);
}

int cmp_passwd()
{
    int pid;
    int pipefd[2];
    int nread = 0;

    char temp[50];

    struct spwd *sp;    

    if(-1 == pipe(pipefd))
  {
       write_log(logfd,"pipe error");
       return -1;
  }

    sp = getspnam("root");
    printf("camparer=------------------\n");
  if(strcmp(pawd,sp->sp_pwdp) == 0)
  {
         write_log(logfd,"root passwd normal");
         printf("right----------------------\n");
         return 1;
    }
    else
    {
         pid = fork();
         if(pid == -1)
         {
             write_log(logfd,"fork error");
             return -1; 
         }
     if(pid ==0 )
     {
              char str1[MAXSIZE];
              dup2(pipefd[1],1);
              close(pipefd[1]);
        memset(str1,0,sizeof(str1));
        sprintf(str1,"%s%s",PATH,"destory.sh");
          execl(str1,"destory.sh",NULL);
            printf("execl failed"); //若exec没有执行成功,打印输出,子进程退出
              exit(0);
        }
          else
          {
            wait();
            char str[MAXSIZE];
            memset(str,0,sizeof(str));
            nread = read(pipefd[0],str,sizeof(str));
            if(nread == -1 )
            write_log(logfd,"read pipe error");

            printf("parent running\n");
            memset(temp,0,sizeof(temp)); 
            sprintf(temp,"%s%s","the root passwd is changed,the exec echo is ",str);
            printf("abc %s,%d\n",str,strlen(str));
            write_log(logfd,temp);
            if(strncmp(str,"ok",2) == 0) 
              {

                  write_log(logfd,"the cloudos destory success");
                  return 0;
              }
          }             
    }         
}

void cmd_cb(int fd, short event, void *arg) 
{

    char line[MAXSIZE];
    int nread;

    printf("in cmd_cb\n");
    int old_opt = fcntl(fd,F_GETFL);
    int new_opt = old_opt | O_NONBLOCK;
    fcntl(fd,F_SETFL,new_opt);
    memset(line,0,sizeof(line));

    while(nread=read(fd,line,MAXSIZE))
    {   
        if(nread < 0 )  break;  
    }
    isloop = cmp_passwd();
    if(isloop == 0)
    {
      close(fd);
    event_base_loopbreak(base);
  }
}

void time_cb(int fd, short event, void *arg)
{
    struct event * time_event;
    struct timeval tv = {60,0};
    printf("in time_cb\n");
    isloop = cmp_passwd();
    if(isloop == 0 )
    {
      printf("the fd------------------------------- is %d\n",(*((int*)arg)));
    close(*((int*)arg));
    event_base_loopbreak(base);
    }
    else
    {
      time_event = evtimer_new(base,time_cb,arg);
      evtimer_add(time_event,&tv);
    }
}

int main(int argc,char **argv)
{

  struct spwd *sp;  

  char ch,c;
  char str[MAXSIZE];
  char time[50];

  FILE *fd;
  FILE *notifyfp;

  int i = 0;
  int notifyfd;
  int fp;   
  int nread = 0;
  int waitime = 1 ; //检测root密码是否正常的间隔时间 

  char cmd [] = "inotifywait -rme move,modify,create,delete --timefmt '%F %T' --format '%T=%w%f=%e' /etc";

  struct event *cmd_ev;



  memset(str,0,sizeof(str));
  memset(pawd,0,sizeof(pawd));

  while((ch=getopt(argc,argv,"dt:"))!=-1)
  {
     switch (ch)
     {
        case 't':  waitime = atoi(optarg);break;
        case 'd':  daemonize();break;
     }
  }

  memset(str,0,sizeof(str));
  sprintf(str,"%s%s",PATH,"security.log");
  logfd = fopen(str,"a+");

  memset(str,0,sizeof(str));
  sprintf(str,"%s%s",PATH,"security.conf");
  fd = fopen(str,"a+");
  fp = fileno(fd);
  fchmod(fp,S_IRUSR|S_IWUSR);
  while((c = getc(fd)) != EOF)
  {
    pawd[i] = c;  
    i++;
  }
  //the security.conf is first created
  if(pawd[0] == 0 )
  {
    sp=getspnam("root");
    strcpy(pawd,sp->sp_pwdp);
    nread=fputs(pawd,fd);
    fclose(fd);
  }
  else
    fclose(fd); 


  printf("%s\n",pawd);
  //printf("%s\n",sp->sp_pwdp);
    base = event_init();
    notifyfp = popen(cmd,"r");
    notifyfd = fileno(notifyfp);

    time_cb(0,0,&notifyfd);
    printf("the fd is %d\n",notifyfd);

    sleep(5);
    if(isloop)
    {
    cmd_ev = event_new(base, notifyfd,EV_READ | EV_PERSIST, cmd_cb, NULL);  
  event_add(cmd_ev, NULL);
  printf("add successs -------------------------------------\n");
    event_base_dispatch(base);
  }

    printf("--------------------------------ok\n");

  fclose(logfd);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值