/* * Check your login from site is "approved" by you. * Put this in your .login. For added insurance, add ip numbers as well * (to fall back on if addr_server fails). * * 1994.05.07 [robo] created * 1994.05.11 [inspie] rewrote it to add wildcards * 1994.05.11 [robo] reformatted it, added some comments, made some changes, etc * 1994.05.13 [robo] inspie's idea to allow wildcard in suffix portion of * a specified site name; made this optional via -w * 1994.05.15 [robo] pallando's idea to test site list via -t; * some minor code changes */ #include <config.h> #include <mudlib.h> #include <logs.h> #ifndef SITECHECK_LOG #define SITECHECK_LOG "sitecheck.err" #endif inherit DAEMON; static int destruct_flag, test_flag, wildcard_flag; static string site, site_num; #define SYNTAX "Syntax: sitecheck [-dtw] site [sites...]\n" string help() { return(SYNTAX "\n" @ENDHELP This command (placed in your ~.login file) checks your login is from a site "approved" by you. Site check failures are logged, and if the "-d" option is specified, the caller's connection is dropped. For added safety: in the event addr_server is unable to resolve the caller's site (host ip/domain name), you'll want to add ip addresses (ip numbers) to the site list. If the "-w" option is given, this command will allow more liberal wildcard usage in the specified site list, eg the suffix portion of a site name, or the first three octets of an ip address. Extreme caution is advised when using this option. Examples: *.240.120.* calvin.* hobbes.* The "-t" option is for testing and overrides the "-d" switch. ENDHELP ); } /* * compare dot portions (address components) of ip number (dotted decimal/ * dotted quad) with an ip number pattern (ie containing wildcard(s)) * - returns 1 if a match, 0 otherwise */ int dot_match(string *site, string *pattern, int flag) { int i, j; j = sizeof(pattern); if (j != 4) return 0; while (j--) { if (flag) { /* * match any octect */ if (pattern[j] == "*") continue; } else { /* * be strict (last octect only) */ if (j == 3 && pattern[3] == "*") continue; } /* * component doesn't match */ if (site[j] != pattern[j]) return 0; } /* * by process of elimination...it must match */ return 1; } static int exit(int ok) { if (test_flag) { write(sprintf("Site check test %s: %s %s\n", ok ? "passed" : "failed", site ? site : "", site_num ? site_num : "")); } else { if (!ok) { /* * site not listed */ log_file(SITECHECK_LOG, sprintf("Site check failed: %s@%s [%s]\n", geteuid(previous_object()), site ? site : site_num, ctime(time()))); if (destruct_flag) { previous_object()->remove(); if (previous_object()) destruct(previous_object()); } } } return 1; } int cmd_sitecheck(string arg) { string *sites; object ob; int i, s, l1, l2; string *site_dots, *match_dots; /* * if no sites listed, just return */ if (!arg || arg == "") return 1; /* * initialize vars */ site = 0; site_num = 0; destruct_flag = 0; test_flag = 0; wildcard_flag = 0; /* * parse command line args */ arg = replace_string(arg, ",", " "); sites = explode(lower_case(arg), " "); /* * check for options */ if (sites[0][0] == '-') { if (strsrch(sites[0], 'd') != -1) destruct_flag = 1; if (strsrch(sites[0], 't') != -1) test_flag = 1; if (strsrch(sites[0], 'w') != -1) wildcard_flag = 1; } /* * check list of accepted sites */ ob = previous_object()->query_link(); if (!ob) ob = previous_object(); if (ob) { site = query_ip_name( ob ); if (!site) site = query_ip_name( previous_object() ); if (site) { /* * 1) check for perfect match */ site = lower_case(site); if (member_array(site, sites) != -1) return exit(1); /* * 2) check ip number (from ip name) */ if (sscanf(site, "%*d.%*d.%*d.%*d") != 4) { site_num = query_ip_number(ob); if (!site_num) site_num = query_ip_number(previous_object()); if (member_array(site_num, sites) != -1) return exit(1); } else { site_num = site; site = 0; } /* * LAST: loop through wildcards in sites[] * Note: sites[] is altered */ if (strsrch(arg, '*') != -1) { /* * here's a quick filter :) */ sites = regexp(sites, "\\*"); if (sites && (s = sizeof(sites))) { /* * check site ip name; * default only allows '*' as a prefix, ie "*.domain.name" */ if (site) { l1 = strlen(site); i = s; while (i--) { l2 = strlen(sites[i]) - 1; if (l2 > 1 && l1 > l2 && sites[i][0..1] == "*." && strcmp(site[l1-l2..<1], sites[i][1..<1]) == 0) return exit(1); } if (wildcard_flag) { /* * handle '*' as suffix */ i = s; while (i--) { l2 = strlen(sites[i]) - 2; if (l2 > 0 && l1 > l2 && sites[i][l2..<1] == ".*" && strcmp(site[0..l2], sites[i][0..l2]) == 0) return exit(1); } } } /* * check site ip number */ if (site_num) { site_dots = explode(site_num, "."); i = s; while (i--) { match_dots = explode(sites[i], "."); if (dot_match(site_dots, match_dots, wildcard_flag)) return exit(1); } } } } return exit(0); } } return 1; }