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