Crossfire Server, Branch 1.12  R12190
ban.c
Go to the documentation of this file.
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 }