wifidog 源码初分析
来源:互联网 发布:linux luajit 编辑:程序博客网 时间:2024/05/21 10:45
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://quietmadman.blog.51cto.com/3269500/1386291
1
2
3
4
httpdAddCContent(webserver,
"/wifidog"
,
"about"
, 0, NULL, http_callback_about);
httpdAddCContent(webserver,
"/wifidog"
,
"status"
, 0, NULL, http_callback_status);
// 注册了针对 /wifidog/auth 的访问回调 http_callback_auth
httpdAddCContent(webserver,
"/wifidog"
,
"auth"
, 0, NULL, http_callback_auth);
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
http_callback_auth(httpd *webserver, request *r)
{
t_client *client;
httpVar * token;
char
*mac;
// 1, 获取条件参数中的 logout 值
httpVar *logout = httpdGetVariableByName(r,
"logout"
);
// 2, 获取条件参数中的 token 值
if
((token = httpdGetVariableByName(r,
"token"
))) {
/* They supplied variable "token" */
// 3, 可以看到, 这里要求必须能够通过 ARP 协议获取到 接入设备 的 MAC 地址
if
(!(mac = arp_get(r->clientAddr))) {
/* We could not get their MAC address */
debug(LOG_ERR,
"Failed to retrieve MAC address for ip %s"
, r->clientAddr);
send_http_page(r,
"WiFiDog Error"
,
"Failed to retrieve your MAC address"
);
}
else
{
/* We have their MAC address */
LOCK_CLIENT_LIST();
// 4, 检查该客户端(接入设备)是否已经在 wifidog 维护的接入客户端列表中
if
((client = client_list_find(r->clientAddr, mac)) == NULL) {
debug(LOG_DEBUG,
"New client for %s"
, r->clientAddr);
client_list_append(r->clientAddr, mac, token->value);
}
else
if
(logout) {
// 5, 退出处理
t_authresponse authresponse;
s_config *config = config_get_config();
unsigned
long
long
incoming = client->counters.incoming;
unsigned
long
long
outgoing = client->counters.outgoing;
char
*ip = safe_strdup(client->ip);
char
*urlFragment = NULL;
t_auth_serv *auth_server = get_auth_server();
fw_deny(client->ip, client->mac, client->fw_connection_state);
client_list_delete(client);
debug(LOG_DEBUG,
"Got logout from %s"
, client->ip);
/* Advertise the logout if we have an auth server */
if
(config->auth_servers != NULL) {
UNLOCK_CLIENT_LIST();
auth_server_request(&authresponse, REQUEST_TYPE_LOGOUT, ip, mac, token->value,
incoming, outgoing);
LOCK_CLIENT_LIST();
/* Re-direct them to auth server */
debug(LOG_INFO,
"Got manual logout from client ip %s, mac %s, token %s"
"- redirecting them to logout message"
, client->ip, client->mac, client->token);
safe_asprintf(&urlFragment,
"%smessage=%s"
,
auth_server->authserv_msg_script_path_fragment,
GATEWAY_MESSAGE_ACCOUNT_LOGGED_OUT
);
http_send_redirect_to_auth(r, urlFragment,
"Redirect to logout message"
);
free
(urlFragment);
}
free
(ip);
}
else
{
// 6, 已经登录校验通过
debug(LOG_DEBUG,
"Client for %s is already in the client list"
, client->ip);
}
UNLOCK_CLIENT_LIST();
if
(!logout) {
// 7, 到 auth server 上进一步校验 token
authenticate_client(r);
}
free
(mac);
}
}
else
{
/* They did not supply variable "token" */
// 8, 未携带 token, 直接拒绝
send_http_page(r,
"WiFiDog error"
,
"Invalid token"
);
}
}
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
authenticate_client(request *r)
{
t_client *client;
t_authresponse auth_response;
char
*mac,
*token;
char
*urlFragment = NULL;
s_config *config = NULL;
t_auth_serv *auth_server = NULL;
LOCK_CLIENT_LIST();
// 根据 IP 地址获取 客户端的 MAC 地址以及本次会话分配的 token
// 主要用于 token 校验过程
client = client_list_find_by_ip(r->clientAddr);
if
(client == NULL) {
debug(LOG_ERR,
"authenticate_client(): Could not find client for %s"
, r->clientAddr);
UNLOCK_CLIENT_LIST();
return
;
}
mac = safe_strdup(client->mac);
token = safe_strdup(client->token);
UNLOCK_CLIENT_LIST();
/*
* At this point we've released the lock while we do an HTTP request since it could
* take multiple seconds to do and the gateway would effectively be frozen if we
* kept the lock.
*/
// 通过 "login" 到 认证服务器 上进行客户端的 token 校验
auth_server_request(&auth_response, REQUEST_TYPE_LOGIN, r->clientAddr, mac, token, 0, 0);
LOCK_CLIENT_LIST();
/* can't trust the client to still exist after n seconds have passed */
// 这里主要防止在到 认证服务器 上进行 token 校验的过程中
// 该客户端已经退出的情形, 此时就不需要再进行处理
client = client_list_find(r->clientAddr, mac);
if
(client == NULL) {
debug(LOG_ERR,
"authenticate_client(): Could not find client node for %s (%s)"
, r->clientAddr, mac);
UNLOCK_CLIENT_LIST();
free
(token);
free
(mac);
return
;
}
free
(token);
free
(mac);
/* Prepare some variables we'll need below */
config = config_get_config();
auth_server = get_auth_server();
// 根据返回的校验结果做不同的处理
switch
(auth_response.authcode) {
case
AUTH_ERROR:
case
AUTH_DENIED:
case
AUTH_VALIDATION:
case
AUTH_VALIDATION_FAILED:
... ...
break
;
case
AUTH_ALLOWED:
/* Logged in successfully as a regular account */
debug(LOG_INFO,
"Got ALLOWED from central server authenticating token %s from %s at %s - "
"adding to firewall and redirecting them to portal"
, client->token, client->ip, client->mac);
client->fw_connection_state = FW_MARK_KNOWN;
fw_allow(client->ip, client->mac, FW_MARK_KNOWN);
served_this_session++;
safe_asprintf(&urlFragment,
"%sgw_id=%s"
,
auth_server->authserv_portal_script_path_fragment,
config->gw_id
);
http_send_redirect_to_auth(r, urlFragment,
"Redirect to portal"
);
free
(urlFragment);
break
;
}
UNLOCK_CLIENT_LIST();
return
;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/** Set if a specific client has access through the firewall */
// 针对上面的流程,这里的输入参数
// type 为 FW_ACCESS_ALLOW,tag 为 FW_MARK_KNOWN
int
iptables_fw_access(fw_access_t type,
const
char
*ip,
const
char
*mac,
int
tag)
{
int
rc;
fw_quiet = 0;
switch
(type) {
case
FW_ACCESS_ALLOW:
iptables_do_command(
"-t mangle -A "
TABLE_WIFIDOG_OUTGOING
" -s %s -m mac --mac-source %s -j MARK --set-mark %d"
, ip, mac, tag);
rc = iptables_do_command(
"-t mangle -A "
TABLE_WIFIDOG_INCOMING
" -d %s -j ACCEPT"
, ip);
break
;
case
FW_ACCESS_DENY:
iptables_do_command(
"-t mangle -D "
TABLE_WIFIDOG_OUTGOING
" -s %s -m mac --mac-source %s -j MARK --set-mark %d"
, ip, mac, tag);
rc = iptables_do_command(
"-t mangle -D "
TABLE_WIFIDOG_INCOMING
" -d %s -j ACCEPT"
, ip);
break
;
default
:
rc = -1;
break
;
}
return
rc;
}
0 0
- wifidog 源码初分析
- wifidog源码分析 - wifidog原理
- wifidog 源码初分析(1)
- wifidog 源码初分析(2)
- wifidog 源码初分析(3)
- wifidog 源码初分析(4)
- wifidog 源码初分析(一)
- wifidog 源码初分析(二)
- wifidog 源码初分析(三)
- wifidog 源码初分析(1)
- wifidog 源码初分析(2)
- wifidog 源码初分析(3)
- wifidog 源码初分析(4)
- wifidog 源码初分析(1)
- wifidog 源码初分析-1-转
- wifidog 源码初分析(4)
- wifidog 源码初分析(3)
- wifidog 源码初分析(2)
- 性格即命运
- com组件提取excel中的图片office07可以提取office13无法提取的问题
- 在Qt中获取屏幕大小
- 逆序排列数组
- Hibernate HQL介绍
- wifidog 源码初分析
- 3.对经历过的创业项目的总结
- 求前N项和
- Java 并发深入学习二
- 解决ADB server didn't ACK问题,连上手机问题
- Java 遍历Map集合的方法
- 如何突破 云网络延迟障碍
- 登陆EBS系统问题
- Extjs 3实现Combobox下拉列表的拼音过滤