1 /*
2 * Part of Very Secure FTPd
3 * Licence: GPL v2
4 * Author: Dmitriy Balashov
5 * usersip.c
6 */
7
8 #include "usersip.h"
9 #include "tunables.h"
10 #include "str.h"
11 #include "filestr.h"
12 #include "sysutil.h"
13 #include "session.h"
14 #include "defs.h"
15 #include "logging.h"
16 #include "utility.h"
17 #include "charconv.h"
18
19 static void parse_rules(struct mystr* p_rule_str);
20
21 static ip_rules rules_list = 0;
22
23 void
vsf_userip_load(const char * p_filename)24 vsf_userip_load(const char* p_filename)
25 {
26 struct mystr rules_file_str = INIT_MYSTR;
27 struct mystr rule_setting_str = INIT_MYSTR;
28 int retval;
29 unsigned int str_pos = 0;
30
31 retval = str_fileread(&rules_file_str, p_filename, VSFTP_CONF_FILE_MAX);
32 if (vsf_sysutil_retval_is_error(retval))
33 {
34 return;
35 }
36
37 while (str_getline(&rules_file_str, &rule_setting_str, &str_pos))
38 {
39 if (str_isempty(&rule_setting_str) ||
40 str_get_char_at(&rule_setting_str, 0) == '#')
41 {
42 continue;
43 }
44 parse_rules(&rule_setting_str);
45 }
46
47 str_free(&rules_file_str);
48 if (!str_isempty(&rule_setting_str))
49 {
50 str_free(&rule_setting_str);
51 }
52
53 if (rules_list) {
54 while (rules_list->prev)
55 {
56 rules_list = rules_list->prev;
57 }
58 }
59 }
60
61 int
vsf_userip_check(const struct mystr * p_user,struct vsf_session * p_sess)62 vsf_userip_check(const struct mystr* p_user,
63 struct vsf_session* p_sess)
64 {
65 int accept_login = (tunable_users_access_ip_deny == 1) ? 0 : 1;
66 static ip_rules rules;
67
68 if (!rules_list)
69 {
70 return(1);
71 }
72
73 rules = rules_list;
74
75 do
76 {
77 if (str_equal(p_user, &rules->p_user))
78 {
79 accept_login = 0;
80 if (vsf_sysutil_sockaddr_in_mask(p_sess->p_remote_addr,
81 rules->remote_ip,
82 rules->remote_mask))
83 {
84 p_sess->remote_charset = rules->codepage;
85 return (1);
86 }
87 }
88 rules = rules->next;
89 }
90 while (rules);
91
92 return (accept_login);
93 }
94
95 void
vsf_userip_free()96 vsf_userip_free()
97 {
98 if (rules_list)
99 {
100 do
101 {
102 str_free(&rules_list->p_user);
103 vsf_sysutil_sockaddr_clear(&rules_list->remote_ip);
104 vsf_sysutil_sockaddr_clear(&rules_list->remote_mask);
105
106 if (rules_list->next)
107 {
108 rules_list = rules_list->next;
109 vsf_sysutil_free (rules_list->prev);
110 } else
111 {
112 vsf_sysutil_free (rules_list);
113 rules_list = 0;
114 }
115 }
116 while (rules_list);
117 }
118 }
119
120 static void
parse_rules(struct mystr * p_rule_str)121 parse_rules(struct mystr* p_rule_str)
122 {
123 static struct mystr s_lhs_chunk_str;
124 static struct mystr s_rhs_chunk_str;
125 static struct mystr login;
126 static struct str_locate_result locate;
127 static struct mystr s_ip;
128 static struct vsf_sysutil_sockaddr *addr_remote = 0;
129 static struct vsf_sysutil_sockaddr *addr_mask = 0;
130 int codepage = 0;
131
132 str_replace_char(p_rule_str, '\t', ' ');
133 str_trim_char(p_rule_str, ' ');
134
135 str_copy(&s_lhs_chunk_str, p_rule_str);
136 str_split_char(&s_lhs_chunk_str, &s_rhs_chunk_str, ' '); // Get user login
137 str_copy(&login, &s_lhs_chunk_str);
138
139 str_copy(&s_lhs_chunk_str, &s_rhs_chunk_str);
140 str_split_char(&s_lhs_chunk_str, &s_rhs_chunk_str, ' '); // Get user codepage
141 codepage = vsf_charconv_codepage(str_getbuf(&s_lhs_chunk_str));
142 if (codepage == 0)
143 {
144 codepage = vsf_charconv_codepage(tunable_remote_charset);
145 str_append_char(&s_lhs_chunk_str, ' ');
146 str_append_str(&s_lhs_chunk_str, &s_rhs_chunk_str);
147 str_copy(&s_rhs_chunk_str, &s_lhs_chunk_str);
148 }
149
150 do
151 {
152 if (!addr_remote)
153 {
154 if (tunable_listen_ipv6)
155 {
156 vsf_sysutil_sockaddr_alloc_ipv6(&addr_mask);
157 vsf_sysutil_sockaddr_alloc_ipv6(&addr_remote);
158 }
159 else
160 {
161 vsf_sysutil_sockaddr_alloc_ipv4(&addr_mask);
162 vsf_sysutil_sockaddr_alloc_ipv4(&addr_remote);
163 }
164 }
165
166 str_copy(&s_lhs_chunk_str, &s_rhs_chunk_str);
167 str_split_char(&s_lhs_chunk_str, &s_rhs_chunk_str, ' ');
168
169 locate = str_locate_char(&s_lhs_chunk_str, '/');
170 if (locate.found == 1)
171 {
172 str_copy(&s_ip, &s_lhs_chunk_str);
173 str_split_char(&s_ip, &s_lhs_chunk_str, '/');
174 str_append_char(&s_ip, '\0');
175 if (vsf_sysutil_inet_aton(str_getbuf(&s_ip), addr_remote) != 0)
176 {
177 if (vsf_sysutil_inet_aton(str_getbuf(&s_lhs_chunk_str), addr_mask) == 0)
178 {
179 vsf_sysutil_sockaddr_set_mask(addr_mask, str_atoi(&s_lhs_chunk_str));
180 }
181 }
182 else
183 {
184 continue;
185 }
186 }
187 else
188 {
189 str_append_char(&s_lhs_chunk_str, '\0');
190 if (vsf_sysutil_inet_aton(str_getbuf(&s_lhs_chunk_str), addr_remote) != 0)
191 {
192 vsf_sysutil_sockaddr_set_mask(addr_mask, ((tunable_listen_ipv6) ? 128 : 32));
193 }
194 else
195 {
196 continue;
197 }
198 }
199
200 if (!rules_list)
201 {
202 rules_list = vsf_sysutil_malloc(sizeof(ip_rule));
203 vsf_sysutil_fillbuff(rules_list, sizeof(ip_rule), 0);
204 }
205 else
206 {
207 rules_list->next = vsf_sysutil_malloc(sizeof(ip_rule));
208 vsf_sysutil_fillbuff(rules_list->next, sizeof(ip_rule), 0);
209 rules_list->next->prev = rules_list;
210 rules_list = rules_list->next;
211 }
212 rules_list->remote_ip = addr_remote;
213 rules_list->remote_mask = addr_mask;
214 rules_list->codepage = codepage;
215 str_copy (&rules_list->p_user, &login);
216 addr_remote = 0;
217 addr_mask = 0;
218 }
219 while (!str_isempty(&s_rhs_chunk_str));
220
221 if (addr_remote)
222 {
223 vsf_sysutil_sockaddr_clear(&addr_remote);
224 vsf_sysutil_sockaddr_clear(&addr_mask);
225 }
226
227 str_free(&s_lhs_chunk_str);
228 str_free(&s_rhs_chunk_str);
229 str_free(&login);
230 str_free(&s_ip);
231 }
232
233