system "$ipfwpath","-q","add","$rulenumber",
"count","tag","$ipfwtagnumber","ip","from","any","to","$clientaddr";
-## remove process attached to the same user on different ip address.
-## if you allow multi-login, comment out next line.
-removeSameUserProc
- ($ipfwpath,$rulenumber,$clientaddr,$userid,$macaddr,$userproperty,$ipfwtagnumber);
-
exit 0;
-
-######## Search same user processes and remove.############
-sub removeSameUserProc
-{
- # get response from 'ps ax'.
- open(pspipe, "ps -axww|");
-
- # scan ps output
- while(<pspipe>){
- # get lines for opengatesrv process and divide it with ','
- if(/\s*(\d*) .* opengatesrv.cgi: (.*),(.*),(.*) /){
- $ps_number=$1; $ps_arg1=$2; $ps_arg2=$3; $ps_arg3=$4;
-
- # get the user id before '('
- if($ps_arg1=~/(.*)\(/){
- $ps_user=$1;
- }else{
- $ps_user=$ps_arg1;
- }
-
- # get the IPv4 address located between '[' and '('
- if($ps_arg2=~/\[(.*)\(/){
- $ps_ipv4=$1;
- }else{
- $ps_ipv4="";
- }
- # get the IPv4 rule number located between '(' and ')'
- if($ps_arg2=~/\((\d*)\)\]/){
- $ps_rule4=$1;
- }else{
- $ps_rule4="";
- }
-
- # get the IPv6 address located between '[' and '('
- if($ps_arg3=~/\[(.*)\(/){
- $ps_ipv6=$1;
- }else{
- $ps_ipv6="";
- }
- # get the IPv6 rule number located between '(' and ')'
- if($ps_arg3=~/\((\d*)\)\]/){
- $ps_rule6=$1;
- }else{
- $ps_rule6="";
- }
-
- # get the IPv6 address located between '[' and '('
- if($ps_arg3=~/\[(.*)\(/){
- $ps_ipv6=$1;
- }else{
- $ps_ipv6="";
- }
-
- # kill process attached to same user on different address.
- $need_to_kill = 0;
-
- # is same user?
- if($userid eq $ps_user){
-
- # is ipv6 addr ?
- if($clientaddr=~/:/){
-
- # is not same ipv6 addr ?
- if( ($ps_ipv6 ne "") && ($ps_ipv6 ne $clientaddr) ){
- system "$ipfwpath","-q","del","$ps_rule6";
- $need_to_kill = 1;
- }
-
- }else{
-
- # is not same ipv4 addr ?
- if( ($ps_ipv4 ne "") && ($ps_ipv4 ne $clientaddr) ){
- system "$ipfwpath","-q","del","$ps_rule4";
- $need_to_kill = 1;
- }
- }
-
- # is found process need to kill ?
- if( $need_to_kill == 1 ){
- system "kill", "$ps_number";
- }
- }
- }
- }
- close(pspipe);
-}
-
__END__
########### Above line is the end of interpreting#############
system "$ipfwpath","-q","add","$rulenumber",
"count","tag","$ipfwtagnumber","ip","from","any","to","$clientaddr";
-## remove process attached to the same user on different ip address.
-## if you allow multi-login, comment out next line.
-removeSameUserProc
- ($ipfwpath,$rulenumber,$clientaddr,$userid,$macaddr,$userproperty,$ipfwtagnumber);
-
exit 0;
======================================================
Ver.1.5.17 at 2012.2.13
</DT><DD>
Removed 2 error messages.
+ </DD><DT>
+ Ver.1.5.18 at 2012.2.28
+ </DT><DD>
+ Modified treatment of overlapped sessions. Fixed bugs.
</DD>
</DL>
<P>
/********************************************/
/* get data related to cookie from client */
/********************************************/
-int getCookieData(char *userid, char *clientAddr4, int *duration, int *durationEntered, char *language)
+int getCookieData(char *userid, char *clientAddr4, int *duration, int *durationEntered, char *language, char* closeTime)
{
char cookie[SIDMAXLN]=""; /* md5 session key from cookie */
char useridInCookie[USERMAXLN]=""; /* userid from cookie */
/* get related info from DB */
if(!GetSessionInfoFromDb(cookie, userid, clientAddr4, macAddrInDb,
- duration, durationEntered, language)) return FALSE;
+ duration, durationEntered, language, closeTime)) return FALSE;
/* if userid is changed, cookie auth is failed */
if(strcmp(useridInCookie, userid)!=0) return FALSE;
return ret;
}
-int GetCookieData(char *userid, char *clientAddr4, int *duration, int *durationEntered, char *language){
+int GetCookieData(char *userid, char *clientAddr4, int *duration, int *durationEntered, char *language, char* closeTime){
int ret;
if(debug>1) err_msg("DEBUG:=>getCookieData( )");
- ret=getCookieData(userid,clientAddr4,duration,durationEntered,language);
- if(debug>1) err_msg("DEBUG:%d<=getCookieData(%s,passwd,%s,%d,%d,%s)",ret,userid,clientAddr4,*duration,*durationEntered,language);
+ ret=getCookieData(userid,clientAddr4,duration,durationEntered,
+ language,closeTime);
+ if(debug>1) err_msg("DEBUG:%d<=getCookieData(%s,passwd,%s,%d,%d,%s,%s)",ret,userid,clientAddr4,*duration,*durationEntered,language,closeTime);
return ret;
}
Sigfunc *defaultSigFunc;
- /* exclusive exec of ipfw to avoid overlapped rule number */
+ /* exclusive exec of ipfw to avoid duplicated rule number */
/**** prepare ****/
/* open lockfile */
err_msg("ERR at %s#%d: exec ipfw script error",__FILE__,__LINE__);
ret=1; /* abmormal */
}
-
- /* lock is not necessary in following exec */
- Unlock(fd);
- Close(fd); /* because reserved number is used */
-
- }else{
+ }
+ else{
/********** direct control of firewall **********************/
/********** add outgoing ipfw rule for the client *************/
if(Systeml(1, GetConfValue("IpfwPath"),"-q","add",ruleNumber6,
err_msg("ERR at %s#%d: exec ipfw add error",__FILE__,__LINE__);
ret=1;
}
-
- /* lock is not necessary in following exec */
- Unlock(fd);
- Close(fd); /* because reserved number is used */
/********** add incoming ipfw rule for the client *************/
if(Systeml(1, GetConfValue("IpfwPath"),"-q","add",ruleNumber6,
ret=1; /* abnormal */
}
}
+
+ /* uplock */
+ Unlock(fd);
+ Close(fd);
+
return ret;
}
int ip6fwinterval;
int portStatus;
int fileStatus;
- enum status {NORMAL, ABNORMAL, FOUND, NOTFOUND, DUPLICATED};
+ enum status {NORMAL, ABNORMAL, FOUND, NOTFOUND, DUP};
if((fpipe=Popenl(1, "r", GetConfValue("IpfwPath"),"list",(char *)0)) == NULL){
err_msg("ERR at %s#%d: exec ipfw list error",__FILE__,__LINE__);
&& !isalnum(*(p+strlen(clientAddr6)))){
/* the clientAddr is found in the rule num */
newNum=num;
- portStatus=DUPLICATED;
+ portStatus=DUP;
break;
}
/* the num is used for other client */
err_msg("ERR at %s#%d: cannot get unused ipfw number",__FILE__,__LINE__);
return -1;
}
- if(portStatus==DUPLICATED){
+ if(portStatus==DUP){
+ snprintf(ruleNumber6, WORDMAXLN, "%d", newNum); /* to string */
return -newNum;
}
Sigfunc *defaultSigFunc;
- /* exclusive exec of ipfw to avoid overlapped rule number */
+ /* exclusive exec of ipfw to avoid duplicated rule number */
/**** prepare ****/
/* open lockfile */
fd=open(GetConfValue("LockFile"), O_RDWR|O_CREAT,
err_msg("ERR at %s#%d: exec script error",__FILE__,__LINE__);
ret=1; /* abnormal */
}
-
- /* lock is not necessary in following exec */
- Unlock(fd);
- Close(fd); /* because reserved number is used */
-
- }else{
+ }
+ else{
/********** direct control of firewall **********************/
/********** add outgoing ipfw rule for the client *************/
if(Systeml(1, GetConfValue("IpfwPath"),"-q","add",ruleNumber4,
ret=1; /* abnormal */
}
- /* lock is not necessary in following exec */
- Unlock(fd);
- Close(fd); /* because reserved number is used */
-
if(Systeml(1, GetConfValue("IpfwPath"),"-q","add",ruleNumber4,
"count","tag",GetConfValue("IpfwTagNumber"),
"ip","from","any","to",clientAddr4,
ret=1; /* abnormal */
}
}
+
+ /* unlock */
+ Unlock(fd);
+ Close(fd);
+
return ret;
}
int ipfwinterval;
int portStatus;
int fileStatus;
- enum status {NORMAL, ABNORMAL, FOUND, NOTFOUND, DUPLICATED};
+ enum status {NORMAL, ABNORMAL, FOUND, NOTFOUND, DUP};
/* exec ipfw list and open pipe */
if((fpipe=Popenl(1, "r", GetConfValue("IpfwPath"),"list",(char *)0)) == NULL){
if(((p=(char*)strstr(buf+1,clientAddr4))!=NULL)
&& isspace(*(p-1))
&& !isalnum(*(p+strlen(clientAddr4)))){
- err_msg("ERR at %s#%d: overlapped request from %s",
- __FILE__,__LINE__, clientAddr4);
newNum=num;
- portStatus=DUPLICATED;
+ portStatus=DUP;
break;
}
/* the num is used for other client */
err_msg("ERR at %s#%d: cannot get unused ipfw number",__FILE__,__LINE__);
return -1;
}
- if(portStatus==DUPLICATED){
+ if(portStatus==DUP){
+ snprintf(ruleNumber4, WORDMAXLN, "%d", newNum); /* to string */
return -newNum;
}
sqlite3 *db;
char *pErrMsg;
/* SQL CREATE COMMAND */
- char *createCmd="CREATE TABLE session (cookie TEXT PRIMARY KEY,\
+ char *createTblCmd="CREATE TABLE IF NOT EXISTS \
+ session (cookie TEXT PRIMARY KEY,\
userid TEXT, pid INTEGER, openTime TEXT, closeTime TEXT,\
clientAddr4 TEXT, clientAddr6 TEXT, macAddr TEXT,\
ruleNumber4 INTEGER, ruleNumber6 INTEGER,duration INTEGER,\
durationEntered INTEGER, cookieAuth INTEGER, language TEXT, watchMode TEXT)";
+ char *createIdx1Cmd="CREATE INDEX IF NOT EXISTS \
+ clientAddr4Index ON session (clientAddr4)";
+
+ char *createIdx2Cmd="CREATE INDEX IF NOT EXISTS \
+ closeTimeIndex ON session (closeTime)";
+
+
/* SQL INSERT COMMAND, where %x is replaced in snprintf */
char *insertFormat="INSERT INTO session\
(cookie, userid, pid, openTime, closeTime,\
return FALSE;
}
+ /* create table if not exists */
+ if(sqlite3_exec(db, createTblCmd, NULL, NULL, &pErrMsg)!=SQLITE_OK){
+ resultFlag=FALSE;
+ err_msg("ERR at %s#%d: sqlite3_exec: %s",__FILE__,__LINE__,pErrMsg);
+ }
+
+ /* create index for clientAddr4 if not exists */
+ if(sqlite3_exec(db, createIdx1Cmd, NULL, NULL, &pErrMsg)!=SQLITE_OK){
+ resultFlag=FALSE;
+ err_msg("ERR at %s#%d: sqlite3_exec: %s",__FILE__,__LINE__,pErrMsg);
+ }
+
+ /* create index for closeTime if not exists */
+ if(sqlite3_exec(db, createIdx2Cmd, NULL, NULL, &pErrMsg)!=SQLITE_OK){
+ resultFlag=FALSE;
+ err_msg("ERR at %s#%d: sqlite3_exec: %s",__FILE__,__LINE__,pErrMsg);
+ }
+
/* Prepare insert command */
insertCmd=sqlite3_mprintf(insertFormat,cookie,userid,
getpid(),time(NULL),clientAddr4,clientAddr6,
/* Execute insert to sqlite */
if((rc=sqlite3_exec(db, insertCmd, NULL, NULL, &pErrMsg))!=SQLITE_OK){
-
- /* If the error is 'no such table' It might be initial state */
- if(rc==SQLITE_ERROR && strstr(pErrMsg, "no such table:")!=NULL){
-
- /* retry from create */
- if(sqlite3_exec(db, createCmd, NULL, NULL, &pErrMsg)!=SQLITE_OK){
- resultFlag=FALSE;
- err_msg("ERR at %s#%d: sqlite3_exec: %s",__FILE__,__LINE__,pErrMsg);
- }
- if(sqlite3_exec(db, insertCmd, NULL, NULL, &pErrMsg)!=SQLITE_OK){
- resultFlag=FALSE;
- err_msg("ERR at %s#%d: sqlite3_exec: %s",__FILE__,__LINE__,pErrMsg);
- }
- }
/* If the error is 'table session has no column named xxx' */
/* It might be adding column in varsion up */
- else if(rc==SQLITE_ERROR && strstr(pErrMsg, "has no column named")!=NULL){
+ if(rc==SQLITE_ERROR && strstr(pErrMsg, "has no column named")!=NULL){
err_msg("ERR at %s#%d: DB format is changed in version up, remove '%s' and retry",__FILE__,__LINE__,GetConfValue("SqliteDb"));
resultFlag=FALSE;
}
return resultFlag;
}
+/**************************************************************/
+/* write close time to db to fix no-close error */
+/**************************************************************/
+int fixProcessEndInDb(int pid, char* watchMode){
+
+ sqlite3 *db;
+ char *pErrMsg;
+
+ /* SQL UPDATE COMMAND, where %x is replaced in mprintf */
+ char *updateFormat="UPDATE session SET closeTime=\
+ datetime(%d,'unixepoch','localtime'), watchMode='%s' WHERE pid=%d";
+ char *updateCmd;
+ int resultFlag=TRUE;
+
+ /* open sqlite */
+ if(sqlite3_open(GetConfValue("SqliteDb"),&db)!=SQLITE_OK){
+ err_msg("ERR at %s#%d: sqlite3_open",__FILE__,__LINE__);
+ sqlite3_close(db);
+ return FALSE;
+ }
+
+ /* prepare command */
+ updateCmd=sqlite3_mprintf(updateFormat, time(NULL), watchMode, pid);
+
+ /* execute replace to sqlite */
+ if(sqlite3_exec(db, updateCmd, NULL, NULL, &pErrMsg)!=SQLITE_OK){
+ resultFlag=FALSE;
+ err_msg("ERR at %s#%d: sqlite3_exec: %s",__FILE__,__LINE__,pErrMsg);
+ }
+
+ /*memory free for sqlite3 string */
+ sqlite3_free(updateCmd);
+
+ /* sqlite close */
+ sqlite3_close(db);
+
+ return resultFlag;
+}
+
/*************************************************/
-/* read userid and others from session database */
+/* read userid and others from session database */
+/* search key is coocke */
/*************************************************/
int getSessionInfoFromDb(char* cookie, char* userid,
char* clientAddr4, char *macAddr,
- int *duration, int *durationEntered, char *language){
+ int *duration, int *durationEntered, char *language,
+ char* closeTime){
sqlite3 *db;
sqlite3_stmt *stmt;
/* SQL UPDATE COMMAND, where %x is replaced in snprintf */
char *selectFormat="SELECT userid, clientAddr4, macAddr,\
- duration, durationEntered,language FROM session WHERE cookie='%s'";
+ duration, durationEntered,language,closeTime FROM session WHERE cookie='%s'";
char *selectCmd;
int resultFlag=TRUE;
*duration=(int)sqlite3_column_int(stmt, 3);
*durationEntered=(int)sqlite3_column_int(stmt, 4);
strncpy(language, (char*)sqlite3_column_text(stmt, 5), WORDMAXLN);
+ strncpy(closeTime, (char*)sqlite3_column_text(stmt, 6), WORDMAXLN);
resultFlag=TRUE;
}else{
resultFlag=FALSE;
return ACCEPT; /* The User is Accepted */
}
+
+/******************************************
+find the duplicated entry in db for an ipv4 address
+if redundant rule exists, positive value is returned
+******************************************/
+int findDuplicateInDbAndClose(char* clientAddr4, int* redundantRule4,
+ int* redundantRule6, int* redundantPid ){
+
+ sqlite3 *db;
+ sqlite3_stmt *stmt;
+ char *pErrMsg;
+
+ /* SQL COMMAND, where %x is replaced in mprintf */
+ char *selectMeFormat="SELECT ruleNumber4, ruleNumber6 \
+ FROM session WHERE clientAddr4='%s' and closeTime='-' and pid=%d";
+ char *selectOtherFormat="SELECT ruleNumber4, ruleNumber6, pid \
+ FROM session WHERE clientAddr4='%s' and closeTime='-' and pid!=%d";
+ char *selectCmd;
+
+ /* SQL UPDATE COMMAND to write close time */
+ char *updateFormat="UPDATE session SET closeTime=\
+ datetime(%d,'unixepoch','localtime'), watchMode='%s' \
+ WHERE clientAddr4='%s' and closeTime='-' and pid=%d";
+
+ /* SQL TRANSACTION COMMAND */
+ char *beginTransaction="BEGIN TRANSACTION";
+ char *commitTransaction="COMMIT TRANSACTION";
+
+ char *updateCmd;
+ int resultFlag=TRUE;
+ int ruleNumberMe4=0;
+ int ruleNumberMe6=0;
+ int ruleNumberOther4=0;
+ int ruleNumberOther6=0;
+
+ /* initial values */
+ *redundantRule4=0;
+ *redundantRule6=0;
+ *redundantPid=0;
+
+ /********************prepare db**********************/
+ /* open sqlite */
+ if(sqlite3_open(GetConfValue("SqliteDb"),&db)!=SQLITE_OK){
+ err_msg("ERR at %s#%d: sqlite3_open",__FILE__,__LINE__);
+ sqlite3_close(db);
+ return FALSE;
+ }
+
+ /* begin transaction */
+ sqlite3_exec(db, beginTransaction, NULL, NULL, &pErrMsg);
+
+ /***************** search other session in db******************/
+
+ /* prepare command string to search other session */
+ selectCmd=sqlite3_mprintf(selectOtherFormat, clientAddr4, getpid());
+
+ /* compile to internal statement */
+ if(sqlite3_prepare(db, selectCmd, BUFFMAXLN, &stmt, NULL)!=SQLITE_OK){
+ resultFlag=FALSE;
+ err_msg("ERR at %s#%d: sqlite3_prepare:%s",__FILE__,__LINE__,
+ sqlite3_errmsg(db));
+
+ /* finalize */
+ sqlite3_free(selectCmd);
+ sqlite3_finalize(stmt);
+ sqlite3_close(db);
+ return FALSE;
+ }
+
+ /* get first match item */
+ if(sqlite3_step(stmt)==SQLITE_ROW){
+ ruleNumberOther4=(int)sqlite3_column_int(stmt, 0);
+ ruleNumberOther6=(int)sqlite3_column_int(stmt, 1);
+ *redundantPid=(int)sqlite3_column_int(stmt, 2);
+ resultFlag=TRUE;
+ }else{
+ resultFlag=FALSE;
+ }
+
+ /* finalize */
+ sqlite3_free(selectCmd);
+ sqlite3_finalize(stmt);
+ if(resultFlag==FALSE){
+ sqlite3_close(db);
+ return FALSE;
+ }
+
+ /***********if found other, search my session in db ***********/
+
+ /* prepare command string to search my session */
+ selectCmd=sqlite3_mprintf(selectMeFormat, clientAddr4, getpid());
+
+ /* compile to internal statement */
+ if(sqlite3_prepare(db, selectCmd, BUFFMAXLN, &stmt, NULL)!=SQLITE_OK){
+ resultFlag=FALSE;
+ err_msg("ERR at %s#%d: sqlite3_prepare:%s",__FILE__,__LINE__,
+ sqlite3_errmsg(db));
+
+ /* finalize */
+ sqlite3_free(selectCmd);
+ sqlite3_finalize(stmt);
+ sqlite3_close(db);
+ return FALSE;
+ }
+
+ /* get first match item */
+ if(sqlite3_step(stmt)==SQLITE_ROW){
+ ruleNumberMe4=(int)sqlite3_column_int(stmt, 0);
+ ruleNumberMe6=(int)sqlite3_column_int(stmt, 1);
+ resultFlag=TRUE;
+ }else{
+ resultFlag=FALSE;
+ }
+
+ /* finalize */
+ sqlite3_free(selectCmd);
+ sqlite3_finalize(stmt);
+ if(resultFlag==FALSE){
+ sqlite3_close(db);
+ return FALSE;
+ }
+
+ /*****************write close of my session**********/
+
+ /* prepare command to write close time */
+ updateCmd=sqlite3_mprintf(updateFormat, time(NULL), "NONE",
+ clientAddr4, getpid());
+
+ /* execute replace to sqlite */
+ if(sqlite3_exec(db, updateCmd, NULL, NULL, &pErrMsg)!=SQLITE_OK){
+ resultFlag=FALSE;
+ err_msg("ERR at %s#%d: sqlite3_exec: %s",__FILE__,__LINE__,pErrMsg);
+ }
+
+ /*memory free for sqlite3 string */
+ sqlite3_free(updateCmd);
+
+ /***************finalize db***********************/
+
+ /* end transaction and sqlite close */
+ sqlite3_exec(db, commitTransaction, NULL, NULL, &pErrMsg);
+ sqlite3_close(db);
+
+ /******************check overlapped rule*************/
+
+ /* if rule number is not match, my rule is redundant */
+ if(resultFlag==TRUE){
+ if(ruleNumberMe4==ruleNumberOther4) *redundantRule4=0;
+ else *redundantRule4=ruleNumberMe4;
+ if(ruleNumberMe6==ruleNumberOther6) *redundantRule6=0;
+ else *redundantRule6=ruleNumberMe6;
+ }
+
+ return resultFlag;
+}
+
+
+/***************************************************************/
/***************************************************************/
/* debug write routine */
int PutSessionBeginToDb(char* cookie, char* userid,
return ret;
}
+
+int FixProcessEndInDb(int pid, char* watchMode){
+ int ret;
+
+ if(debug>1) err_msg("DEBUG:=>fixProcessEndInDb(%s,%s)", pid, watchMode);
+ ret=fixProcessEndInDb(pid,watchMode);
+ if(debug>1) err_msg("DEBUG:(%d)<=fixProcessEndInDb()",ret);
+
+ return ret;
+}
+
+
int GetSessionInfoFromDb(char* cookie, char* userid, char* clientAddr4,
char *macAddr, int *duration, int *durationEntered,
- char *language){
+ char *language, char* closeTime){
int ret;
if(debug>1) err_msg("DEBUG:=>getInfoFromDb(%s)",cookie);
ret=getSessionInfoFromDb(cookie,userid,clientAddr4, macAddr,
- duration,durationEntered,language);
+ duration,durationEntered,language,closeTime);
if(debug>1) err_msg("DEBUG:(%d)<=getInfoFromDb(%s,%s,%s,%s,%d,%d,%s)",
ret,cookie,userid,clientAddr4, macAddr,
- *duration,*durationEntered,language);
+ *duration,*durationEntered,language,closeTime);
return ret;
}
if(debug>1) err_msg("DEBUG:(%d)<=checkNatInsertion( )",ret);
return ret;
}
+
+int FindDuplicateInDbAndClose(char* clientAddr4, int* redundantRule4,
+ int* redundantRule6, int* redundantPid ){
+ int ret;
+ if(debug>1) err_msg("DEBUG:=>findDuplicateInDbAndClose(%s,)",clientAddr4);
+ ret=findDuplicateInDbAndClose(clientAddr4,redundantRule4,redundantRule6, redundantPid);
+ if(debug>1) err_msg("DEBUG:(%d)<=findDuplicateInDbAndClose(,%d,%d,%d)",ret,
+ *redundantRule4,*redundantRule6, *redundantPid);
+ return ret;
+}
struct clientAddr *pClientAddr = NULL;
int ipStatus;
-void RemoveOverlapRule(int overlapRule4, int overlapRule6);
-void KillOverlapProcess(int overlapRule4, int overlapRule6,
- char *clientAddr4, char *clientAddr6);
-
/**************************************/
/* Open client gate for IPv4 and IPv6 */
/**************************************/
{
int ret;
struct clientAddr *pLastClientAddr=NULL;
- int overlapRule4=0, overlapRule6=0;
+ int duplicateRule4=0, duplicateRule6=0;
switch(ipStatus){
case IPV46DUAL:
/*** at first, open IPv4 gate *****/
- if((ret=OpenClientGate4(clientAddr4, userid, macAddr4, userProperty))==0){
+ ret=OpenClientGate4(clientAddr4, userid, macAddr4, userProperty);
+ if(ret==0 || ret<-2){ /* normally open or duplicated open */
/* open success */
err_msg("OPEN: user %s from %s at %s", userid, clientAddr4, macAddr4);
/* create new address list. head and tail pointer point the same item. */
pLastClientAddr=pClientAddr=CreateAddrListItem(clientAddr4,ruleNumber4,IPV4);
+
+ /* save dupliacted rule */
+ if(ret<-2) duplicateRule4=-ret;
}
/* open fail */
return FALSE;
}
- /* other case (ret<-2) means overlapped rule */
- else overlapRule4=-ret;
-
/*** next, open IPv6 gate *****/
- if((ret=OpenClientGate6(clientAddr6, userid, macAddr6, userProperty))==0){
+ ret=OpenClientGate6(clientAddr6, userid, macAddr6, userProperty);
+ if(ret==0 || ret<-2){ /* normally open or duplicated open */
/* open success */
err_msg("OPEN: user %s from %s at %s", userid, clientAddr6, macAddr6);
/* add the address info to list */
pLastClientAddr->next = CreateAddrListItem(clientAddr6,ruleNumber6,IPV6);
+
+ /* save dupliacted rule */
+ if(ret<-2) duplicateRule6=-ret;
}
/* open fail */
else{
PutClientMsg("Error: Please contact to the administrator");
return FALSE;
}
-
- /* other case (ret<-2) means overlapped rule */
- else overlapRule6=-ret;
}
break; /* case IPV46DUAL end */
case IPV4ONLY:
/* open IPv4 gate */
- if((ret=OpenClientGate4(clientAddr4, userid, macAddr4, userProperty))==0){
+ ret=OpenClientGate4(clientAddr4, userid, macAddr4, userProperty);
+ if(ret==0 || ret<-2){ /* normally open or duplicated open */
/* open success */
err_msg("OPEN: user %s from %s at %s", userid, clientAddr4, macAddr4);
/* create new address list. head and tail pointer point the same item. */
pLastClientAddr=pClientAddr
=CreateAddrListItem(clientAddr4,ruleNumber4,IPV4);
+
+ /* save dupliacted rule */
+ if(ret<-2) duplicateRule4=-ret;
}
/* open fail */
PutClientMsg("Error: Please contact to the administrator");
return FALSE;
}
-
- /* other case (ret<-2) means overlapped rule */
- else overlapRule4=-ret;
-
break; /* case IPV4ONLY end */
/***** if client have IPv6 only, do below ******/
case IPV6ONLY:
/* open IPv6 gate */
- if((ret=OpenClientGate6(clientAddr6, userid, macAddr6, userProperty))==0){
+ ret=OpenClientGate6(clientAddr6, userid, macAddr6, userProperty);
+ if(ret==0 || ret<-2){ /* normally open or duplicated open */
/* open success */
err_msg("OPEN: user %s from %s at %s", userid, clientAddr6, macAddr6);
/* create new address list. head and tail pointer point the same item. */
pLastClientAddr=pClientAddr
=CreateAddrListItem(clientAddr6,ruleNumber6,IPV6);
+
+ /* save dupliacted rule */
+ if(ret<-2) duplicateRule6=-ret;
}
/* open fail */
PutClientMsg("Error: Please contact to the administrator");
return FALSE;
}
-
- /* other case (ret<-2) means overlapped rule */
- else overlapRule6=-ret;
-
break; /* case IPv6ONLY end */
default:
} /* switch end */
- /* if overlapped rules exist, remove them */
- if(overlapRule4>0 || overlapRule6>0){
+ /* if duplicated rules exist, ignore */
+ if(duplicateRule4>0 || duplicateRule6>0){
- /* to cope to modification of IPv4 addr in Dual stack(send as http param)*/
+ /* to cope to modification of IPv4 addr in Dual stack(send as http param) */
if(ipStatus==IPV46DUAL && IsSameMacAddr(macAddr4, macAddr6)==FALSE){
err_msg("ERR at %s#%d: arp and ndp return different mac addr",
__FILE__,__LINE__);
PutClientMsg("Error. Please End Web and Retry. ");
-
- }else{
-
- /* ipfw rule is deleted and the process is killed */
- RemoveOverlapRule(overlapRule4,overlapRule6);
- KillOverlapProcess(overlapRule4,overlapRule6,clientAddr4,clientAddr6);
+ return FALSE;
- err_msg("INFO: user %s forces to close overlapped client", userid);
- PutClientMsg("Network is closed. Please End Web and Retry. ");
+ }else{
+ return TRUE;
}
- return FALSE;
}
return TRUE;
}
/*************************************************/
-/* remove overlapped firewall rule for same addr */
+/* remove duplicated firewall rule for same addr */
/*************************************************/
-void removeOverlapRule(int overlapRule4, int overlapRule6)
+void removeDuplicateRule(int duplicateRule4, int duplicateRule6)
{
char ruleNumStr[WORDMAXLN];
/* if ipfw rule exist, delete it */
- if(overlapRule4>0){
- snprintf(ruleNumStr,WORDMAXLN,"%d",overlapRule4);
+ if(duplicateRule4>0){
+ snprintf(ruleNumStr,WORDMAXLN,"%d",duplicateRule4);
DelIpfwRule(ruleNumStr);
}
/* if ip6fw rule exist, delete it */
- if(overlapRule6>0){
- snprintf(ruleNumStr,WORDMAXLN,"%d",overlapRule6);
+ if(duplicateRule6>0){
+ snprintf(ruleNumStr,WORDMAXLN,"%d",duplicateRule6);
DelIp6fwRule(ruleNumStr);
}
}
-/*************************************************/
-/* kill overlapped process */
-/*************************************************/
-void killOverlapProcess(int overlapRule4, int overlapRule6, char *clientAddr4, char *clientAddr6){
-
- FILE *fpipe;
- char buff[BUFFMAXLN];
- char cgiNamePattern[WORDMAXLN];
- char addr4Pattern[ADDRMAXLN]="*dummy*";
- char addr6Pattern[ADDRMAXLN]="*dummy*";
- int procNumber=0;
- char procNumStr[WORDMAXLN];
-
- /* make cgi name pattern in ps title */
- snprintf(cgiNamePattern,WORDMAXLN," %s: ", GetConfValue("MainCgi"));
-
- /* make cgi param pattern in ps title */
- if(overlapRule4>0){
- snprintf(addr4Pattern,ADDRMAXLN,"[%s(%d)]", clientAddr4, overlapRule4);
- }
- if(overlapRule6>0){
- snprintf(addr6Pattern,ADDRMAXLN,"[%s(%d)]", clientAddr6, overlapRule6);
- }
-
- /* search process corresponding to the overlap rule */
- /* opengate.cgi process shows the following title line for ps command */
- /* "123 ... opengatesrv.cgi: ..,[123.4.5.6(10000)],[2001:1:1:1::1(10000)]..." */
-
- /* exec "ps -axww" */
- if((fpipe=Popenl(1, "r", GetConfValue("PsPath"), "-axww", (char *)0)) == NULL){
- err_msg("ERR at %s#%d: exec ps ax error",__FILE__,__LINE__);
- }
-
- /* read "ps -axww" output as follows */
- while(fgets(buff, BUFFMAXLN, fpipe)!=NULL){
-
- /* if opengatesrv cgi corresponding to overlap rule */
- if(strstr(buff, cgiNamePattern)!=NULL &&
- ( strstr(buff, addr4Pattern)!=NULL ||
- strstr(buff, addr6Pattern)!=NULL ) ){
-
- /* get the process number */
- sscanf(buff, "%d", &procNumber);
-
- /* kill the process */
- snprintf(procNumStr, WORDMAXLN, "%d", procNumber);
- if(Systeml(1, "kill", procNumStr, (char *)0) != 0){
- err_msg("ERR at %s#%d: exec kill error",__FILE__,__LINE__);
- }
- }
- }
-
- /* close pipe */
- Pclose(fpipe);
-}
-
/**************************/
/* make address list */
/**************************/
return ret;
}
-void RemoveOverlapRule(int overlapRule4, int overlapRule6){
-
- if(debug>1) err_msg("DEBUG:=>removeOverlapRule(%d,%d)",overlapRule4,overlapRule6);
- removeOverlapRule(overlapRule4,overlapRule6);
- if(debug>1) err_msg("DEBUG:<=removeOverlapRule( )");
-}
+void RemoveDuplicateRule(int duplicateRule4, int duplicateRule6){
-void KillOverlapProcess(int overlapRule4, int overlapRule6,
- char *clientAddr4, char *clientAddr6){
- if(debug>1) err_msg("DEBUG:=>killOverlapProcess(%d,%d,%s,%s)",
- overlapRule4,overlapRule6,clientAddr4,clientAddr6);
- killOverlapProcess(overlapRule4,overlapRule6,clientAddr4,clientAddr6);
- if(debug>1) err_msg("DEBUG:<=killOverlapProcess( )");
+ if(debug>1) err_msg("DEBUG:=>removeDuplicateRule(%d,%d)",duplicateRule4,duplicateRule6);
+ removeDuplicateRule(duplicateRule4,duplicateRule6);
+ if(debug>1) err_msg("DEBUG:<=removeDuplicateRule( )");
}
-
int GetPacketCount(struct clientAddr *pClientAddr)
{
int ret;
time_t timeIn, timeOut;
int ipStatus; /* flag for IPV4ONLY,IPV6ONLY or IPV46DUAL */
int connectionMode; /* client connect mode */
-char *mode[3]={"NONE","HTTP","TIME"};
+char *mode[4]={"NONE","HTTP","TIME", "NONE"};
/* variable to measuring processing time (in msec) */
struct timeval timeBeginCgi, timeBeginWait, timeConnect, timeDisconnect;
int authNum=1; /* present authserver number to check user */
int cookieAuth=FALSE; /* Auth with HTTP-Cookie is passed */
int isUidInEnv=FALSE; /* userid is included in environment (shibb/basic) */
+ char closeTime[WORDMAXLN]; /* session closing time ('-'=not close) */
/* drop root privilege */
seteuid(getuid());
/* if cookie auth is enabled. */
if( (*GetConfValue("EnableCookieAuth")!='0') ){
cookieAuth=GetCookieData(userid, clientAddr4,
- &duration,&durationEntered,language);
+ &duration,&durationEntered,language,closeTime);
+ }
+
+ /* if already opened, exit */
+ if(cookieAuth && closeTime[0]=='-'){
+ PutClientMsg("Already opened. Please close this page and retry.");
+ return 0;
}
/* split user@server to user and server */
hour=time/60/60;
min=(time-hour*60*60)/60;
sec=(time-hour*60*60-min*60);
- //err_msg("STOP: user %s at %s ( %02d:%02d:%02d )", userid, macAddr4, hour,min,sec);
+ // err_msg("STOP: user %s at %s ( %02d:%02d:%02d )", userid, macAddr4, hour,min,sec);
return;
}
/*****************************/
void closeExit(int signo)
{
- /* save the connect mode */
- logConnectMode();
-
/* write closing information to database */
PutSessionEndToDb(cookie, mode[connectionMode]);
/* signal is disabled */
Signal(SIGTERM, SIG_DFL);
- /* close firewalls */
- while(pClientAddr!=NULL){
+ /* ignore redundant process */
+ if(connectionMode!=DUPLICATED){
+
+ /* save the connect mode */
+ logConnectMode();
- if(pClientAddr->ipType==IPV4){
- CloseClientGate4(pClientAddr,userid,macAddr4);
- }else{
- CloseClientGate6(pClientAddr,userid,macAddr6);
- DeleteNdpEntry(pClientAddr->ipAddr);
+ /* close firewalls */
+ while(pClientAddr!=NULL){
+
+ if(pClientAddr->ipType==IPV4){
+
+ CloseClientGate4(pClientAddr,userid,macAddr4);
+ }else{
+
+ CloseClientGate6(pClientAddr,userid,macAddr6);
+ DeleteNdpEntry(pClientAddr->ipAddr);
+ }
+ pClientAddr = pClientAddr->next;
}
- pClientAddr = pClientAddr->next;
+
+ /* put out time */
+ timeOut=time(NULL);
+ PutCloseMsg(timeOut,timeIn);
}
- /* put out time */
- timeOut=time(NULL);
- PutCloseMsg(timeOut,timeIn);
if(debug>1) err_msg("DEBUG:terminated");
exit(1);
{
long time1sec,time2sec,time3sec;
long time1usec,time2usec,time3usec;
+ int conMode=0;
/* set value on failure */
- if(connectionMode<0 || connectionMode>2) connectionMode=NOCONNECT;
- if(connectionMode==NOCONNECT){
+ conMode=connectionMode;
+ if(connectionMode<0 || connectionMode>2) conMode=NOCONNECT;
+ if(conMode==NOCONNECT){
gettimeofday(&timeBeginWait, NULL) ;
gettimeofday(&timeConnect, NULL) ;
}
}
if(debug>0) err_msg("INFO: user=%s watchmode=%s procsec=%ld.%06ld,%ld.%06ld,%ld.%06ld ipversion=%d useragent=%s",
- userid, mode[connectionMode],
+ userid, mode[conMode],
time1sec,time1usec,
time2sec,time2usec,
time3sec,time3usec,
#define NOCONNECT 0 /* the client is not connected yet. */
#define HTTPCONNECT 1 /* the client is connected by HTTP Keep-Alive */
#define ENDCONNECT 2 /* the client is now terminating */
+#define DUPLICATED 3 /* the client is duplicated */
#define IPV4ONLY 4
#define IPV46DUAL 46
int OpenClientGate(char *clientAddr4, char *macAddr4, char *clientAddr6, char *macAddr6, char *userid, char *userProperty, int ipStatus);
void DelIpfwRule(char *ruleNumber);
void DelIp6fwRule(char *ruleNumber);
+void RemoveDuplicateRule(int duplicateRule4, int duplicateRule6);
/* ndp and arp control */
void DeleteNdpEntry(char *clientAddr6);
/* cgi interface */
void GetClientAddr(char *clientAddr);
int GetPostData(char *userid, char *password, char *clientAddr4, int *durationPtr, int *durationEntered,char *language, char *redirectedUrl);
-int GetCookieData(char *userid, char *clientAddr4, int *durationPtr, int *durationEntered,char *language);
+int GetCookieData(char *userid, char *clientAddr4, int *durationPtr, int *durationEntered,char *language, char* closeTime);
int GetAuthCookie(char *cookie, char *userid);
void SplitId(char* userid, char* useridshort, char* extraId);
int CheckReferer(void);
int duration, int durationEntered, int cookieAuth,
char *language);
int PutSessionEndToDb(char* cookie, char* watchMode);
+int FixProcessEndInDb(int pid, char* watchMode);
int GetSessionInfoFromDb(char* cookie, char* userid, char* clientAddr4,
- char *macAddr, int *duration, int *durationEntered, char *language);
+ char *macAddr, int *duration, int *durationEntered,
+ char *language, char* closeTime);
int GetUserProperty(char *userid, char *userProperty);
int CheckNatInsertion(char* macAddr4, char* macAddr6, char* userid);
+int FindDuplicateInDbAndClose(char* clientAddr4, int* redundantRule4,
+ int* redundantRule6, int* redundantPid );
/* TCP communication with client */
int GetListenPort(void);
char clientAddr4[ADDRMAXLN];
char macAddr[ADDRMAXLN];
char language[WORDMAXLN];
+ char closeTime[WORDMAXLN];
int duration;
int durationEntered;
char *pErrMsg;
sqlite3 *db;
sqlite3_stmt *stmt;
-
printf("This is a test program for accessing sqlite db\n");
/* get data from db */
GetSessionInfoFromDb("testcookie", userid,
clientAddr4, macAddr,
- &duration, &durationEntered, language);
+ &duration, &durationEntered, language, closeTime);
/* dump getting data */
printf("%s, %s, %s, %d, %d, %s\n", userid, clientAddr4, macAddr,
void OnCheckHttpAlarm(int signo);
void OnReadWaitAlarm(int signo);
void OnAjaxWaitAlarm(int signo);
+void CheckBasic(void);
+void CheckHttp(void);
+
extern char ruleNumber4[WORDMAXLN]; /* ipfw rule number in string form */
extern char ruleNumber6[WORDMAXLN]; /* ip6fw rule number in string form */
int sendHelloTime=0; /* the time of sending hello */
int noReplyCount=0; /* count up the no reply to hello message */
+int checkBasicAlarmRinged=FALSE;
+int checkHttpAlarmRinged=FALSE;
+
/***************************************/
/* get temp listen port of this server */
/* start alarms */
EnableAlarm();
- /* connection wait. retry at abnormal */
- if((connfd = SelectAccept()) < 0 ){
+ /* connection wait */
+ connfd = SelectAccept();
+
+ /* stop alarms*/
+ DisableAlarm();
+
+ /* if abnormal accept check interupt */
+ if(connfd<0){
+
+ /* periodic check */
+ if(checkBasicAlarmRinged) CheckBasic();
+
Close(connfd);
continue;
}
- /* at normal connection */
- /* stop alarm interupt between checking */
- DisableAlarm();
-
/* is it from the correct client addr(the check is skipped for IPv6) */
if(ipType==IPV4 && ipStatus!=IPV6ONLY){
GetPeerAddr(connfd, connectAddr);
connectMode=NOCONNECT;
}
- /***************************************/
+/***************************************/
/* called at periodic alive basic check */
/***************************************/
void onCheckBasicAlarm(int signo)
{
+ checkBasicAlarmRinged=TRUE;
+}
+
+/***************************************/
+/* called at periodic alive basic check */
+/***************************************/
+void checkBasic(void)
+{
static int packetCountPrev=0; /* packet count at previous check */
int packetCountNow=0; /* packet count at now */
- static int noPacketPeriod=0; /* no packet period count in check loop */
+ static int noPacketPeriod=0; /* no packet period count in check loop */
+ static int firstCheck=TRUE;
+ int duplicateRule4,duplicateRule6;
+ int otherPid;
/* search new IPv6 addresses */
ScanNdpEntry(alarmArg.pClientAddr, alarmArg.userid,
connectMode=ENDCONNECT;
return;
}
+
+ /* duplicated session check */
+ if(firstCheck){
+ firstCheck=FALSE;
+ if( FindDuplicateInDbAndClose(alarmArg.clientAddr4,
+ &duplicateRule4, &duplicateRule6, &otherPid) ){
+ if(kill(otherPid, 0)==0){ /* the process exists */
+ RemoveDuplicateRule(duplicateRule4, duplicateRule6);
+ connectMode=DUPLICATED;
+ }else{ /* the process does not exist */
+ FixProcessEndInDb(otherPid, "NONE");
+ }
+ }
+ }
+
/* set the alarm for next periodic keep alive check */
+ checkBasicAlarmRinged=FALSE;
AddAlarm("CheckBasicAlarm", alarmArg.checkInterval, FALSE, OnCheckBasicAlarm); /* EnableAlarm is called automatically in alarm function */
}
else{
/*abnormal read */
/* some alarm is ringed or connecion is closed */
- /* connectionMode might be modified in onAlarm */
+
+ /* periodic check */
+ if(checkHttpAlarmRinged) CheckHttp();
+
+ /* if no connection, retry connect */
if(connectMode==NOCONNECT){
/* wait short time to accept reconnection */
/***************************************/
void onCheckHttpAlarm(int signo)
{
+ checkHttpAlarmRinged=TRUE;
+}
+
+/***************************************/
+/* called at periodic http alive check */
+/***************************************/
+void checkHttp(void)
+{
/* at this timing, hello request might be received */
/* if in hello wait mode, it is abnormal */
if(helloWait==TRUE){
}
/* set the alarm for next periodic check */
+ checkHttpAlarmRinged=FALSE;
AddAlarm("CheckHttpAlarm", alarmArg.checkInterval, FALSE, OnCheckHttpAlarm);
/* EnableAlarm is called automatically in alarm function */
Writefmt(connfd,"\r\n");
}
+
+
/***************************************************/
/***************************************************/
void GetPeerAddr(int sockfd, char *peerAddr)
if(debug>1) err_msg("DEBUG:<=onCheckBasicAlarm()");
}
+void CheckBasic(void){
+
+ if(debug>1) err_msg("DEBUG:=>checkBasic()");
+ checkBasic();
+ if(debug>1) err_msg("DEBUG:<=checkBasic()");
+}
+
void OnCheckHttpAlarm(int signo){
if(debug>1) err_msg("DEBUG:=>onCheckHttpAlarm()");
if(debug>1) err_msg("DEBUG:<=onCheckHttpAlarm()");
}
+void CheckHttp(void){
+
+ if(debug>1) err_msg("DEBUG:=>checkHttp()");
+ checkHttp();
+ if(debug>1) err_msg("DEBUG:<=checkHttp()");
+}
+
void OnReadWaitAlarm(int signo){
if(debug>1) err_msg("DEBUG:=>onReadWaitAlarm()");
sendHttpNotFound();
if(debug>1) err_msg("DEBUG:<=sendHttpNotFound()");
}
+