1 #include "ml-tcpserver.h"
2 #include "motorconst.h"
8 #include "util_const.h"
9 #include "util_check.h"
10 #include "util_string.h"
19 ==dbtcpserver module==
22 static uregex re_iprange ("^[0-9]{1,3}\\.([0-9]{1,3}\\.([0-9]{1,3}\\.([0-9]{1,3})?)?)?$");
23 static uregex re_domainrange ("^\\.?[a-zA-Z0-9][a-zA-Z0-9\\-]*(\\.[a-zA-Z0-9][a-zA-Z0-9\\-]*)*$");
25 void MLDbTcpserver::setPath (const ustring& name) {
26 dbpath = mlenv->env->path_to_auth (name);
27 dbpath.append (CharConst (kEXT_HASH));
30 void MLDbTcpserver::opendb () {
31 db.open (dbpath.c_str ());
32 flock (db.db->fd (db.db), LOCK_EX);
35 void MLDbTcpserver::closedb () {
37 flock (db.db->fd (db.db), LOCK_UN);
42 void MLDbTcpserver::addAllow (const ustring& key, time_t span, MNode* rest, MlEnv* mlenv) {
50 val.append (CharConst ("\xff\xff\xff\xff")).append ((const char*)(&span), sizeof (time_t));
54 estr = eval_str (rest->car (), mlenv);
56 // if (! checkASCII (estr) || estr.length () > 1024)
57 if (! matchASCII (estr.begin (), estr.end ()) || estr.length () > 1024)
58 throw (estr + uErrorBadValue);
59 val.append (CharConst ("+")).append (estr).append (1, 0);
65 void MLDbTcpserver::addDeny (const ustring& key) {
68 val.assign (CharConst ("D\x00"));
72 void MLDbTcpserver::del (const ustring& key) {
76 bool MLDbTcpserver::splitRec (const ustring& rec, bool& allow, time_t& limit, MNodeList& estr) {
85 } else if (matchHead (b, e, CharConst ("D\x00"))) {
89 } else if (matchSkip (b, e, CharConst ("\xff\xff\xff\xff"))) {
90 if (e - b >= sizeof (time_t)) {
92 memcpy ((void*)&limit, &*b, sizeof (time_t));
104 if (splitChar (b, e, '\x00', m)) {
105 estr.append (newMNode_str (new ustring (b, m)));
114 bool MLDbTcpserver::splitRec (const ustring& rec, bool& allow, time_t& limit) {
123 } else if (matchHead (b, e, CharConst ("D\x00"))) {
127 } else if (matchSkip (b, e, CharConst ("\xff\xff\xff\xff"))) {
128 if (e - b >= sizeof (time_t)) {
130 memcpy ((void*)&limit, &*b, sizeof (time_t));
131 b += sizeof (time_t);
141 ($dbtcpserver NAME [SUBFUNCTION...])
142 DJBのucspi-tcp拡張版のBerkeleyDBアクセス制御データベースのハンドリング。
145 //#MFUNC $dbtcpserver ml_dbtcpserver cMLDbTcpserverID
146 MNode* ml_dbtcpserver (MNode* cell, MlEnv* mlenv) {
147 MNode* arg = cell->cdr ();
148 MLDbTcpserver obj (mlenv);
153 throw (uErrorWrongNumber);
155 name = eval_str (arg->car (), mlenv);
158 if (name.size () == 0)
159 throw (uErrorFilenameEmpty);
160 if (! matchName (name))
161 throw (name + uErrorBadName);
166 mlenv->setMStack (&obj);
168 ans = progn (arg, mlenv);
169 mlenv->stopBreak (cell->car ());
173 return ans.release ();
177 ===subfunctions of $dbtcpserver===
182 (add-allow-ip IP SPAN ENV...) -> NIL
183 IPアドレス,アドレスレンジをキーにしたallow行を追加する。
184 ドットで終わる4オクテット未満のアドレスを指定すると,アドレスレンジ指定となる。
185 SPANが0以上の時,登録時からSPAN秒後までの間,レコードが有効になる。
186 環境変数指定を「名前=値」の形式で指定する。環境変数指定は複数指定できる。
188 ====add-allow-host====
189 (add-allow-host DOMAIN SPAN ENV...) -> NIL
190 ホスト名,ドメイン名をキーにしたallow行を追加する。
191 ドットで始まるドメイン名を指定すると,ドメイン全体の指定となる。
192 SPANが0以上の時,登録時からSPAN病後までの間,レコードが有効になる。
193 環境変数指定を「名前=値」の形式で指定する。環境変数指定は複数指定できる。
196 (add-deny-ip IP) -> NIL
197 IPアドレス,アドレスレンジをキーにしたdeny行を追加する。
198 ドットで終わる4オクテット未満のアドレスを指定すると,アドレスレンジ指定となる。
200 ====add-deny-host====
201 (add-deny-host DOMAIN) -> NIL
202 ホスト名,ドメイン名をキーにしたdeny行を追加する。
203 ドットで始まるドメイン名を指定すると,ドメイン全体の指定となる。
206 (delete-ip IP) -> NIL
207 IPアドレスをキーとして登録したレコードを削除する。
211 ドメイン名をキーとして登録したレコードを削除する。
214 (read-ip IP) -> (["allow" | "deny"] TIME ENV_LIST)
215 IPアドレスをキーとしてレコードを読み取る。
216 レコードの期限が指定されているものは,期限の時刻のUNIX timeが返される。
220 (read-host DOMAIN) -> (["allow" | "deny"] TIME ENV_LIST)
221 ドメイン名をキーとしてレコードを読み取る。
222 レコードの期限が指定されているものは,期限の時刻のUNIX timeが返される。
226 (dump-ip) -> (IP PERM_LIST TIME_LIST ENV_LIST)
227 IPアドレスをキーとした全レコードをリストで返す。
228 空文字列のキーのレコードは,dump-ip関数の戻り値に含まれる。
231 (dump-host) -> (DOMAIN PERM_LIST TIME_LIST ENV_LIST)
232 ドメイン名をキーとしたレコードをリストで返す。
236 有効期限指定のあるレコードで,期限を過ぎたレコードを削除する。
240 //#SFUNC add-allow-ip ml_dbtcpserver_add_allow_ip $dbtcpserver
241 MNode* ml_dbtcpserver_add_allow_ip (MNode* cell, MlEnv* mlenv, MLFunc* mobj) {
242 MNode* arg = cell->cdr ();
243 MLDbTcpserver* obj = MObjRef<MLDbTcpserver> (mobj, cMLDbTcpserverID);
244 std::vector<MNode*> params;
249 setParams (arg, 2, ¶ms, NULL, NULL, &rest);
250 ip = eval_str (params[0], mlenv);
251 span = eval_int (params[1], mlenv);
252 if (ip.length () > 0 && ! checkRe (ip, re_iprange))
253 throw (ip + uErrorBadValue);
255 obj->addAllow (ip, span, rest, mlenv);
260 //#SFUNC add-allow-host ml_dbtcpserver_add_allow_host $dbtcpserver
261 MNode* ml_dbtcpserver_add_allow_host (MNode* cell, MlEnv* mlenv, MLFunc* mobj) {
262 MNode* arg = cell->cdr ();
263 MLDbTcpserver* obj = MObjRef<MLDbTcpserver> (mobj, cMLDbTcpserverID);
264 std::vector<MNode*> params;
269 setParams (arg, 2, ¶ms, NULL, NULL, &rest);
270 host = eval_str (params[0], mlenv);
271 span = eval_int (params[1], mlenv);
272 if (host.length () > 0 && ! checkRe (host, re_domainrange))
273 throw (host + uErrorBadValue);
275 if (host.length () > 0)
276 host = ustring (CharConst ("=")).append (host);
277 obj->addAllow (host, span, rest, mlenv);
282 //#SFUNC add-deny-ip ml_dbtcpserver_add_deny_ip $dbtcpserver
283 MNode* ml_dbtcpserver_add_deny_ip (MNode* cell, MlEnv* mlenv, MLFunc* mobj) {
284 MNode* arg = cell->cdr ();
285 MLDbTcpserver* obj = MObjRef<MLDbTcpserver> (mobj, cMLDbTcpserverID);
286 std::vector<MNode*> params;
289 setParams (arg, 1, ¶ms, NULL, NULL, NULL);
290 ip = eval_str (params[0], mlenv);
291 if (ip.length () > 0 && ! checkRe (ip, re_iprange))
292 throw (ip + uErrorBadValue);
299 //#SFUNC add-deny-host ml_dbtcpserver_add_deny_host $dbtcpserver
300 MNode* ml_dbtcpserver_add_deny_host (MNode* cell, MlEnv* mlenv, MLFunc* mobj) {
301 MNode* arg = cell->cdr ();
302 MLDbTcpserver* obj = MObjRef<MLDbTcpserver> (mobj, cMLDbTcpserverID);
303 std::vector<MNode*> params;
306 setParams (arg, 1, ¶ms, NULL, NULL, NULL);
307 host = eval_str (params[0], mlenv);
308 if (host.length () > 0 && ! checkRe (host, re_domainrange))
309 throw (host + uErrorBadValue);
311 if (host.length () > 0)
312 host = ustring (CharConst ("=")).append (host);
318 //#SFUNC delete-ip ml_dbtcpserver_delete_ip $dbtcpserver
319 MNode* ml_dbtcpserver_delete_ip (MNode* cell, MlEnv* mlenv, MLFunc* mobj) {
320 MNode* arg = cell->cdr ();
321 MLDbTcpserver* obj = MObjRef<MLDbTcpserver> (mobj, cMLDbTcpserverID);
322 std::vector<MNode*> params;
325 setParams (arg, 1, ¶ms, NULL, NULL, NULL);
326 ip = eval_str (params[0], mlenv);
327 if (ip.length () > 0 && ! checkRe (ip, re_iprange))
328 throw (ip + uErrorBadValue);
335 //#SFUNC delete-host ml_dbtcpserver_delete_host $dbtcpserver
336 MNode* ml_dbtcpserver_delete_host (MNode* cell, MlEnv* mlenv, MLFunc* mobj) {
337 MNode* arg = cell->cdr ();
338 MLDbTcpserver* obj = MObjRef<MLDbTcpserver> (mobj, cMLDbTcpserverID);
339 std::vector<MNode*> params;
342 setParams (arg, 1, ¶ms, NULL, NULL, NULL);
343 host = eval_str (params[0], mlenv);
344 if (host.length () > 0 && ! checkRe (host, re_domainrange))
345 throw (host + uErrorBadValue);
347 if (host.length () > 0)
348 host = ustring (CharConst ("=")).append (host);
354 static MNode* accessRec (MLDbTcpserver* obj, const ustring& key) {
360 if (obj->db.get (key, val)) {
361 if (obj->splitRec (val, allow, limit, estr)) {
364 ans.append (newMNode_str (new ustring (CharConst ("allow"))));
366 ans.append (newMNode_str (new ustring (CharConst ("deny"))));
368 ans.append (newMNode_num (limit));
369 ans.append (estr.release ());
370 return ans.release ();
376 static void accessRec (MLDbTcpserver* obj, const ustring& key, const ustring& val, MNodeList& lkey, MNodeList& lallow, MNodeList& llimit, MNodeList& lestr) {
381 if (obj->splitRec (val, allow, limit, estr)) {
382 lkey.append (newMNode_str (new ustring (key)));
384 lallow.append (newMNode_str (new ustring (CharConst ("allow"))));
386 lallow.append (newMNode_str (new ustring (CharConst ("deny"))));
388 llimit.append (newMNode_num (limit));
389 lestr.append (estr.release ());
393 //#SFUNC read-ip ml_dbtcpserver_read_ip $dbtcpserver
394 MNode* ml_dbtcpserver_read_ip (MNode* cell, MlEnv* mlenv, MLFunc* mobj) {
395 MNode* arg = cell->cdr ();
396 MLDbTcpserver* obj = MObjRef<MLDbTcpserver> (mobj, cMLDbTcpserverID);
397 std::vector<MNode*> params;
400 setParams (arg, 1, ¶ms, NULL, NULL, NULL);
401 ip = eval_str (params[0], mlenv);
402 if (ip.length () > 0 && ! checkRe (ip, re_iprange))
403 throw (ip + uErrorBadValue);
405 return accessRec (obj, ip);
408 //#SFUNC read-host ml_dbtcpserver_read_host $dbtcpserver
409 MNode* ml_dbtcpserver_read_host (MNode* cell, MlEnv* mlenv, MLFunc* mobj) {
410 MNode* arg = cell->cdr ();
411 MLDbTcpserver* obj = MObjRef<MLDbTcpserver> (mobj, cMLDbTcpserverID);
412 std::vector<MNode*> params;
415 setParams (arg, 1, ¶ms, NULL, NULL, NULL);
416 host = eval_str (params[0], mlenv);
417 if (host.length () > 0 && ! checkRe (host, re_domainrange))
418 throw (host + uErrorBadValue);
420 if (host.length () > 0)
421 host = ustring (CharConst ("=")).append (host);
422 return accessRec (obj, host);
425 //#SFUNC dump-ip ml_dbtcpserver_dump_ip $dbtcpserver
426 MNode* ml_dbtcpserver_dump_ip (MNode* cell, MlEnv* mlenv, MLFunc* mobj) {
427 MNode* arg = cell->cdr ();
428 MLDbTcpserver* obj = MObjRef<MLDbTcpserver> (mobj, cMLDbTcpserverID);
429 MNodeList ans, lkey, lallow, llimit, lestr;
433 throw (uErrorWrongNumber);
436 while (obj->db.each (key, val)) {
437 if (key.length () > 0 && key[0] == '=') {
439 accessRec (obj, key, val, lkey, lallow, llimit, lestr);
442 ans.append (lkey.release ());
443 ans.append (lallow.release ());
444 ans.append (llimit.release ());
445 ans.append (lestr.release ());
446 return ans.release ();
449 //#SFUNC dump-host ml_dbtcpserver_dump_host $dbtcpserver
450 MNode* ml_dbtcpserver_dump_host (MNode* cell, MlEnv* mlenv, MLFunc* mobj) {
451 MNode* arg = cell->cdr ();
452 MLDbTcpserver* obj = MObjRef<MLDbTcpserver> (mobj, cMLDbTcpserverID);
453 MNodeList ans, lkey, lallow, llimit, lestr;
457 throw (uErrorWrongNumber);
460 while (obj->db.each (key, val)) {
461 if (key.length () > 0 && key[0] == '=') {
462 key.assign (key.begin () + 1, key.end ());
463 accessRec (obj, key, val, lkey, lallow, llimit, lestr);
467 ans.append (lkey.release ());
468 ans.append (lallow.release ());
469 ans.append (llimit.release ());
470 ans.append (lestr.release ());
471 return ans.release ();
474 //#SFUNC cleanup ml_dbtcpserver_cleanup $dbtcpserver
475 MNode* ml_dbtcpserver_cleanup (MNode* cell, MlEnv* mlenv, MLFunc* mobj) {
476 MNode* arg = cell->cdr ();
477 MLDbTcpserver* obj = MObjRef<MLDbTcpserver> (mobj, cMLDbTcpserverID);
479 std::vector<ustring> ary;
480 time_t now = time (NULL);
483 std::vector<ustring>::iterator b, e;
486 throw (uErrorWrongNumber);
489 while (obj->db.each (key, val)) {
490 if (obj->splitRec (val, allow, limit)) {
491 if (allow && limit > 0 && limit < now) {
500 for (; b < e; b ++) {