搜索
发新帖
NETGEAR R7500v2NETGEAR Vs ASUS T-Mobile定制版NETGEAR 免费延保
开启左侧

wifidog认证功能源码初分析(2)

[复制链接]
2167 0

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

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

通过上面的防火墙规则,会将通过上面的防火墙规则,会将HTTP请求的外部IP地址和端口通过NAT方式重定向至本地wifidog内嵌HTTP服务器的地址和端口上,并由内嵌HTTP服务器进行服务,而内嵌HTTP服务器的路径和回调处理如下:
  1. if ((webserver = httpdCreate(config->gw_address, config->gw_port)) == NULL) {  
  2.     debug(LOG_ERR, "Could not create web server: %s", strerror(errno));  
  3.     exit(1);  
  4. }  
  5. debug(LOG_DEBUG, "Assigning callbacks to web server");  
  6. httpdAddCContent(webserver, "/", "wifidog", 0, NULL, http_callback_wifidog);  
  7. httpdAddCContent(webserver, "/wifidog", "", 0, NULL, http_callback_wifidog);  
  8. httpdAddCContent(webserver, "/wifidog", "about", 0, NULL, http_callback_about);  
  9. httpdAddCContent(webserver, "/wifidog", "status", 0, NULL, http_callback_status);  
  10. httpdAddCContent(webserver, "/wifidog", "auth", 0, NULL, http_callback_auth);  
  11. httpdAddC404Content(webserver, http_callback_404);
复制代码
客户端首次访问时回调客户端首次访问时回调http_callback_404函数,在该函数中根据获取的客户端信息来配置重定向的URL fragment,如下:
  1. /** The 404 handler is also responsible for redirecting to the auth server */
  2. void http_callback_404(httpd *webserver, request *r)
  3. {
  4.     char        tmp_url[MAX_BUF],
  5.         *url;
  6.     s_config    *config = config_get_config();
  7.     t_auth_serv *auth_server = get_auth_server();

  8.     memset(tmp_url, 0, sizeof(tmp_url));
  9.     /*
  10.      * XXX Note the code below assumes that the client's request is a plain
  11.      * http request to a standard port. At any rate, this handler is called only
  12.      * if the internet/auth server is down so it's not a huge loss, but still.
  13.      */
  14.     snprintf(tmp_url, (sizeof(tmp_url) - 1), "http://%s%s%s%s",
  15.                     r->request.host,
  16.                     r->request.path,
  17.                     r->request.query[0] ? "?" : "",
  18.                     r->request.query);
  19.     url = httpdUrlEncode(tmp_url);

  20.     if (!is_online()) {
  21.         /* The internet connection is down at the moment  - apologize and do not redirect anywhere */
  22.         char * buf;
  23.         safe_asprintf(&buf,
  24.             "<p>We apologize, but it seems that the internet connection that powers this hotspot is temporarily unavailable.</p>"
  25.             "<p>If at all possible, please notify the owners of this hotspot that the internet connection is out of service.</p>"
  26.             "<p>The maintainers of this network are aware of this disruption.  We hope that this situation will be resolved soon.</p>"
  27.             "<p>In a while please <a href='%s'>click here</a> to try your request again.</p>", tmp_url);

  28.         send_http_page(r, "Uh oh! Internet access unavailable!", buf);
  29.         free(buf);
  30.         debug(LOG_INFO, "Sent %s an apology since I am not online - no point sending them to auth server", r->clientAddr);
  31.     }
  32.     else if (!is_auth_online()) {
  33.         /* The auth server is down at the moment - apologize and do not redirect anywhere */
  34.         char * buf;
  35.         safe_asprintf(&buf,
  36.             "<p>We apologize, but it seems that we are currently unable to re-direct you to the login screen.</p>"
  37.             "<p>The maintainers of this network are aware of this disruption.  We hope that this situation will be resolved soon.</p>"
  38.         "<p>In a couple of minutes please <a href='%s'>click here</a> to try your request again.</p>", tmp_url);

  39.         send_http_page(r, "Uh oh! Login screen unavailable!", buf);
  40.         free(buf);
  41.         debug(LOG_INFO, "Sent %s an apology since auth server not online - no point sending them to auth server", r->clientAddr);
  42.     }
  43.     else {
  44.         /* Re-direct them to auth server */
  45.         char *urlFragment;
  46.         safe_asprintf(&urlFragment, "%sgw_address=%s&gw_port=%d&gw_id=%s&url=%s",
  47.             auth_server->authserv_login_script_path_fragment,
  48.             config->gw_address,
  49.             config->gw_port,
  50.             config->gw_id,
  51.             url);
  52.         debug(LOG_INFO, "Captured %s requesting [%s] and re-directing them to login page", r->clientAddr, url);
  53.         http_send_redirect_to_auth(r, urlFragment, "Redirect to login page");
  54.         free(urlFragment);
  55.     }
  56.     free(url);
  57. }
复制代码
上面代码基本不用解释,具体重定向至auth server的消息在下面的 http_send_redirect_to_auth 函数中实现:
  1. void http_send_redirect_to_auth(request *r, char *urlFragment, char *text)
  2. {
  3.     char *protocol = NULL;
  4.     int port = 80;
  5.     t_auth_serv *auth_server = get_auth_server();

  6.     if (auth_server->authserv_use_ssl) {
  7.         protocol = "https";
  8.         port = auth_server->authserv_ssl_port;
  9.     } else {
  10.         protocol = "http";
  11.         port = auth_server->authserv_http_port;
  12.     }

  13.     char *url = NULL;
  14.     safe_asprintf(&url, "%s://%s:%d%s%s",
  15.         protocol,
  16.         auth_server->authserv_hostname,
  17.         port,
  18.         auth_server->authserv_path,
  19.         urlFragment
  20.     );
  21.     http_send_redirect(r, url, text);
  22.     free(url);  
  23. }
复制代码
具体的重定向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
gw_address,路由器的LAN地址

gw_port:为wifidog的监听端口

gw_id:路由器的标识名

mac:客户端设备的MAC地址

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

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

精彩推荐

热点动态

精彩图文


快速回复 返回顶部 返回列表