Crossfire Server, Branch 1.12
R12190
|
00001 /* 00002 * static char *rcsid_ban_c = 00003 * "$Id: ban.c 11578 2009-02-23 22:02:27Z lalo $"; 00004 */ 00005 00012 #include <global.h> 00013 #include <sproto.h> 00014 #ifndef WIN32 /* ---win32 : remove unix headers */ 00015 #include <sys/ioctl.h> 00016 #endif /* win32 */ 00017 #ifdef hpux 00018 #include <sys/ptyio.h> 00019 #endif 00020 00021 #ifndef WIN32 /* ---win32 : remove unix headers */ 00022 #include <errno.h> 00023 #include <stdio.h> 00024 #include <sys/file.h> 00025 #endif /* win32 */ 00026 00038 int checkbanned(const char *login, const char *host) { 00039 FILE *bannedfile; 00040 char buf[MAX_BUF]; 00041 char log_buf0[160], host_buf[64], line_buf[160]; 00042 char *indexpos; 00043 int num1; 00044 int hits = 0; /* Hits==2 means we're banned */ 00045 int loop; 00046 00047 /* Inverse ban feature: if a line is prefixed by a ~, then we will 00048 * immediately return "check passed" if it matches. This allow to ban a 00049 * network, but let a part of it still connect. 00050 */ 00051 int inverse_ban = 0; 00052 00053 for (loop = 0; loop < 2; loop++) { /* have to check both ban files now */ 00054 00055 /* First time through look for BANFILE */ 00056 00057 if (loop == 0) { 00058 snprintf(buf, sizeof(buf), "%s/%s", settings.confdir, BANFILE); 00059 bannedfile = fopen(buf, "r"); 00060 if (bannedfile == NULL) { 00061 LOG(llevDebug, "Could not find file Banned file\n"); 00062 continue; 00063 } 00064 } 00065 00066 /* Second time through look for BANISHFILE */ 00067 00068 if (loop == 1) { 00069 snprintf(buf, sizeof(buf), "%s/%s", settings.localdir, BANISHFILE); 00070 bannedfile = fopen(buf, "r"); 00071 if (bannedfile == NULL) { 00072 LOG(llevDebug, "Could not find file Banish file\n"); 00073 return(0); 00074 } 00075 } 00076 00077 /* Do the actual work here checking for banned IPs */ 00078 00079 while (fgets(line_buf, 160, bannedfile) != NULL) { 00080 char *log_buf = log_buf0; 00081 00082 inverse_ban = 0; 00083 hits = 0; 00084 00085 /* Split line up */ 00086 if (*line_buf == '#' || *line_buf == '\n') 00087 continue; 00088 00089 indexpos = strrchr(line_buf, '@'); 00090 if (indexpos == NULL) { 00091 LOG(llevDebug, "Bad line in banned file\n"); 00092 continue; 00093 } 00094 00095 /* copy login name into log_buf */ 00096 num1 = indexpos-line_buf; 00097 strncpy(log_buf, line_buf, num1); 00098 log_buf[num1] = '\0'; 00099 00100 /* copy host name into host_buf */ 00101 strncpy(host_buf, indexpos+1, sizeof(host_buf)-1); 00102 host_buf[sizeof(host_buf)-1] = '\0'; 00103 00104 /* Cut off any extra spaces on the host buffer */ 00105 indexpos = host_buf; 00106 while (!isspace(*indexpos)) { 00107 indexpos++; 00108 } 00109 *indexpos = '\0'; 00110 00111 if (*log_buf == '~') { 00112 log_buf++; 00113 inverse_ban = 1; 00114 } 00115 00116 /* 00117 LOG(llevDebug, "Login: <%s>; host: <%s>\n", login, host); 00118 LOG(llevDebug, " Checking Banned <%s> and <%s>.\n", log_buf, host_buf); 00119 */ 00120 00121 if (*log_buf == '*') 00122 hits = 1; 00123 else if (login != NULL && strcmp(login, log_buf) == 0) 00124 hits = 1; 00125 00126 if (hits == 1) { 00127 if (*host_buf == '*') { /* Lock out any host */ 00128 hits++; 00129 00130 /* break out now. otherwise hits will get reset to one */ 00131 break; 00132 } else if (strstr(host, host_buf) != NULL) { /* Lock out subdomains (eg, "*@usc.edu" */ 00133 hits++; 00134 00135 /* break out now. otherwise hits will get reset to one */ 00136 break; 00137 } else if (strcmp(host, host_buf) == 0) { /* Lock out specific host */ 00138 hits++; 00139 00140 /* break out now. otherwise hits will get reset to one */ 00141 break; 00142 } 00143 } 00144 } /* loop for one file */ 00145 00146 fclose(bannedfile); 00147 00148 if (hits >= 2) { 00149 return(!inverse_ban); 00150 } 00151 00152 } 00153 00154 return(0); 00155 }