wifidog 源码初分析(2)

上一篇分析了接入设备的首次浏览器访问请求如何通过 防火墙过滤规则 重定向到 wifidog 的 HTTP 服务中,本篇主要分析了 wifidog 在接收到 接入设备的 HTTP 访问请求后,如何将此 HTTP 请求重定向到 认证服务器(auth-server) 上。


通过上面的防火墙规则,会将通过上面的防火墙规则,会将HTTP请求的外部IP地址和端口通过NAT方式重定向至本地wifidog内嵌HTTP服务器的地址和端口上,并由内嵌HTTP服务器进行服务,而内嵌HTTP服务器的路径和回调处理如下:

 

1
2
3
4
5
6
7
8
9
10
11
12
if  ((webserver = httpdCreate(config->gw_address, config->gw_port)) == NULL) {
     debug(LOG_ERR,  "Could not create web server: %s" strerror ( errno ));
     exit (1);
}
debug(LOG_DEBUG,  "Assigning callbacks to web server" );
httpdAddCContent(webserver,  "/" "wifidog" , 0, NULL, http_callback_wifidog);
httpdAddCContent(webserver,  "/wifidog" "" , 0, NULL, http_callback_wifidog);
httpdAddCContent(webserver,  "/wifidog" "about" , 0, NULL, http_callback_about);
httpdAddCContent(webserver,  "/wifidog" "status" , 0, NULL, http_callback_status);
httpdAddCContent(webserver,  "/wifidog" "auth" , 0, NULL, http_callback_auth);
                                               
httpdAddC404Content(webserver, http_callback_404);

 

客户端首次访问时回调客户端首次访问时回调http_callback_404函数,在该函数中根据获取的客户端信息来配置重定向的URL fragment,如下:

 

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
void
http_callback_404(httpd *webserver, request *r)
{
     char  tmp_url[MAX_BUF],
             *url,
             *mac;
     s_config    *config = config_get_config();
     t_auth_serv *auth_server = get_auth_server();
     memset (tmp_url, 0,  sizeof (tmp_url));
     /*
      * XXX Note the code below assumes that the client's request is a plain
      * http request to a standard port. At any rate, this handler is called only
      * if the internet/auth server is down so it's not a huge loss, but still.
      */  /* 用户需要访问的URL */
         snprintf(tmp_url, ( sizeof (tmp_url) - 1),  "http://%s%s%s%s" ,
                         r->request.host,
                         r->request.path,
                         r->request.query[0] ?  "?"  "" ,
                         r->request.query);
     url = httpdUrlEncode(tmp_url);
     if  (!is_online()) {
         /* 路由器都接入不到 internet */
         char  * buf;
         send_http_page(r,  "Uh oh! Internet access unavailable!" , buf);
         free (buf);
     }
     else  if  (!is_auth_online()) {
         /* auth server 挂起 */
         char  * buf;
         send_http_page(r,  "Uh oh! Login screen unavailable!" , buf);
         free (buf);
     }
     else  {
         /* 配置重定向到 auth server 的 url 参数 */
         char  *urlFragment;
         if  (!(mac = arp_get(r->clientAddr))) {
             /* We could not get their MAC address */
             debug(LOG_INFO,  "Failed to retrieve MAC address for ip %s, so not putting in the login request" , r->clientAddr);
             safe_asprintf(&urlFragment,  "%sgw_address=%s&gw_port=%d&gw_id=%s&url=%s" ,
                 auth_server->authserv_login_script_path_fragment,
                 config->gw_address,
                 config->gw_port,
                 config->gw_id,
                 url);
         else  {          
             debug(LOG_INFO,  "Got client MAC address for ip %s: %s" , r->clientAddr, mac);
             safe_asprintf(&urlFragment,  "%sgw_address=%s&gw_port=%d&gw_id=%s&mac=%s&url=%s" ,
                 auth_server->authserv_login_script_path_fragment,
                 config->gw_address,
                 config->gw_port,
                 config->gw_id,
                 mac,
                 url);
         }
         /* 调用该函数将用户请求重定向到 auth server 的登录页面 */
         http_send_redirect_to_auth(r, urlFragment,  "Redirect to login page" );
         free (urlFragment);
     }
     free (url);
}

 

上面代码基本不用解释,具体重定向至auth server的消息在下面的 http_send_redirect_to_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
void  http_send_redirect_to_auth(request *r,  char  *urlFragment,  char  *text)
{
     char  *protocol = NULL;
     int  port = 80;
     t_auth_serv *auth_server = get_auth_server();
     if  (auth_server->authserv_use_ssl) {
         protocol =  "https" ;
         port = auth_server->authserv_ssl_port;
     else  {
         protocol =  "http" ;
         port = auth_server->authserv_http_port;
     }
                                            
     char  *url = NULL;
     safe_asprintf(&url,  "%s://%s:%d%s%s" ,
         protocol,
         auth_server->authserv_hostname,
         port,
         auth_server->authserv_path,
         urlFragment
     );
     http_send_redirect(r, url, text);
     free (url);
}

具体的重定向URL给个实例:


POST /login/?gw_address=192.168.1.1&gw_port=2060&gw_id=default&mac=44:94:fc:ef:28:40&url=http%3A//www.baidu.com/ HTTP/1.1


可以看到这里有这几个参数信息:


2gw_address,路由器的LAN地址

2gw_port:为wifidog的监听端口

2gw_id:路由器的标识名

2mac:客户端设备的MAC地址

2url:为客户端访问的原URL(以便于重定向)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值