1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
|
/*
* static char *rcsid_ban_c =
* "$Id: ban.c 5894 2007-03-25 20:41:32Z ryo_saeba $";
*/
/*
* Ban.c
* Code was grabbed from the netrek source and modified to work with
* crossfire. This function checks a file in the lib directory for any
* banned players. If it finds one it returns a 1. Wildcards can be used.
*/
#include <global.h>
#include <sproto.h>
#ifndef WIN32 /* ---win32 : remove unix headers */
#include <sys/ioctl.h>
#endif /* win32 */
#ifdef hpux
#include <sys/ptyio.h>
#endif
#ifndef WIN32 /* ---win32 : remove unix headers */
#include <errno.h>
#include <stdio.h>
#include <sys/file.h>
#endif /* win32 */
/**
* Check if a player and/or host is banned.
*
* @param login the player name to check; NULL to check only the host name
*
* @param host the host name to check
*
* @return 1=player/host is banned; 0=player/host is not banned
*/
int checkbanned(const char *login, const char *host)
{
FILE *bannedfile;
char buf[MAX_BUF];
char log_buf0[160], host_buf[64], line_buf[160];
char *indexpos;
int num1;
int hits = 0; /* Hits==2 means we're banned */
int loop;
/* Inverse ban feature: if a line is prefixed by a ~, then we will
* immediately return "check passed" if it matches. This allow to ban a
* network, but let a part of it still connect.
*/
int inverse_ban = 0;
for (loop = 0; loop < 2; loop++) { /* have to check both ban files now */
/* First time through look for BANFILE */
if (loop == 0) {
sprintf(buf, "%s/%s", settings.confdir, BANFILE);
bannedfile = fopen(buf, "r");
if (bannedfile == NULL) {
LOG(llevDebug, "Could not find file Banned file\n");
continue;
}
}
/* Second time through look for BANISHFILE */
if (loop == 1) {
sprintf(buf, "%s/%s", settings.localdir, BANISHFILE);
bannedfile = fopen(buf, "r");
if (bannedfile == NULL) {
LOG(llevDebug, "Could not find file Banish file\n");
return(0);
}
}
/* Do the actual work here checking for banned IPs */
while (fgets(line_buf, 160, bannedfile) != NULL) {
char *log_buf = log_buf0;
inverse_ban = 0;
hits = 0;
/* Split line up */
if(*line_buf == '#' || *line_buf == '\n')
continue;
indexpos = strrchr(line_buf, '@');
if (indexpos == NULL) {
LOG(llevDebug, "Bad line in banned file\n");
continue;
}
/* copy login name into log_buf */
num1 = indexpos-line_buf;
strncpy(log_buf, line_buf, num1);
log_buf[num1] = '\0';
/* copy host name into host_buf */
strncpy(host_buf, indexpos+1, sizeof(host_buf)-1);
host_buf[sizeof(host_buf)-1] = '\0';
/* Cut off any extra spaces on the host buffer */
indexpos = host_buf;
while (!isspace(*indexpos)) {
indexpos++;
}
*indexpos = '\0';
if (*log_buf == '~') {
log_buf++;
inverse_ban = 1;
}
/*
LOG(llevDebug, "Login: <%s>; host: <%s>\n", login, host);
LOG(llevDebug, " Checking Banned <%s> and <%s>.\n", log_buf, host_buf);
*/
if(*log_buf=='*')
hits = 1;
else if (login != NULL && strcmp(login, log_buf) == 0)
hits = 1;
if (hits == 1) {
if (*host_buf == '*') { /* Lock out any host */
hits++;
/* break out now. otherwise hits will get reset to one */
break;
}
else if (strstr(host, host_buf) != NULL) { /* Lock out subdomains (eg, "*@usc.edu" */
hits++;
/* break out now. otherwise hits will get reset to one */
break;
}
else if (strcmp(host, host_buf) == 0) { /* Lock out specific host */
hits++;
/* break out now. otherwise hits will get reset to one */
break;
}
}
} /* loop for one file */
fclose(bannedfile);
if (hits >= 2) {
return(!inverse_ban);
}
}
return(0);
}
|