Crossfire Server, Trunk
ban.c
Go to the documentation of this file.
1 
7 #include "global.h"
8 
9 #include <ctype.h>
10 #include <errno.h>
11 #include <stdio.h>
12 #include <string.h>
13 
14 #include "sproto.h"
15 
16 #ifndef WIN32 /* ---win32 : remove unix headers */
17 #include <sys/ioctl.h>
18 #include <sys/file.h>
19 #endif /* win32 */
20 
32 int checkbanned(const char *login, const char *host) {
33  FILE *bannedfile;
34  char buf[MAX_BUF];
35  char log_buf0[160], host_buf[64], line_buf[160];
36  char *indexpos;
37  int num1;
38  int hits = 0; /* Hits==2 means we're banned */
39  int loop;
40 
41  /* Inverse ban feature: if a line is prefixed by a ~, then we will
42  * immediately return "check passed" if it matches. This allow to ban a
43  * network, but let a part of it still connect.
44  */
45  int inverse_ban = 0;
46 
47  for (loop = 0; loop < 2; loop++) { /* have to check both ban files now */
48  /* First time through look for BANFILE */
49 
50  if (loop == 0) {
51  snprintf(buf, sizeof(buf), "%s/%s", settings.confdir, BANFILE);
52  bannedfile = fopen(buf, "r");
53  if (bannedfile == NULL) {
54  LOG(llevDebug, "Could not find file Banned file\n");
55  continue;
56  }
57  }
58 
59  /* Second time through look for BANISHFILE */
60 
61  if (loop == 1) {
62  snprintf(buf, sizeof(buf), "%s/%s", settings.localdir, BANISHFILE);
63  bannedfile = fopen(buf, "r");
64  if (bannedfile == NULL) {
65  LOG(llevDebug, "Could not find file Banish file\n");
66  return(0);
67  }
68  }
69 
70  /* Do the actual work here checking for banned IPs */
71 
72  while (fgets(line_buf, 160, bannedfile) != NULL) {
73  char *log_buf = log_buf0;
74 
75  inverse_ban = 0;
76  hits = 0;
77 
78  /* Split line up */
79  if (*line_buf == '#' || *line_buf == '\n')
80  continue;
81 
82  indexpos = strrchr(line_buf, '@');
83  if (indexpos == NULL) {
84  LOG(llevDebug, "Bad line in banned file\n");
85  continue;
86  }
87 
88  /* copy login name into log_buf */
89  num1 = indexpos-line_buf;
90  strncpy(log_buf, line_buf, num1);
91  log_buf[num1] = '\0';
92 
93  /* copy host name into host_buf */
94  strncpy(host_buf, indexpos+1, sizeof(host_buf)-1);
95  host_buf[sizeof(host_buf)-1] = '\0';
96 
97  /* Cut off any extra spaces on the host buffer */
98  indexpos = host_buf;
99  while (!isspace(*indexpos)) {
100  indexpos++;
101  }
102  *indexpos = '\0';
103 
104  if (*log_buf == '~') {
105  log_buf++;
106  inverse_ban = 1;
107  }
108 
109  /*
110  LOG(llevDebug, "Login: <%s>; host: <%s>\n", login, host);
111  LOG(llevDebug, " Checking Banned <%s> and <%s>.\n", log_buf, host_buf);
112  */
113 
114  if (*log_buf == '*')
115  hits = 1;
116  else if (login != NULL && strcmp(login, log_buf) == 0)
117  hits = 1;
118 
119  if (hits == 1) {
120  if (*host_buf == '*') { /* Lock out any host */
121  hits++;
122 
123  /* break out now. otherwise hits will get reset to one */
124  break;
125  } else if (strstr(host, host_buf) != NULL) { /* Lock out subdomains (eg, "*@usc.edu" */
126  hits++;
127 
128  /* break out now. otherwise hits will get reset to one */
129  break;
130  } else if (strcmp(host, host_buf) == 0) { /* Lock out specific host */
131  hits++;
132 
133  /* break out now. otherwise hits will get reset to one */
134  break;
135  }
136  }
137  } /* loop for one file */
138 
139  fclose(bannedfile);
140 
141  if (hits >= 2) {
142  return(!inverse_ban);
143  }
144  }
145 
146  return(0);
147 }
global.h
settings
struct Settings settings
Definition: init.c:39
checkbanned
int checkbanned(const char *login, const char *host)
Definition: ban.c:32
Settings::confdir
const char * confdir
Definition: global.h:242
sproto.h
MAX_BUF
#define MAX_BUF
Definition: define.h:35
BANISHFILE
#define BANISHFILE
Definition: config.h:512
LOG
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.c:51
buf
StringBuffer * buf
Definition: readable.c:1610
llevDebug
@ llevDebug
Definition: logger.h:13
BANFILE
#define BANFILE
Definition: config.h:347
Settings::localdir
const char * localdir
Definition: global.h:244