📄 session.cpp
字号:
/* session.cpp*/#define _GNU_SOURCE#include <sys/types.h>#include <shadow.h>#include <unistd.h>#include <syslog.h>#include <pwd.h>#include <string.h>#include <stdlib.h>#include <time.h> //time#include <stdio.h> //asprintf#include <sys/stat.h> //stat#include <syslog.h>#include <errno.h>#include <dirent.h>#include <time.h>#include <signal.h>#include <sys/wait.h>#include "main.h"#include "session.h"#include "environment.h"#include "config.h"#include "mail_process.h"session_t user_ses;char* create_ses_filename(void);int get_session_info_from_file(FILE*);int create_session_file(void);int destroy_passwd(char*); /////////////////////////////////////////////////////////////////////////This will check to see if the user is has already authenticated.// user_ses.sessionid is required// returns 0 on successint check_session(void){ char* ses_filename=NULL; FILE* ses_file=NULL; if(user_ses.sessionid == NULL || user_env.remote_addr == NULL) return(-1); if( (ses_filename=create_ses_filename()) == NULL) return(-1); setuid(euid); if(file_exists(ses_filename) != 1) { setuid(ruid); syslog(LOG_MAIL | LOG_INFO,"%s tried to open non-existent session %s", user_env.remote_addr,user_ses.sessionid); free(ses_filename); return(2); } ses_file=fopen(ses_filename,"r"); setuid(ruid); free(ses_filename); ses_filename=NULL; if(ses_file == NULL) { syslog(LOG_MAIL | LOG_ERR,"Could open ses file (%s)",strerror(errno)); return(-1); } if(get_session_info_from_file(ses_file) != 0) { fclose(ses_file); return(-1); } fclose(ses_file); if (strcmp(user_ses.remoteip,user_env.remote_addr) != 0) { syslog(LOG_MAIL | LOG_INFO, "%s tried to open session he didn't own.", user_env.remote_addr); return(-1); } return(0);}/////////////////////////////////////////////////////////////////////////This will read the session info from a session file// user_ses.sessionid is required// user_ses.name is filled in// user_ses.remoteip is filled in and verified//// returns 0 on success, -1 on failureint get_session_info_from_file(FILE* ses_file){ char* file_buff=NULL; size_t file_buff_size=0; ssize_t b_read=0; char* parameter_start=NULL; enum read_status { rs_pending, rs_done }; read_status status=rs_pending; if(ses_file == NULL || user_ses.sessionid == NULL) return(-1); do { b_read=getline(&file_buff,&file_buff_size,ses_file); if(b_read <= 0 || file_buff == NULL) { if(file_buff != NULL) free(file_buff); status=rs_done; } else { parameter_start=strchr(file_buff,'\n'); if(parameter_start != NULL) *parameter_start='\0'; parameter_start=strchr(file_buff,'='); if(parameter_start != NULL) { parameter_start++; if(strlen(parameter_start) <= 0) parameter_start=NULL; } } if(status == rs_pending && parameter_start != NULL) { if(strncmp(file_buff,"loginname",sizeof("loginname")-1) == 0 && user_ses.loginname == NULL) { if( (user_ses.loginname=strdup(parameter_start)) == NULL) { syslog(LOG_MAIL | LOG_ERR,"Out of memory (%s)",strerror(errno)); destroy_user_ses(); return(-1); } } else if(strncmp(file_buff,"name",sizeof("name")-1) == 0 && user_ses.name == NULL) { if( (user_ses.name=strdup(parameter_start)) == NULL) { syslog(LOG_MAIL | LOG_ERR,"Out of memory (%s)",strerror(errno)); destroy_user_ses(); return(-1); } } else if(strncmp(file_buff,"remoteip",sizeof("remoteip")-1) == 0 && user_ses.remoteip == NULL) { if( (user_ses.remoteip=strdup(parameter_start)) == NULL) { syslog(LOG_MAIL | LOG_ERR,"Out of memory (%s)",strerror(errno)); destroy_user_ses(); return(-1); } } } } while(status == rs_pending); if(user_ses.loginname == NULL || user_ses.remoteip == NULL) { syslog(LOG_MAIL | LOG_ERR,"Corrupt session file %s.",user_ses.sessionid); destroy_user_ses(); return(-1); } return(0);}/////////////////////////////////////////////////////////////////////////This will init a login session, does name/passwd check. If valid,// creates session file //// user_ses.loginname is required//// returns 0 on success// returns 1 on bad username/password// returns -1 on fatal errorint create_session(char* password){ int fdes[2]; FILE* out_pipe=NULL; pid_t pid=0; int status=-1; if(user_ses.loginname == NULL) return(-1); if(pipe(fdes) != 0) { syslog(LOG_MAIL | LOG_ERR,"Pipe failed (%s)",strerror(errno)); return(-1); } pid=fork(); if(pid == 0) //child { destroy_passwd(password); close(fdes[1]); dup2(fdes[0],0); close(fdes[0]); execl(SBINDIR "/login_validate",SBINDIR "/login_validate",NULL); syslog(LOG_MAIL | LOG_ERR,"exec login_validate failed (%s)", strerror(errno)); exit(-1); } else if(pid > 0) //parent { close(fdes[0]); out_pipe=fdopen(fdes[1],"w"); if(out_pipe == NULL) { kill(pid,SIGKILL); syslog(LOG_MAIL | LOG_ERR,"fdopen(pipe) fail (%s)",strerror(errno)); return(-1); } fprintf(out_pipe,"%s\n",user_ses.loginname); fprintf(out_pipe,"%s\n",password); destroy_passwd(password); fclose(out_pipe); waitpid(pid,&status,WUNTRACED); } else //failed { destroy_passwd(password); syslog(LOG_MAIL | LOG_ERR,"Fork failed during auth (%s)",strerror(errno)); return(-1); } if(status != 0) { syslog(LOG_MAIL | LOG_INFO,"User login %s from %s failed", user_ses.loginname,user_env.remote_addr); return(1); } if( create_session_file() != 0) { syslog(LOG_MAIL | LOG_ERR,"Could not create session file"); return(-1); } return(0);}/////////////////////////////////////////////////////////////////////////This creates a session file.// user_ses.loginname && user_env.remote_addr is required.// user_ses.name && user_ses.sessionid && user_ses.remoteip is filled in//// returns 0 on success// returns -1 on fatal errorint create_session_file(void){ mode_t old_mask=0; char* ses_filename; FILE* ses_file_handle; int err=0; struct passwd* data_pwd; if(user_ses.loginname == NULL || user_env.remote_addr == NULL) return(-1);//Fill in user_ses.remoteip if( (user_ses.remoteip=strdup(user_env.remote_addr)) == NULL) { syslog(LOG_MAIL | LOG_ERR,"Out of memory (%s)",strerror(errno)); return(-1); }//Fill in user_ses.name data_pwd=getpwnam(user_ses.loginname); if(data_pwd == NULL) { syslog(LOG_MAIL | LOG_INFO,"User %s exists in /etc/shadow " "but not /etc/passwd",user_ses.loginname); return(-1); } if(data_pwd->pw_uid == 0) { syslog(LOG_MAIL | LOG_INFO,"%s attempted to check root mail", user_ses.remoteip); return(-1); } if(data_pwd->pw_gecos != NULL && *(data_pwd->pw_gecos) != '\0') if( (user_ses.name=strdup(data_pwd->pw_gecos)) == NULL) { syslog(LOG_MAIL | LOG_ERR,"Out of memory (%s)",strerror(errno)); return(-1); }//Fill in user_ses.sessionid srand(time(NULL)); asprintf(&(user_ses.sessionid),"%d",rand()); if(user_ses.sessionid == NULL) { syslog(LOG_MAIL | LOG_ERR,"Out of memory (%s)",strerror(errno)); return(-1); } if( (ses_filename=create_ses_filename()) == NULL) return(-1); setuid(euid); err=file_exists(ses_filename); if(err == 1) { setuid(ruid); syslog(LOG_MAIL | LOG_ERR,"Duplicate sessionid"); return(-1); } if(err != 0) { setuid(ruid); return(-1); } old_mask=umask(0177); ses_file_handle=fopen(ses_filename,"w"); setuid(ruid); umask(old_mask); free(ses_filename);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -