• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/router/lighttpd-1.4.39/src/
1#include "base.h"
2#include "log.h"
3#include "buffer.h"
4#include "response.h"
5
6#include "plugin.h"
7
8#include "stream.h"
9#include "stat_cache.h"
10
11#include "sys-mmap.h"
12////////////////////////////////
13
14#include <sys/types.h>
15#include <sys/stat.h>
16#include <ctype.h>
17#include <stdlib.h>
18#include <string.h>
19#include <errno.h>
20#include <fcntl.h>
21#include <stdio.h>
22#include <assert.h>
23#include <pthread.h>
24#include <signal.h>
25#include <sys/time.h>
26
27#include <unistd.h>
28#include <dirent.h>
29#include <libsmbclient.h>
30#include <dlinklist.h>
31#include "mod_smbdav.h"
32
33#define DBE 0
34
35#ifndef EMBEDDED_EANBLE
36char* g_is_webdav_block = "0";
37#endif
38
39#if defined(HAVE_LIBXML_H) && defined(HAVE_SQLITE3_H)
40#include <sqlite3.h>
41#endif
42
43int do_account_authentication(const char *username, const char *password){
44
45	char *nvram_acc_list;
46
47#if EMBEDDED_EANBLE
48	char *a = nvram_get_acc_list();
49	if(a==NULL) return -1;
50	int l = strlen(a);
51	nvram_acc_list = (char*)malloc(l+1);
52	strncpy(nvram_acc_list, a, l);
53	nvram_acc_list[l] = '\0';
54	#ifdef APP_IPKG
55	free(a);
56	#endif
57#else
58	int i = 100;
59	nvram_acc_list = (char*)malloc(100);
60	strcpy(nvram_acc_list, "admin>admin<jerry>jerry");
61#endif
62
63	int account_right = -1;
64
65	char * pch;
66	pch = strtok(nvram_acc_list, "<>");
67
68	buffer* buffer_acc_name = buffer_init();
69	buffer* buffer_acc_pass = buffer_init();
70
71	while(pch!=NULL){
72		char *name;
73		char *pass;
74		int len;
75
76		//- User Name
77		len = strlen(pch);
78		name = (char*)malloc(len+1);
79		strncpy(name, pch, len);
80		name[len] = '\0';
81		buffer_copy_string(buffer_acc_name, name);
82		buffer_urldecode_path(buffer_acc_name);
83		free(name);
84
85		//- User Password
86		pch = strtok(NULL,"<>");
87		len = strlen(pch);
88		pass = (char*)malloc(len+1);
89		strncpy(pass, pch, len);
90		pass[len] = '\0';
91		buffer_copy_string(buffer_acc_pass, pass);
92		buffer_urldecode_path(buffer_acc_pass);
93		free(pass);
94
95		if( buffer_is_equal_string(buffer_acc_name, username, strlen(username)) &&
96			buffer_is_equal_string(buffer_acc_pass, password, strlen(password)) ){
97
98			//- pass
99			account_right = 1;
100
101			break;
102		}
103
104		pch = strtok(NULL,"<>");
105	}
106
107	buffer_free(buffer_acc_name);
108	buffer_free(buffer_acc_pass);
109	free(nvram_acc_list);
110
111	aicloud_acc_info_t* c = NULL;
112	for (c = aicloud_acc_info_list; c; c = c->next) {
113		if( buffer_is_equal_string(c->username, username, strlen(username)) &&
114			buffer_is_equal_string(c->password, password, strlen(password)) ){
115
116			//- pass
117			account_right = 1;
118
119			break;
120		}
121	}
122
123	#if 0
124	int jffs_supported = is_jffs_supported();
125	if(jffs_supported==1){
126
127		char *err;
128		char sql_query[2048] = "\0";
129		sqlite3 *sql_aicloud;
130		char **result;
131		int rows;
132		int column_count;
133		char* aicloud_db_file_path = get_aicloud_db_file_path();
134
135		if (SQLITE_OK == sqlite3_open(aicloud_db_file_path, &(sql_aicloud))) {
136			//- check if account is existed.
137			sprintf(sql_query, "SELECT COUNT(*) AS count FROM account_info WHERE username='%s' AND password='%s'", username, password);
138			if( sql_get_table(sql_aicloud, sql_query, &result, &rows, NULL) == SQLITE_OK ){
139				Cdbg(DBE, "sql_query=%s, rows=%d", sql_query, rows);
140
141				int count = 0;
142				int i=0;
143				column_count = 1;
144
145				for( i=column_count; i<=rows*column_count; i+=column_count ){
146					count = atoi(result[i]);
147				}
148
149				sqlite3_free_table(result);
150
151				if(count==1){
152					//- pass
153					account_right = 1;
154				}
155			}
156
157			if (sql_aicloud) {
158				sqlite3_close(sql_aicloud);
159			}
160		}
161	}
162	#endif
163
164	return account_right;
165}
166
167handler_t basic_authentication_handler(server *srv, connection *con, plugin_data *p)
168{
169	data_string *ds_auth = (data_string *)array_get_element(con->request.headers, "Authorization");
170	data_string *ds_useragent = (data_string *)array_get_element(con->request.headers, "user-Agent");
171
172	buffer *user = buffer_init();
173	buffer *pass = buffer_init();
174	buffer_copy_string(user, " ");
175	buffer_copy_string(pass, " ");
176
177	int get_account_from_smb_info = 0;
178	char *auth_username = NULL;
179	char *auth_password = NULL;
180	if( smbc_parser_basic_authentication(srv, con, &auth_username, &auth_password) != 1 ){
181
182		if(con->smb_info==NULL)
183			goto error_401;
184
185		if( con->smb_info->username->used && con->smb_info->password->used ){
186			buffer_copy_buffer(user, con->smb_info->username);
187			buffer_copy_buffer(pass, con->smb_info->password);
188			get_account_from_smb_info = 1;
189		}
190
191		Cdbg(DBE, "fail smbc_parser_basic_authentication and get account from smb_info %s, %s", user->ptr, pass->ptr);
192	}
193	else{
194		buffer_copy_string(user, auth_username);
195		buffer_copy_string(pass, auth_password);
196		free(auth_username);
197		free(auth_password);
198	}
199
200	time_t cur_time = time(NULL);
201
202	double result = difftime(cur_time, con->smb_info->auth_time);
203
204	if(con->smb_info->qflag == SMB_HOST_QUERY) {
205		//data_string *ds2 = (data_string *)array_get_element(con->request.headers, "user-Agent");
206
207		//- MUST login again more than 30 minutes
208		if(result>1800){
209			goto error_401;
210		}
211
212		if( con->smb_info && buffer_is_equal_string(con->smb_info->username, "RELOGIN", 7) ){
213			buffer_reset(con->smb_info->username);
214			buffer_reset(con->smb_info->password);
215			goto error_401;
216		}
217		/*
218		if(con->smb_info->username->used && con->smb_info->password->used){
219			buffer_copy_buffer(user, con->smb_info->username);
220			buffer_copy_buffer(pass, con->smb_info->password);
221			Cdbg(DBE, "SMB_HOST_QUERY-->copy from smb_info user=[%s], pass=[%s]", user->ptr, pass->ptr);
222		}
223		*/
224#if EMBEDDED_EANBLE
225		//char* webav_user = nvram_get_http_username();
226		//char* webav_pass = nvram_get_http_passwd();
227		char* enable_webdav_block = nvram_get_enable_webdav_lock();
228		char* is_webdav_block = nvram_get_webdav_acc_lock();
229#ifndef APP_IPKG
230		int try_times = atoi(nvram_get_webdav_lock_times());
231		int try_interval = atoi(nvram_get_webdav_lock_interval())*60;
232#else
233		char* lock_times = nvram_get_webdav_lock_times();
234		char* lock_interval = nvram_get_webdav_lock_interval();
235		int try_times = atoi(lock_times);
236        int try_interval = atoi(lock_interval)*60;
237#endif
238#else
239		//char* webav_user = "admin";
240		//char* webav_pass = "admin";
241		char* enable_webdav_block = "1";
242		char* is_webdav_block = g_is_webdav_block;
243		int try_times = 3;
244		int try_interval = 1*60; //- 1 minutes
245#endif
246		int isBrowser = ( ds_useragent && (strstr( ds_useragent->value->ptr, "Mozilla" ) || strstr( ds_useragent->value->ptr, "Opera" ))) ? 1 : 0;
247		if( isBrowser == 1 && strcmp(enable_webdav_block, "1") == 0 && strcmp(is_webdav_block, "1") == 0 ){
248			Cdbg(DBE, "Direct go to 455 error page");
249#if EMBEDDED_EANBLE
250#ifdef APP_IPKG
251	        //free(webav_user);
252	        //free(webav_pass);
253	        free(enable_webdav_block);
254	        free(is_webdav_block);
255	        free(lock_times);
256	        free(lock_interval);
257#endif
258#endif
259			goto error_455;
260		}
261
262		if( do_account_authentication(user->ptr, pass->ptr) != 1 ){
263		//if( smbc_acc_account_authentication(con, user->ptr, pass->ptr) != 1 ){
264		//if( strcmp(user->ptr, webav_user)!=0 || strcmp(pass->ptr, webav_pass)!=0 ){
265
266			//- login failed.
267
268			if( isBrowser==1 && strcmp(enable_webdav_block, "1") == 0 && con->smb_info && ds_auth!=NULL ){
269				//- block user
270
271				con->smb_info->login_count++;
272
273				time_t current_time = time(NULL);
274
275				double result2 = difftime(cur_time, con->smb_info->login_begin_time);
276				if( result2 > try_interval ){
277					con->smb_info->login_count = 1;
278				}
279
280				if(con->smb_info->login_count==1)
281					con->smb_info->login_begin_time = time(NULL);
282
283				Cdbg(DBE, "con->smb_info->login_count=[%d][%d]", con->smb_info->login_count, try_times);
284				if(con->smb_info->login_count>=try_times){
285
286					con->smb_info->login_count = 0;
287
288					#if EMBEDDED_EANBLE
289					nvram_set_webdav_acc_lock("1");
290					nvram_do_commit();
291					#else
292					g_is_webdav_block = "1";
293					#endif
294
295					Cdbg(DBE, "error_455...");
296#if EMBEDDED_EANBLE
297#ifdef APP_IPKG
298                    //free(webav_user);
299                    //free(webav_pass);
300                    free(enable_webdav_block);
301                    free(is_webdav_block);
302                    free(lock_times);
303                    free(lock_interval);
304#endif
305#endif
306					goto error_455;
307				}
308			}
309#if EMBEDDED_EANBLE
310#ifdef APP_IPKG
311            //free(webav_user);
312            //free(webav_pass);
313            free(enable_webdav_block);
314            free(is_webdav_block);
315            free(lock_times);
316            free(lock_interval);
317#endif
318#endif
319			goto error_401;
320		}
321
322		if(con->smb_info){
323			con->smb_info->login_count = 0;
324		}
325
326		if(!get_account_from_smb_info){
327			log_sys_write(srv, "ssss", "User", user->ptr, "login from ip", con->dst_addr_buf->ptr);
328
329			buffer_copy_buffer(srv->last_login_info, srv->cur_login_info);
330
331			buffer_copy_string(srv->cur_login_info, user->ptr);
332			buffer_append_string(srv->cur_login_info, ">");
333
334			char srv_time[255];
335			strftime(srv_time, 254, "%Y/%m/%d %H:%M:%S", localtime(&(srv->cur_ts)));
336			buffer_append_string(srv->cur_login_info, srv_time);
337			buffer_append_string(srv->cur_login_info, ">");
338
339			buffer_append_string(srv->cur_login_info, con->dst_addr_buf->ptr);
340
341			#if EMBEDDED_EANBLE
342			nvram_set_webdav_last_login_info(srv->last_login_info->ptr);
343			#endif
344		}
345#if EMBEDDED_EANBLE
346#ifdef APP_IPKG
347        //free(webav_user);
348        //free(webav_pass);
349        free(enable_webdav_block);
350        free(is_webdav_block);
351        free(lock_times);
352        free(lock_interval);
353#endif
354#endif
355	}
356	else {
357
358		//- check user / password
359		struct stat st;
360
361		if( con->smb_info && buffer_is_equal_string(con->smb_info->username, "RELOGIN", 7) ){
362			buffer_reset(con->smb_info->username);
363			buffer_reset(con->smb_info->password);
364
365			goto error_401;
366		}
367
368		int res = smbc_server_check_creds( con->smb_info->server->ptr,
369									       con->smb_info->share->ptr,
370									       con->smb_info->workgroup->ptr,
371									       user->ptr,
372									       pass->ptr );
373
374		//if( res == NT_STATUS_V(NT_STATUS_NOT_SUPPORTED)) {
375		if( res == 0xc00000bb ){
376			buffer_free(user);
377			buffer_free(pass);
378			con->http_status = 406;
379
380			return HANDLER_FINISHED;
381		}
382		else if(res != 0) { //the username/password for smb_server is not correct
383			if(con->smb_info->username->used && con->smb_info->password->used){
384				buffer_copy_buffer(user, con->smb_info->username);
385				buffer_copy_buffer(pass, con->smb_info->password);
386				Cdbg(DBE, "Try to login again, server=%s, share=%s, user=%s, pass=%s",
387						con->smb_info->server->ptr,
388						con->smb_info->share->ptr,
389						user->ptr, pass->ptr);
390
391				//- MUST login again more than 30 minutes
392				if(result>1800){
393					buffer_copy_string(pass, "");
394				}
395
396				int res = smbc_server_check_creds(con->smb_info->server->ptr,
397											    con->smb_info->share->ptr,
398											    con->smb_info->workgroup->ptr,
399											    user->ptr,
400											    pass->ptr);
401
402				if(res != 0)
403					goto error_401;
404			}
405			else
406				goto error_401;
407		}
408
409		if(!get_account_from_smb_info)
410			log_sys_write(srv, "sssbss", "User", user->ptr, "login", con->smb_info->server, "from ip", con->dst_addr_buf->ptr);
411	}
412
413	con->smb_info->auth_time = time(NULL);
414
415	if( !buffer_is_equal_string(user, "no", 2) && !buffer_is_equal_string(pass, "no", 2)){
416		buffer_copy_buffer(con->smb_info->username, user);
417		buffer_copy_buffer(con->smb_info->password, pass);
418		Cdbg(DBE, "save username=[%s], password=[%s], time=[%d] to con->smb_info", con->smb_info->username->ptr, con->smb_info->password->ptr, con->smb_info->auth_time);
419	}
420
421	buffer_free(user);
422	buffer_free(pass);
423
424	return HANDLER_UNSET;
425
426error_401:
427	buffer_free(user);
428	buffer_free(pass);
429
430	if(con->smb_info)
431		con->smb_info->auth_time = time(NULL);
432
433	smbc_wrapper_response_401(srv, con);
434
435	return HANDLER_FINISHED;
436
437error_455:
438	//- Block webdav
439	buffer_free(user);
440	buffer_free(pass);
441	con->http_status = 455;
442	return HANDLER_FINISHED;
443
444}
445