<?xml version="1.0"?>
-<Opengate ConfigVersion="1.4.7">
+<Opengate ConfigVersion="1.4.9">
<!-- #################################################
# ####### NEED TO MODIFY FOLLOWING PARAMETERS ##### -->
<!-- Watch client with Http Keep-Alive -->
<HttpWatch>
- <!-- HTTP 'HELLO' request interval(sec) to Keep-Alive -->
- <!-- must be smaller than keep-alive time of browsers -->
- <HelloInterval>50</HelloInterval>
-
<!-- HTTP_USER_AGENT ignoring http watch mode -->
<!-- defined by "POSIX Extended Regular Expression" -->
- <SkipAgentPattern>Safari/4</SkipAgentPattern>
+ <SkipAgentPattern>^$</SkipAgentPattern>
</HttpWatch>
<!-- Watch client with Java Applet -->
<Min>30000</Min>
<Max>60000</Max>
</ListenPort>
+
+ <!-- communication reply timeout(second) -->
+ <CommWaitTimeout>10</CommWaitTimeout>
+
+ <!-- http reconnect timeout(second) -->
+ <ReconnectTimeout>10</ReconnectTimeout>
+
+ <!-- ipfw exclusive exec lock timeout (second) -->
+ <LockTimeout>10</LockTimeout>
+
+ <!-- max delay from fwd.cgi to auth.cgi (second) -->
+ <ForwardingDelay>300</ForwardingDelay>
+
<!-- Available HTML languages (first lang is used as default) -->
<HtmlLangs>en ja</HtmlLangs>
<!-- Java Script (in opengate dir) -->
<HttpKeepJS>httpkeep.js</HttpKeepJS>
+ <Md5JS>md5.js</Md5JS>
<!-- URL used to retry -->
<ExternalUrl>http://www.google.com/</ExternalUrl>
<DD>\r
Fix small bugs and modify pages and measurement items.\r
</DD>\r
+<DT>\r
+Ver.1.4.9 at 2006.12.20</DT>\r
+<DD>\r
+Change hello timing control from client side to server side.\r
+</DD>\r
\r
</DL>\r
<b>Please see CVS in SourceForge.net to check the file difference between versions.</b>\r
<LI>\r
If java applet or http-keep script is connected, the watch process watchs the TCP connection linked to the client. \r
When the TCP connection is closed, the watch process removes the firewall rule and terminates.\r
+Thus the usage termination can be found immediately.\r
</LI>\r
\r
<LI>\r
-In java applet connection, the watch process sends 'hello' to the client every ActiveCheck/Interval seconds. \r
-When no reply to hello, the watch process removes the firewall rule and terminates. \r
-In http-keep script connection, the watch process reads 'GET /hello' and sends 'hello'. \r
-When no hello-request during ActiveCheckInterval, the watch process removes the firewall rule and terminates.\r
+To check to cut off the cable, in java applet connection, the watch process sends 'hello' to the client every ActiveCheck/Interval seconds. \r
+In http-keep script connection, the watch process reads 'GET /hello' and sends 'hello' after ActiveCheck/Interval seconds. \r
</LI>\r
\r
<LI>\r
<table bgcolor="lightyellow" border="1">
<tr><td>
-<b>Please keep this window as it is or in minimized mode.
+<b>Please keep this window 'as it is' or 'in minimized mode'.
Start browsers or other applications for network usage. </b>
Or click <a href="%%STARTURL%%" target="_blank"><b>[Start Page]</b></a>
to start browsing
<table bgcolor="lightyellow" border="1">
<tr><td>
-<b>Please keep this window as it is or in minimized mode.
+<b>Please keep this window 'as it is' or 'in minimized mode'.
Start browsers or other applications for network usage. </b>
Or click <a href="%%STARTURL%%" target="_blank"><b>[Start Page]</b></a>
to start browsing
<table bgcolor="lightyellow" border="1">
<tr><td>
<b>This page can be closed.</b> But it is recommended to save this page for termination request.
-If possible, please keep this window as it is or in minimized mode.
+If possible, please keep this window 'as it is' or 'in minimized mode'.
Start browsers or other applications for network usage.
Or click <a href="%%STARTURL%%" target="_blank"><b>[Start Page]</b></a>
to start browsing
<meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<title>Http Keep-Alive</title>
-<script type="text/JavaScript" src="http://opengate.og.saga-u.ac.jp/opengate/httpkeep.js"></script>
+<script type="text/JavaScript" src="%%HTTPKEEPJSURL%%"></script>
+<script type="text/JavaScript" src="%%MD5JSURL%%"></script>
</head>
<td align='center'>Authenticated for networt use </td>
<td align='center'>User name %%USERID%%</td>
<td align='center'>Confirmation </td>
-<td align='center'><div id="dispmsg">Starting...</div> </td>
+<td align='center'><div id="dispmsg">Started</div> </td>
</tr>
</table>
</div>
<table bgcolor="lightyellow" border="1">
<tr><td>
-<b>Please keep this window as it is or in minimized mode.
+<b>Please keep this window 'as it is' or 'in minimized mode'.
Start browsers or other applications for network usage. </b>
Or click <a href="%%STARTURL%%" target="_blank"><b>[Start Page]</b></a>
to start browsing
applet +=' <param name=lang value="%%LANGUAGE%%"> ';
applet +=' </applet> ';
- initHttpkeep(%%HTTPHELLOINTERVAL%%,"%%HTTPHELLOURL%%",applet);
+ initHttpkeep("%%HTTPHELLOURL%%",applet, "%%SESSIONID%%");
//-->
</script>
//<!--
-var checkInterval;
var httpkeepUrl;
var appletDescription;
var httpObj;
+var nextKey;
+var nowKey;
+var sessionId;
function createXMLHttpRequest() {
try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch(e) {}
return null;
}
-function onTimeout()
-{
- if(httpObj.readyState==4&&httpObj.status==200){
- sendHello();
- setTimeout('onTimeout()', checkInterval*1000);
- }
- else{
- document.getElementById("dispmsg").innerHTML = 'Error!';
- }
-}
-
function sendHello(){
// http communication
httpObj.onreadystatechange = displayResponse;
try{
- httpObj.open("GET",httpkeepUrl+Math.random(),true);
- httpObj.send(null);
+ httpObj.open("GET",httpkeepUrl+"-"+nowKey+"-"+hex_md5(nextKey+sessionId) ,true);
+ httpObj.send(null);
+ nowKey=nextKey;
+ rand=Math.random();
+ nextKey=hex_md5(String(rand));
}catch(e){
document.getElementById("watchdog").innerHTML = appletDescription;
- setTimeout('', 0);
}
-
}
+
// java communication
else{
document.getElementById("watchdog").innerHTML = appletDescription;
- setTimeout('', 0);
}
}
function displayResponse()
{
try{
- if(httpObj.readyState==4&&httpObj.status==200){
- today=new Date;
- hh=today.getHours(); mm=today.getMinutes();
- if(hh<10)hh='0'+hh; if(mm<10)mm='0'+mm;
- document.getElementById("dispmsg").innerHTML = hh+':'+mm;
- }else{
- document.getElementById("dispmsg").innerHTML = 'Waiting...';
+ if(httpObj.readyState==4){
+ if(httpObj.status==200){
+ today=new Date;
+ hh=today.getHours(); mm=today.getMinutes();
+ if(hh<10)hh='0'+hh; if(mm<10)mm='0'+mm;
+ document.getElementById("dispmsg").innerHTML = hh+':'+mm;
+ if(httpObj.responseText=="hello") sendHello();
+ }else{
+ document.getElementById("dispmsg").innerHTML = "Error!";
+ }
}
}catch(e){
document.getElementById("watchdog").innerHTML = appletDescription;
- setTimeout('onTimeout()', 0);
}
}
-function initHttpkeep(intervalArg, urlArg, appletArg)
+function initHttpkeep(urlArg, appletArg, sid)
{
// save arguments
- checkInterval = intervalArg;
httpkeepUrl=urlArg;
appletDescription=appletArg;
+ nowKey=hex_md5(sid);
+ sessionId=sid;
+ rand=Math.random();
+ nextKey=hex_md5(String(rand));
// set timeout and send hello
- setTimeout('onTimeout()', checkInterval*1000);
sendHello();
}
//-->
--- /dev/null
+<!-- without this file, the directory list might be sent -->
\ No newline at end of file
<table bgcolor="lightyellow" border="1">
<tr><td>
-<b>\e$B$3$N%Z!<%8$O!"$3$N$^$^$+Kt$O:G>/2=>uBV$K$7$F2<$5$$!#\e(B
-\e$B%M%C%H%o!<%/MxMQ$O!"JL$K%V%i%&%6$=$NB>$N%M%C%H%o!<%/MxMQ%W%m%0%i%`$r5/F0$7$F9T$C$F$/$@$5$$!#\e(B</b>
-\e$B$^$?$O!"\e(B<a href="%%STARTURL%%" target="_blank"><b>[\e$B%9%?!<%H%Z!<%8\e(B]
+<b>\e$B$3$N%Z!<%8$O!"!V$3$N$^$^!W$+Kt$O!V:G>/2=>uBV!W$K$7$F2<$5$$!#%M%C%H\e(B
+\e$B%o!<%/MxMQ$O!"JL$K%V%i%&%6$=$NB>$N%M%C%H%o!<%/MxMQ%W%m%0%i%`$r5/F0$7$F\e(B
+\e$B9T$C$F$/$@$5$$!#\e(B</b> \e$B$^$?$O!"\e(B<a href="%%STARTURL%%"
+target="_blank"><b>[\e$B%9%?!<%H%Z!<%8\e(B]
</b></a>\e$B$+$i3+;O$7$F$/$@$5$$!J%/%j%C%/$G%9%?!<%H%Z!<%8$,3+$+$J$1$l$P!"\e(B
\e$B%7%U%H%-!<$r2!$7$J$,$i%/%j%C%/$7$F$/$@$5$$!#\e(B
\e$B$^$?%]%C%W%"%C%W5v2D$K@_Dj$9$l$P<+F0E*$K%]%C%W%"%C%W$7$^$9!K!#\e(B
<table bgcolor="lightyellow" border="1">
<tr><td>
-<b>\e$B$3$N%Z!<%8$O!"$3$N$^$^$+Kt$O:G>/2=>uBV$K$7$F2<$5$$!#\e(B
-\e$B%M%C%H%o!<%/MxMQ$O!"JL$K%V%i%&%6$=$NB>$N%M%C%H%o!<%/MxMQ%W%m%0%i%`$r5/F0$7$F9T$C$F$/$@$5$$!#\e(B</b>
-\e$B$^$?$O!"\e(B<a href="%%STARTURL%%" target="_blank"><b>[\e$B%9%?!<%H%Z!<%8\e(B]
+<b>\e$B$3$N%Z!<%8$O!"!V$3$N$^$^!W$+Kt$O!V:G>/2=>uBV!W$K$7$F2<$5$$!#%M%C%H\e(B
+\e$B%o!<%/MxMQ$O!"JL$K%V%i%&%6$=$NB>$N%M%C%H%o!<%/MxMQ%W%m%0%i%`$r5/F0$7$F\e(B
+\e$B9T$C$F$/$@$5$$!#\e(B</b> \e$B$^$?$O!"\e(B<a href="%%STARTURL%%"
+target="_blank"><b>[\e$B%9%?!<%H%Z!<%8\e(B]
</b></a>\e$B$+$i3+;O$7$F$/$@$5$$!J%/%j%C%/$G%9%?!<%H%Z!<%8$,3+$+$J$1$l$P!"\e(B
\e$B%7%U%H%-!<$r2!$7$J$,$i%/%j%C%/$7$F$/$@$5$$!#\e(B
\e$B$^$?%]%C%W%"%C%W5v2D$K@_Dj$9$l$P<+F0E*$K%]%C%W%"%C%W$7$^$9!K!#\e(B
<table bgcolor="lightyellow" border="1">
<tr><td>
<b>\e$B$3$N%Z!<%8$OJD$8$F$b9=$$$^$;$s!#\e(B</b>\e$BMxMQCfCG%j%s%/$rJ];}$9$k$?$a!"\e(B
-\e$B2DG=$G$"$l$P!"$3$N%Z!<%8$O!"$3$N$^$^$+Kt$O:G>/2=>uBV$K$7$F2<$5$$!#\e(B
-\e$B%M%C%H%o!<%/MxMQ$O!"JL$K%V%i%&%6$=$NB>$N%M%C%H%o!<%/MxMQ%W%m%0%i%`$r5/F0$7$F9T$C$F$/$@$5$$!#\e(B
-\e$B$^$?$O!"\e(B<a href="%%STARTURL%%" target="_blank"><b>[\e$B%9%?!<%H%Z!<%8\e(B]
+\e$B2DG=$G$"$l$P!"$3$N%Z!<%8$O!"!V$3$N$^$^!W$+Kt$O!V:G>/2=>uBV!W$K$7$F2<$5\e(B
+\e$B$$!#%M%C%H%o!<%/MxMQ$O!"JL$K%V%i%&%6$=$NB>$N%M%C%H%o!<%/MxMQ%W%m%0%i%`\e(B
+\e$B$r5/F0$7$F9T$C$F$/$@$5$$!#$^$?$O!"\e(B<a href="%%STARTURL%%"
+target="_blank"><b>[\e$B%9%?!<%H%Z!<%8\e(B]
</b></a>\e$B$+$i3+;O$7$F$/$@$5$$!J%/%j%C%/$G%9%?!<%H%Z!<%8$,3+$+$J$1$l$P!"\e(B
\e$B%7%U%H%-!<$r2!$7$J$,$i%/%j%C%/$7$F$/$@$5$$!#\e(B
\e$B$^$?%]%C%W%"%C%W5v2D$K@_Dj$9$l$P<+F0E*$K%]%C%W%"%C%W$7$^$9!K!#\e(B
<title>Http Keep-Alive</title>
<script type="text/JavaScript" src="%%HTTPKEEPJSURL%%"></script>
+<script type="text/JavaScript" src="%%MD5JSURL%%"></script>
</head>
<td align='center'>\e$B%M%C%H%o!<%/MxMQ5v2D\e(B</td>
<td align='center'>\e$B%f!<%6L>\e(B %%USERID%%</td>
<td align='center'>\e$B@\B33NG'\e(B</td>
-<td align='center'><div id="dispmsg">\e$B3+;OCf\e(B...</div> </td>
+<td align='center'><div id="dispmsg">\e$B3+;O$7$^$7$?\e(B</div> </td>
</tr>
</table>
</div>
</p>
<hr />
-<p>\e$B>e$N\e(B2\e$BK\$N@~$N4V$K2+?'$N%P!<$,I=<($5$l$J$$>l9g$J$IF0:n$,$*$+$7$$>l9g$O!"\e(B
-<a href="%%TERMINATEURL%%"><b>\e$BMxMQCfCG\e(B</b></a>\e$B$r%/%j%C%/$7$F\e(B
-\e$B%V%i%&%6$r=*N;$7$?8e!"G'>Z%Z!<%8$K$*$$$FB>$N4F;kJ}<0$rA*Br$7$F$/$@$5$$!#\e(B
+<p>\e$B>e$N\e(B2\e$BK\$N@~$N4V$K2+?'$N%P!<$,I=<($5$l$J$+$C$?$j%M%C%H%o!<%/$,JD:?$5$l$k\e(B
+\e$B$J$IF0:n$,$*$+$7$$>l9g$O!"\e(B<a href="%%TERMINATEURL%%"><b>\e$BMxMQCfCG\e(B
+</b></a>\e$B$r%/%j%C%/$7$F%V%i%&%6$r=*N;$7$?8e!"G'>Z%Z!<%8$K$*$$$FB>$N4F;k\e(B
+\e$BJ}<0$rA*Br$7$F$/$@$5$$!#\e(B
</p>
<table bgcolor="lightyellow" border="1">
<tr><td>
-<b>\e$B$3$N%Z!<%8$O!"$3$N$^$^$+Kt$O:G>/2=>uBV$K$7$F2<$5$$!#\e(B
-\e$B%M%C%H%o!<%/MxMQ$O!"JL$K%V%i%&%6$=$NB>$N%M%C%H%o!<%/MxMQ%W%m%0%i%`$r5/F0$7$F9T$C$F$/$@$5$$!#\e(B</b>
-\e$B$^$?$O!"\e(B<a href="%%STARTURL%%" target="_blank"><b>[\e$B%9%?!<%H%Z!<%8\e(B]
+<b>\e$B$3$N%Z!<%8$O!"!V$3$N$^$^!W$+Kt$O!V:G>/2=>uBV!W$K$7$F2<$5$$!#%M%C%H\e(B
+\e$B%o!<%/MxMQ$O!"JL$K%V%i%&%6$=$NB>$N%M%C%H%o!<%/MxMQ%W%m%0%i%`$r5/F0$7$F\e(B
+\e$B9T$C$F$/$@$5$$!#\e(B</b> \e$B$^$?$O!"\e(B<a href="%%STARTURL%%"
+target="_blank"><b>[\e$B%9%?!<%H%Z!<%8\e(B]
</b></a>\e$B$+$i3+;O$7$F$/$@$5$$!J%/%j%C%/$G%9%?!<%H%Z!<%8$,3+$+$J$1$l$P!"\e(B
\e$B%7%U%H%-!<$r2!$7$J$,$i%/%j%C%/$7$F$/$@$5$$!#\e(B
\e$B$^$?%]%C%W%"%C%W5v2D$K@_Dj$9$l$P<+F0E*$K%]%C%W%"%C%W$7$^$9!K!#\e(B
applet +=' <param name=lang value="%%LANGUAGE%%"> ';
applet +=' </applet> ';
- initHttpkeep(%%HTTPHELLOINTERVAL%%,"%%HTTPHELLOURL%%",applet);
+ initHttpkeep("%%HTTPHELLOURL%%",applet,"%%SESSIONID%%");
//-->
</script>
<TITLE>OpengateStart</TITLE>
</HEAD>
<BODY>
-Opengate\e$B$K$h$k!V%M%C%H%o!<%/MxMQG'>Z!W$N%Z!<%8$X<+F00\F0$7$^$9!#\e(B
+Opengate\e$B$K$h$k!V%M%C%H%o!<%/MxMQ<TG'>Z!W$N%Z!<%8$X<+F00\F0$7$^$9!#\e(B
<P>
\e$B<+F00\F0$G$-$J$$J}$O$3$A$i$r%/%j%C%/$7$F2<$5$$!#\e(B
<P>
--- /dev/null
+/*
+ * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
+ * Digest Algorithm, as defined in RFC 1321.
+ * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.
+ * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
+ * Distributed under the BSD License
+ * See http://pajhome.org.uk/crypt/md5 for more info.
+ */
+
+/*
+ * Configurable variables. You may need to tweak these to be compatible with
+ * the server-side, but the defaults work in most cases.
+ */
+var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */
+var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */
+var chrsz = 8; /* bits per input character. 8 - ASCII; 16 - Unicode */
+
+/*
+ * These are the functions you'll usually want to call
+ * They take string arguments and return either hex or base-64 encoded strings
+ */
+function hex_md5(s){ return binl2hex(core_md5(str2binl(s), s.length * chrsz));}
+function b64_md5(s){ return binl2b64(core_md5(str2binl(s), s.length * chrsz));}
+function str_md5(s){ return binl2str(core_md5(str2binl(s), s.length * chrsz));}
+function hex_hmac_md5(key, data) { return binl2hex(core_hmac_md5(key, data)); }
+function b64_hmac_md5(key, data) { return binl2b64(core_hmac_md5(key, data)); }
+function str_hmac_md5(key, data) { return binl2str(core_hmac_md5(key, data)); }
+
+/*
+ * Perform a simple self-test to see if the VM is working
+ */
+function md5_vm_test()
+{
+ return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72";
+}
+
+/*
+ * Calculate the MD5 of an array of little-endian words, and a bit length
+ */
+function core_md5(x, len)
+{
+ /* append padding */
+ x[len >> 5] |= 0x80 << ((len) % 32);
+ x[(((len + 64) >>> 9) << 4) + 14] = len;
+
+ var a = 1732584193;
+ var b = -271733879;
+ var c = -1732584194;
+ var d = 271733878;
+
+ for(var i = 0; i < x.length; i += 16)
+ {
+ var olda = a;
+ var oldb = b;
+ var oldc = c;
+ var oldd = d;
+
+ a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);
+ d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);
+ c = md5_ff(c, d, a, b, x[i+ 2], 17, 606105819);
+ b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);
+ a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);
+ d = md5_ff(d, a, b, c, x[i+ 5], 12, 1200080426);
+ c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);
+ b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);
+ a = md5_ff(a, b, c, d, x[i+ 8], 7 , 1770035416);
+ d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);
+ c = md5_ff(c, d, a, b, x[i+10], 17, -42063);
+ b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);
+ a = md5_ff(a, b, c, d, x[i+12], 7 , 1804603682);
+ d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);
+ c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);
+ b = md5_ff(b, c, d, a, x[i+15], 22, 1236535329);
+
+ a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);
+ d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
+ c = md5_gg(c, d, a, b, x[i+11], 14, 643717713);
+ b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);
+ a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);
+ d = md5_gg(d, a, b, c, x[i+10], 9 , 38016083);
+ c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);
+ b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
+ a = md5_gg(a, b, c, d, x[i+ 9], 5 , 568446438);
+ d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);
+ c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);
+ b = md5_gg(b, c, d, a, x[i+ 8], 20, 1163531501);
+ a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);
+ d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);
+ c = md5_gg(c, d, a, b, x[i+ 7], 14, 1735328473);
+ b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);
+
+ a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);
+ d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
+ c = md5_hh(c, d, a, b, x[i+11], 16, 1839030562);
+ b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);
+ a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
+ d = md5_hh(d, a, b, c, x[i+ 4], 11, 1272893353);
+ c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);
+ b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);
+ a = md5_hh(a, b, c, d, x[i+13], 4 , 681279174);
+ d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);
+ c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);
+ b = md5_hh(b, c, d, a, x[i+ 6], 23, 76029189);
+ a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);
+ d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);
+ c = md5_hh(c, d, a, b, x[i+15], 16, 530742520);
+ b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);
+
+ a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);
+ d = md5_ii(d, a, b, c, x[i+ 7], 10, 1126891415);
+ c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);
+ b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);
+ a = md5_ii(a, b, c, d, x[i+12], 6 , 1700485571);
+ d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);
+ c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);
+ b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);
+ a = md5_ii(a, b, c, d, x[i+ 8], 6 , 1873313359);
+ d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);
+ c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);
+ b = md5_ii(b, c, d, a, x[i+13], 21, 1309151649);
+ a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);
+ d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);
+ c = md5_ii(c, d, a, b, x[i+ 2], 15, 718787259);
+ b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);
+
+ a = safe_add(a, olda);
+ b = safe_add(b, oldb);
+ c = safe_add(c, oldc);
+ d = safe_add(d, oldd);
+ }
+ return Array(a, b, c, d);
+
+}
+
+/*
+ * These functions implement the four basic operations the algorithm uses.
+ */
+function md5_cmn(q, a, b, x, s, t)
+{
+ return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b);
+}
+function md5_ff(a, b, c, d, x, s, t)
+{
+ return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
+}
+function md5_gg(a, b, c, d, x, s, t)
+{
+ return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
+}
+function md5_hh(a, b, c, d, x, s, t)
+{
+ return md5_cmn(b ^ c ^ d, a, b, x, s, t);
+}
+function md5_ii(a, b, c, d, x, s, t)
+{
+ return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
+}
+
+/*
+ * Calculate the HMAC-MD5, of a key and some data
+ */
+function core_hmac_md5(key, data)
+{
+ var bkey = str2binl(key);
+ if(bkey.length > 16) bkey = core_md5(bkey, key.length * chrsz);
+
+ var ipad = Array(16), opad = Array(16);
+ for(var i = 0; i < 16; i++)
+ {
+ ipad[i] = bkey[i] ^ 0x36363636;
+ opad[i] = bkey[i] ^ 0x5C5C5C5C;
+ }
+
+ var hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz);
+ return core_md5(opad.concat(hash), 512 + 128);
+}
+
+/*
+ * Add integers, wrapping at 2^32. This uses 16-bit operations internally
+ * to work around bugs in some JS interpreters.
+ */
+function safe_add(x, y)
+{
+ var lsw = (x & 0xFFFF) + (y & 0xFFFF);
+ var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
+ return (msw << 16) | (lsw & 0xFFFF);
+}
+
+/*
+ * Bitwise rotate a 32-bit number to the left.
+ */
+function bit_rol(num, cnt)
+{
+ return (num << cnt) | (num >>> (32 - cnt));
+}
+
+/*
+ * Convert a string to an array of little-endian words
+ * If chrsz is ASCII, characters >255 have their hi-byte silently ignored.
+ */
+function str2binl(str)
+{
+ var bin = Array();
+ var mask = (1 << chrsz) - 1;
+ for(var i = 0; i < str.length * chrsz; i += chrsz)
+ bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (i%32);
+ return bin;
+}
+
+/*
+ * Convert an array of little-endian words to a string
+ */
+function binl2str(bin)
+{
+ var str = "";
+ var mask = (1 << chrsz) - 1;
+ for(var i = 0; i < bin.length * 32; i += chrsz)
+ str += String.fromCharCode((bin[i>>5] >>> (i % 32)) & mask);
+ return str;
+}
+
+/*
+ * Convert an array of little-endian words to a hex string.
+ */
+function binl2hex(binarray)
+{
+ var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
+ var str = "";
+ for(var i = 0; i < binarray.length * 4; i++)
+ {
+ str += hex_tab.charAt((binarray[i>>2] >> ((i%4)*8+4)) & 0xF) +
+ hex_tab.charAt((binarray[i>>2] >> ((i%4)*8 )) & 0xF);
+ }
+ return str;
+}
+
+/*
+ * Convert an array of little-endian words to a base-64 string
+ */
+function binl2b64(binarray)
+{
+ var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+ var str = "";
+ for(var i = 0; i < binarray.length * 4; i += 3)
+ {
+ var triplet = (((binarray[i >> 2] >> 8 * ( i %4)) & 0xFF) << 16)
+ | (((binarray[i+1 >> 2] >> 8 * ((i+1)%4)) & 0xFF) << 8 )
+ | ((binarray[i+2 >> 2] >> 8 * ((i+2)%4)) & 0xFF);
+ for(var j = 0; j < 4; j++)
+ {
+ if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;
+ else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
+ }
+ }
+ return str;
+}
/* if the time difference between encode and decode is too large, retry */
diffTime = time(NULL) - encodeTiming;
- if(diffTime <0 || diffTime > MAXFWDDELAY){
+ if(diffTime <0 || diffTime > atoi(GetConfValue("ForwardingDelay"))){
illform = 1;
}
\r
/* set timeout */\r
if((defaultSigFunc=Signal(SIGALRM, sigFunc))==SIG_ERR) return 1;\r
- alarm(LOCKTIMEOUT);\r
+ alarm(atoi(GetConfValue("LockTimeout")));\r
+\r
/* lock */\r
if(Lock(fd)<0){\r
err_msg("ERR at %s#%d: lock error",__FILE__,__LINE__);\r
/* set timeout */
if((defaultSigFunc=Signal(SIGALRM, sigFunc))==SIG_ERR) return 1;
- alarm(LOCKTIMEOUT);
+ alarm(atoi(GetConfValue("LockTimeout")));
/* lock */
if(Lock(fd)<0){
#include "opengatesrv.h"
#include "../ezxml/ezxml.h"
-#define CONFIG_VERSION "1.4.7"
+#define CONFIG_VERSION "1.4.9"
#define SEPARATOR "/"
int debug=0;
else if(connectionMode==HTTPCONNECT){
/* wait until the http keep alive is closed */
- WaitHttpClose(pClientAddr, userid, userProperty, macAddr4, macAddr6, ipStatus);
+ WaitHttpClose(pClientAddr, userid, userProperty, macAddr4, macAddr6, ipStatus, sessionId, port);
}
/* close firewall and exit */
/* Configuration file for opengate */
#define CONFIGFILE "/etc/opengate/opengatesrv.conf"
-
-#define COMMWAITTIMEOUT 30 /* communication reply timeout(second) */
-#define PACKETLOGDELAY 10 /* wait log writing time(second) */
-#define LOCKTIMEOUT 10 /* ipfw exclusive exec lock timeout (second) */
-#define MAXFWDDELAY 300 /* max delay from fwd.cgi to auth.cgi (second) */
-
#define PAMSERVICENAME "opengate" /* default service name used in PAM */
#define RADIUSCONF "/etc/radius.conf" /* default path to radius.conf */
void WaitJavaClose(struct clientAddr *pClientAddr, char *userid, char *userProperty, char *macAddr4, char *macAddr6, int ipStatus);
int GetListenPort(void);
int WaitClientConnect(char *userid, char *userProperty, char *sessionId, char *clientAddr4, char *clientAddr6, int duration, char *macAddr4, char *macAddr6, int ipStatus, struct clientAddr *pClientAddr, char *language, int port, int pid);
-void WaitHttpClose(struct clientAddr *pClientAddr, char *userid, char *userProperty, char *macAddr4, char *macAddr6, int ipStatus);
+void WaitHttpClose(struct clientAddr *pClientAddr, char *userid, char *userProperty, char *macAddr4, char *macAddr6, int ipStatus, char *sessionid, int port);
/* utilities */
ssize_t readln(int fd, void *ptr, size_t maxlen);
int isNull(const char *pStr);
char *GetServicePortStr(char *servName);
void CreateSessionId(char *sessionId);
+char *md5hex(char *hexdigest, int len, char *str);
void ReFormatMacAddr(char* macAddr4, char* macAddr6);
void GetMacAddr(char *clientAddr4, char *macAddr4, char *clientAddr6, char *macAddr6, int ipStatus);
break;
case HTTPCONNECT:
- WaitHttpClose(pClientAddr, userID, "", "?", "?", 4);
+ WaitHttpClose(pClientAddr, userID, "", "?", "?", 4, "999", port);
break;
}
#include "opengatesrv.h"
-
/*************************************************/
/* formated write */
/* fd : file descriptor */
srandom(getpid()+time(NULL));
snprintf(sessionId, BUFFMAXLN, "%ld", random() );
}
+/*************************************************/
+/* calc MD5 in hex form */
+/* str: plain text to convert */
+/* hexdigest: converted hex string */
+/* prepare buff more or equal to 33chars */
+/* len: length of hexdigest buffer */
+/*************************************************/
+char *md5hex(char *hexdigest, int len, char *str)
+{
+ char unsigned digest[16];
+ char hexcode[16]="0123456789abcdef";
+ int i;
+
+ /* if not enough buffer, exit */
+ if(len<33){
+ *hexdigest='\0';
+ return hexdigest;
+ }
+
+ /* calc MD5 digest */
+ MD5(str, strlen(str), digest);
+
+ /* convert to HEX string */
+ for(i=0;i<16;i++){
+ hexdigest[2*i]=hexcode[digest[i]/16];
+ hexdigest[2*i+1]=hexcode[digest[i]%16];
+ }
+ hexdigest[2*16]='\0';
+
+ return hexdigest;
+}
/****************************************/
/****************************************/
/*************************************************
Opengate server
- module for communication with client prgram (java/javascript)
+ module for communication with client program (java/javascript)
Copyright (C) 1999 Opengate Project Team
Written by Yoshiaki Watanabe 1999-2006
void SendReplyToGetHello(void);
void SendHttpKeepPage(char *userid, char *sessionId, char *language, int port);
int SelectAccept(void);
+void AcceptHttpReConnect(void);
+int MacAddrCheck(int ipStatus,char *clientAddr4, char *clientAddr6, char *macAddr4, char *macAddr6);
+int IsRightKey(char *pNowKey, char *sessionId);
+void SendHttpReply(char *reply);
+void CheckAjaxAbility(char *buff, char *sessionId);
void OnUsageTimeLimitAlarm(int signo);
void OnCheckBasicAlarm(int signo);
int helloWait=FALSE; /* hello reply waiting mode */
int readHelloTime=0; /* the time of reading hello */
+int sendHelloTime=0; /* the time of sending hello */
int noReplyCount=0; /* count up the no reply to hello message */
}
/* set read wait alarm */
- AddAlarm("ReadWaitAlarm",COMMWAITTIMEOUT, TRUE, OnReadWaitAlarm);
+ AddAlarm("ReadWaitAlarm",atoi(GetConfValue("CommWaitTimeout")),
+ TRUE, OnReadWaitAlarm);
EnableAlarm();
/* get string from connection */
if(readln(connfd, buff, BUFFMAXLN) <0){
ReadHttpHeaders();
SendHttpKeepPage(userid, sessionId, language, port);
- /* to check the ajax ablility of the client, wait ajax request */
- AddAlarm("AjaxWaitAlarm",COMMWAITTIMEOUT, TRUE, OnAjaxWaitAlarm);
- EnableAlarm();
- /* read wait for ajax request in the connection */
- if(readln(connfd, buff, BUFFMAXLN) <0){
- /* if timeout, no ajax ability */
- connectMode=NOCONNECT;
- Close(connfd);
- continue;
- }
- /* recieve request */
- RemoveAlarm("AjaxWaitAlarm");
- ReadHttpHeaders();
+ /* to check ajax ability, wait XMLHttpRequest for a while */
+ CheckAjaxAbility(buff, sessionId);
- /* enter to the Http watch mode on the connection */
- connectMode=HTTPCONNECT;
break;
}
-
+
/* is it the terminate request */
/* the request is [GET /terminate-<pid> ..] */
snprintf(httpStr, BUFFMAXLN, "GET /terminate-%d", pid);
/* some other unknown request */
err_msg("ERR at %s#%d: unknown request [%s] sent from client",
- __FILE__,__LINE__);
+ __FILE__,__LINE__,buff);
connectMode=NOCONNECT;
Close(connfd);
+
continue;
}
/* stop all alarms */
RemoveAlarm(NULL);
-
- Close(listenfd[0]);
- Close(listenfd[1]);
-
+
return connectMode;
}
+/***************************************/
+/* check ajax ability */
+/* read hello sent by XMLhttpRequest */
+/* (reply is delayed) */
+/* check result is set in connectMode */
+/***************************************/
+void checkAjaxAbility(char *buff, char *sessionId)
+{
+
+ /* to check the ajax ablility of the client, wait ajax request */
+ AddAlarm("AjaxWaitAlarm",atoi(GetConfValue("CommWaitTimeout")),
+ TRUE, OnAjaxWaitAlarm);
+ EnableAlarm();
+
+ /* read wait for ajax request in the connection */
+ while(1){
+ if(readln(connfd, buff, BUFFMAXLN) <0){
+
+ /* if timeout, no ajax ability */
+ /* java might be connected */
+ connectMode=NOCONNECT;
+ Close(connfd);
+ break;
+ }
+
+ /* recieved normal request */
+ RemoveAlarm("AjaxWaitAlarm");
+ ReadHttpHeaders();
+
+ /* usually, hello request is recieve */
+ if(strstr(buff, "GET /hello-")==buff){
+
+ /* if received hello-key is incorrect, exit */
+ /* [GET /hello-key1-key2 ..] */
+ if( IsRightKey(buff+strlen("GET /hello-"), sessionId)==FALSE){
+ connectMode=ENDCONNECT;
+ Close(connfd);
+ break;
+ }
+
+ /* enter to the Http watch mode on the connection */
+ connectMode=HTTPCONNECT;
+ break;
+ }
+ /* or some request might be inserted. eg:[GET /favicon.ico] */
+ /* ignore it */
+ else{
+ SendHttpReply("");
+ continue;
+ }
+ }
+}
+
/****************************/
/* wait for TCP connection */
/****************************/
if(listenfd[0]>listenfd[1]) smax=listenfd[0]+1;
else smax=listenfd[1]+1;
- //if((n = select(smax, &rfd0, NULL, NULL, &timeout)) > 0){
if((n = select(smax, &rfd0, NULL, NULL, NULL)) > 0){
/* wait connection */
+
if(FD_ISSET(listenfd[0], &rfd0)){
+
if((connfd=accept(listenfd[0], (struct sockaddr *)&cliaddr, &len)) >= 0){
+
/* connect by ipv4 */
ipType=IPV4;
}
}
if(FD_ISSET(listenfd[1], &rfd0)){
+
if((connfd=accept(listenfd[1], (struct sockaddr *)&cliaddr, &len)) >= 0){
+
/* connect by ipv6 */
ipType=IPV6;
}
void onReadWaitAlarm(int signo)
{
connectMode=ENDCONNECT;
- err_msg("ERR at %s#%d: read request timeout",__FILE__,__LINE__);
}
/***************************************/
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 */
- char macAddrNow[ADDRMAXLN]; /* MAC address at now */
/* search new IPv6 addresses */
ScanNdpEntry(alarmArg.pClientAddr, alarmArg.userid,
alarmArg.macAddr6, alarmArg.userProperty);
+ /* mac address check */
+ if(MacAddrCheck(alarmArg.ipStatus,
+ alarmArg.clientAddr4, alarmArg.clientAddr6,
+ alarmArg.macAddr4, alarmArg.macAddr6)==FALSE){
+ connectMode=ENDCONNECT;
+ return;
+ }
+
/* packet flow check */
packetCountNow=GetPacketCount(alarmArg.pClientAddr);
if(packetCountNow==packetCountPrev){ /* no packet between checks */
connectMode=ENDCONNECT;
return;
}
-
- /* mac address check */
- if(alarmArg.ipStatus!=IPV6ONLY){
- GetMacAddrFromArp(alarmArg.clientAddr4, macAddrNow);
- if(strcmp(alarmArg.macAddr4, macAddrNow)!=0){
+ /* set the alarm for next periodic keep alive check */
+ AddAlarm("CheckBasicAlarm", alarmArg.checkInterval, FALSE, OnCheckBasicAlarm); /* EnableAlarm is called automatically in alarm function */
+}
+
+/***************************************/
+/* check mac address change */
+/***************************************/
+int macAddrCheck(int ipStatus, char *clientAddr4, char *clientAddr6, char *macAddr4, char *macAddr6)
+{
+ char macAddrNow[ADDRMAXLN]; /* MAC address at now */
+
+ if(ipStatus!=IPV6ONLY){
+ /* check mac address from arp */
+ GetMacAddrFromArp(clientAddr4, macAddrNow);
+ if(*macAddrNow!='?' && strcmp(macAddr4, macAddrNow)!=0){
err_msg("ERR at %s#%d: mac address is changed",__FILE__,__LINE__);
connectMode=ENDCONNECT;
- return;
+ return FALSE;
}
}else{
- GetMacAddrFromNdp(alarmArg.clientAddr6, macAddrNow);
- if(strcmp(alarmArg.macAddr6, macAddrNow)!=0){
+ /* check mac address from ndp */
+ GetMacAddrFromNdp(clientAddr6, macAddrNow);
+ if(*macAddrNow!='?' && strcmp(macAddr6, macAddrNow)!=0){
err_msg("ERR at %s#%d: mac address is changed",__FILE__,__LINE__);
connectMode=ENDCONNECT;
- return;
+ return FALSE;
}
}
-
- /* set the alarm for next periodic keep alive check */
- AddAlarm("CheckBasicAlarm", alarmArg.checkInterval, FALSE, OnCheckBasicAlarm); /* EnableAlarm is called automatically in alarm function */
+ return TRUE;
}
/***************************************/
/***************************************/
void onCheckJavaAlarm(int signo)
{
- char macAddrNow[ADDRMAXLN]; /* MAC address at now */
-
/* search new IPv6 addresses */
ScanNdpEntry(alarmArg.pClientAddr, alarmArg.userid,
alarmArg.macAddr6, alarmArg.userProperty);
helloWait=TRUE;
/* mac address check */
- if(alarmArg.ipStatus!=IPV6ONLY){
- GetMacAddrFromArp(alarmArg.clientAddr4, macAddrNow);
- if(strcmp(alarmArg.macAddr4, macAddrNow)!=0){
- err_msg("ERR at %s#%d: mac address is changed",__FILE__,__LINE__);
- connectMode=ENDCONNECT;
- return;
- }
- }else{
- GetMacAddrFromNdp(alarmArg.clientAddr6, macAddrNow);
- if(strcmp(alarmArg.macAddr6, macAddrNow)!=0){
- err_msg("ERR at %s#%d: mac address is changed",__FILE__,__LINE__);
- connectMode=ENDCONNECT;
- return;
- }
+ if(MacAddrCheck(alarmArg.ipStatus,
+ alarmArg.clientAddr4, alarmArg.clientAddr6,
+ alarmArg.macAddr4, alarmArg.macAddr6)==FALSE){
+ connectMode=ENDCONNECT;
+ return;
}
/* set the alarm for next periodic check */
/***************************************************/
/* wait for close connection of HTTP connection */
/***************************************************/
-void waitHttpClose(struct clientAddr *pClientAddr, char *userid, char *userProperty, char *macAddr4, char *macAddr6, int ipStatus)
+void waitHttpClose(struct clientAddr *pClientAddr, char *userid, char *userProperty, char *macAddr4, char *macAddr6, int ipStatus, char *sessionId, int port)
{
char buff[BUFFMAXLN];
int ret;
/* save time to read hello */
readHelloTime = time(NULL);
+ /* send first reply to hello */
SendReplyToGetHello();
+ sendHelloTime = time(NULL);
+
+ /* set the hello wait mode ON */
+ helloWait=TRUE;
/* TCP read/write loop */
/* this loop implement following logic */
EnableAlarm();
while(1){
+
/* set default to terminate */
connectMode=ENDCONNECT;
/* normal read */
connectMode=HTTPCONNECT;
- /* read [GET /terminate], then quit */
- if(strstr(buff,"GET /terminate") == buff){
- connectMode=ENDCONNECT;
- break;
- }
-
- /* read [GET /hello], then reply */
- else if(strstr(buff,"GET /hello") == buff){
+ /* read [GET /hello] */
+ if(strstr(buff,"GET /hello") == buff){
/* save time to read hello */
readHelloTime = time(NULL);
ReadHttpHeaders();
- SendReplyToGetHello();
- }
+ /* if received key is not match, exit */
+ if(IsRightKey(buff+strlen("GET /hello-"), sessionId)==FALSE){
+ connectMode=ENDCONNECT;
+ break;
+ }
+
+ /* set the hello wait mode OFF */
+ helloWait=FALSE;
+ }
+
/* read other string */
else{
}
/*abnormal read */
/* some alarm is ringed or connecion is closed */
/* connectionMode might be modified in onAlarm */
- if(connectMode==ENDCONNECT) break;
+
+ if(connectMode==ENDCONNECT){
+
+ /* wait short time to accept reconnection */
+ /* (to permit occasional disconnection at exchanging hello) */
+ if(helloWait==TRUE &&
+ (time(NULL)-sendHelloTime)<=atoi(GetConfValue("ReconnectTimeout"))){
+ AcceptHttpReConnect();
+ }
+
+ /* no reconnection, then terminate */
+ if(connectMode==ENDCONNECT){
+ break;
+ }
+ }
}
-
+
/* restart alarm */
EnableAlarm();
}
/* reset alarm */
- RemoveAlarm(NULL);
-
- /* send quit message to client */
- SendQuitClient();
+ RemoveAlarm(NULL);
Close(connfd);
return;
}
+/*************************/
+/* accept http reconnect */
+/*************************/
+void acceptHttpReConnect(void){
+
+ int startTime;
+
+ startTime=time(NULL);
+
+ /* wait a short time */
+ AddAlarm("ReadWaitAlarm",atoi(GetConfValue("ReconnectTimeout")),
+ TRUE, OnReadWaitAlarm);
+ EnableAlarm();
+
+ /* connection wait */
+ connfd = SelectAccept();
+
+ if(connfd<0){
+ /* abnormal return from selectAccept */
+ if(errno==EINTR){ /* timeout interupt */
+ err_msg("ERR at %s#%d: http reconnect timeout",
+ __FILE__,__LINE__);
+ connectMode=ENDCONNECT;
+ }else{ /* other errors */
+ err_msg("ERR: http reconnect error [%s]",strerror(errno));
+ connectMode=ENDCONNECT;
+ }
+
+ }else{
+ /* normal return from selectAccept */
+ if(debug>0)err_msg("INFO: http reconnect after %d seconds",
+ time(NULL)-startTime);
+ connectMode=HTTPCONNECT;
+ }
+
+ /* receive request */
+ RemoveAlarm("ReadWaitAlarm");
+}
+
+/*****************************************************************/
+/* Is the sent client key correct */
+/* request string is as follows */
+/* GET /hello-11111111111111111111-2222222222222222222 HTTP... */
+/* MD5digest(32chars) MD5digest(32chars) */
+/* nowKey nextKey */
+/* */
+/* client server */
+/* save sid <------------------- sid */
+/* md5(sid)+md5(md5(rand1)+sid) ---------> check nowkey */
+/* save nextKey */
+/* md5(rand1)+md5(md5(rand2)+sid)---------> check nowkey */
+/* save nextKey */
+/* md5(rand2)+md5(md5(rand3)+sid)---------> check nowkey */
+/* save nextKey */
+/*****************************************************************/
+int isRightKey(char *arg, char *sessionId)
+{
+ static char savedKey[33]=""; /* saved MD5 string */
+ char tempbuff[BUFFMAXLN]; /* work area */
+ char md5work[33] ; /* md5 work */
+ char *pNowKey;
+ char *pNextKey;
+
+ /* initial value of savedKey is md5(md5(sessionId)+sessionId) */
+ if(isNull(savedKey)){
+ md5hex(tempbuff, 33, sessionId);
+ strncat(tempbuff, sessionId, BUFFMAXLN);
+ md5hex(savedKey, 33, tempbuff);
+ }
+
+ /* split NowKey and NextKey in argument */
+ /* 32 is the length of MD5 result */
+ pNowKey=arg;
+ *(pNowKey+32)='\0';
+ pNextKey=pNowKey+33;
+ *(pNextKey+32)='\0';
+
+ /* make string [nowKey+sessionId] */
+ strncpy(tempbuff, pNowKey, BUFFMAXLN);
+ strncat(tempbuff, sessionId, BUFFMAXLN);
+
+ /* compare savedKey and md5(nowKey+sessionId) */
+ if(strcmp(savedKey, md5hex(md5work, 33, tempbuff))==0){
+
+ /* save nextKey for next check */
+ strncpy(savedKey, pNextKey, 33);
+ return TRUE;
+ }
+ else{
+ err_msg("ERR at %s#%d: incorrect client key",
+ __FILE__,__LINE__);
+ return FALSE;
+ }
+}
+
/***************************************/
/* called at periodic http alive check */
/***************************************/
void onCheckHttpAlarm(int signo)
{
- char macAddrNow[ADDRMAXLN]; /* MAC address at now */
+ /* at this timing, hello request might be received */
+ /* if in hello wait mode, it is abnormal */
+ if(helloWait==TRUE){
+ connectMode=ENDCONNECT;
+ return;
+ }
+
+ /* send delayed reply to hello request */
+ SendReplyToGetHello();
+
+ /* save time to send hello */
+ sendHelloTime = time(NULL);
+
+ /* set the hello wait mode ON */
+ helloWait=TRUE;
/* search new IPv6 addresses */
ScanNdpEntry(alarmArg.pClientAddr, alarmArg.userid,
alarmArg.macAddr6, alarmArg.userProperty);
- /* if long HTTP read waiting, then quit */
- if( (time(NULL)-readHelloTime) > alarmArg.checkInterval ){
- connectMode = ENDCONNECT;
- }else{
- connectMode = HTTPCONNECT;
- }
-
/* mac address check */
- if(alarmArg.ipStatus!=IPV6ONLY){
- GetMacAddrFromArp(alarmArg.clientAddr4, macAddrNow);
- if(strcmp(alarmArg.macAddr4, macAddrNow)!=0){
- err_msg("ERR at %s#%d: mac address is changed",__FILE__,__LINE__);
- connectMode=ENDCONNECT;
- return;
- }
- }else{
- GetMacAddrFromNdp(alarmArg.clientAddr6, macAddrNow);
- if(strcmp(alarmArg.macAddr6, macAddrNow)!=0){
- err_msg("ERR at %s#%d: mac address is changed",__FILE__,__LINE__);
- connectMode=ENDCONNECT;
- return;
- }
+ if(MacAddrCheck(alarmArg.ipStatus,
+ alarmArg.clientAddr4, alarmArg.clientAddr6,
+ alarmArg.macAddr4, alarmArg.macAddr6)==FALSE){
+ connectMode=ENDCONNECT;
+ return;
}
/* set the alarm for next periodic check */
AddAlarm("CheckHttpAlarm", alarmArg.checkInterval, FALSE, OnCheckHttpAlarm);
/* EnableAlarm is called automatically in alarm function */
+ /* normal return */
+ connectMode = HTTPCONNECT;
return;
}
char buff[BUFFMAXLN]; /* read in buffer */
FILE *fp;
char httpKeepDoc[BUFFMAXLN];
- char httpHelloInterval[WORDMAXLN];
char httpHelloUrl[BUFFMAXLN];
char terminateUrl[BUFFMAXLN];
char acceptDoc2Url[BUFFMAXLN];
char httpkeepJsUrl[BUFFMAXLN];
+ char md5JsUrl[BUFFMAXLN];
char *startPageUrl=GetConfValue("StartPage/Url");
int startPageType=atoi(GetConfValue("StartPage/Type"));
char opengateDir[BUFFMAXLN];
snprintf(httpHelloUrl, BUFFMAXLN, "http://%s:%d/hello",
GetConfValue("OpengateServerName"), port);
- /* create httphello interval [50] */
- snprintf(httpHelloInterval, WORDMAXLN, "%s", GetConfValue("HttpWatch/HelloInterval"));
-
/* create httpkeep.js url[http://<serveraddr>/opengate/httpkeep.js] */
snprintf(httpkeepJsUrl, BUFFMAXLN, "http://%s%s/%s",
GetConfValue("OpengateServerName"),
GetConfValue("OpengateDir"),GetConfValue("HttpKeepJS"));
+ /* create md5.js url[http://<serveraddr>/opengate/md5.js] */
+ snprintf(md5JsUrl, BUFFMAXLN, "http://%s%s/%s",
+ GetConfValue("OpengateServerName"),
+ GetConfValue("OpengateDir"),GetConfValue("Md5JS"));
+
/* create path to httpkeep doc */
snprintf(httpKeepDoc,BUFFMAXLN, "%s%s/%s/%s",GetConfValue("DocumentRoot"),
GetConfValue("OpengateDir"),language,GetConfValue("HttpKeepDoc"));
}
/* replace mark */
- htmlReplace(buff, "%%HTTPHELLOINTERVAL%%", httpHelloInterval);
htmlReplace(buff, "%%HTTPHELLOURL%%", httpHelloUrl);
htmlReplace(buff, "%%USERID%%", userid);
htmlReplace(buff, "%%SESSIONID%%", sessionId);
htmlReplace(buff, "%%TERMINATEURL%%", terminateUrl);
htmlReplace(buff, "%%HTTPKEEPJSURL%%", httpkeepJsUrl);
+ htmlReplace(buff, "%%MD5JSURL%%", md5JsUrl);
htmlReplace(buff, "%%OPENGATEDIR%%", opengateDir);
htmlReplace(buff, "%%OPENGATEPORT%%", portStr);
/* chunk end */
Writefmt(connfd,"0\r\n");
Writefmt(connfd,"\r\n");
+
fclose(fp);
}
+
+/*************************************************************/
+/* send reply to unknown http request eg:[GET /favico.ico..] */
+/*************************************************************/
+void sendHttpReply(char *reply)
+{
+ /* send HTTP headers */
+ Writefmt(connfd,"HTTP/1.1 200 OK\r\n");
+ Writefmt(connfd,"Transfer-Encoding: chunked\r\n");
+ Writefmt(connfd,"Keep-Alive: timeout=300\r\n");
+ Writefmt(connfd,"Connection: Keep-Alive\r\n");
+ Writefmt(connfd,"Content-Type: text/html\r\n");
+ Writefmt(connfd,"\r\n");
+
+ if(!isNull(reply)){
+ /* length of chunk in hex */
+ Writefmt(connfd, "%x\r\n", strlen(reply));
+ /* the chunk content */
+ Writefmt(connfd, "%s\r\n", reply);
+ }
+
+ /* chunk end */
+ Writefmt(connfd,"0\r\n");
+ Writefmt(connfd,"\r\n");
+}
+
/***************************************************/
/***************************************************/
void GetPeerAddr(int sockfd, char *peerAddr)
if(debug>1) err_msg("DEBUG:<=sendTerminateReply( )");
}
-void WaitHttpClose(struct clientAddr *pClientAddr, char *userid, char *userProperty, char *macAddr4, char *macAddr6, int ipStatus)
+void WaitHttpClose(struct clientAddr *pClientAddr, char *userid, char *userProperty, char *macAddr4, char *macAddr6, int ipStatus, char *sessionid, int port)
{
- if(debug>1) err_msg("DEBUG:=>waitHttpClose(%p,%s,userProperty,%s,%s,%d)",pClientAddr,userid,macAddr4,macAddr6,ipStatus);
- waitHttpClose(pClientAddr,userid,userProperty,macAddr4,macAddr6,ipStatus);
+ if(debug>1) err_msg("DEBUG:=>waitHttpClose(%p,%s,userProperty,%s,%s,%d,%s,%d)",pClientAddr,userid,macAddr4,macAddr6,ipStatus, sessionid, port);
+ waitHttpClose(pClientAddr,userid,userProperty,macAddr4,macAddr6,ipStatus, sessionid, port);
if(debug>1) err_msg("DEBUG:<=waitHttpClose( )");
}
if(debug>1) err_msg("DEBUG:=>sendReplyToGetHello( )");
sendReplyToGetHello();
if(debug>1) err_msg("DEBUG:<=sendReplyToGetHello( )");
-
}
void SendHttpKeepPage(char *userid, char *sessionId, char *language, int port)
return ret;
}
+
+void AcceptHttpReConnect(void){
+ if(debug>1) err_msg("DEBUG:=>acceptHttpReConnect()");
+ acceptHttpReConnect();
+ if(debug>1) err_msg("DEBUG:<=acceptHttpReConnect()");
+}
+
+int MacAddrCheck(int ipStatus, char *clientAddr4, char *clientAddr6, char *macAddr4, char *macAddr6) {
+ int ret;
+
+ if(debug>1) err_msg("DEBUG:=>macAddrCheck(%d,%s,%s,%s,%s)",
+ ipStatus, clientAddr4, clientAddr6, macAddr4, macAddr6);
+ ret=macAddrCheck(ipStatus, clientAddr4, clientAddr6, macAddr4, macAddr6);
+ if(debug>1) err_msg("DEBUG:(%d)<=macAddrCheck()",ret);
+
+ return ret;
+}
+
+int IsRightKey(char *pNowKey, char *sessionId){
+ int ret;
+
+ if(debug>1) err_msg("DEBUG:=>isRightKey(%s,%s)", pNowKey, sessionId);
+ ret=isRightKey(pNowKey, sessionId);
+ if(debug>1) err_msg("DEBUG:(%d)<=isRightKey()",ret);
+
+ return ret;
+}
+
+void SendHttpReply(char *reply){
+ if(debug>1) err_msg("DEBUG:=>sendHttpRepy(%s)", reply);
+ sendHttpReply(reply);
+ if(debug>1) err_msg("DEBUG:<=sendHttpReply()");
+}
+
+void CheckAjaxAbility(char *buff, char *sessionId){
+ if(debug>1) err_msg("DEBUG:=>checkAjaxAbility(%s,%s)",buff,sessionId);
+ checkAjaxAbility(buff,sessionId);
+ if(debug>1) err_msg("DEBUG:<=checkAjaxAbility()");
+}