Initial analysis of wifidog source code (4)-Conversion

Source: Internet
Author: User

After the previous wifidog source code analysis (3), the access device's browser redirects to the HTTP service (Port 2060) of the wifidog on the router) /wifidog/auth (with the token assigned to the access device by the authentication server). This article describes the verification process after the/wifidog/auth access is received from the wifidog.

-

According to wifidog source code analysis (2), a callback for the access path/wifidog/auth is registered before wifidog starts the HTTP service, as described below:

[CPP]View plaincopy

  1. Httpdaddccontent (Webserver, "/wifidog", "about", 0, null, http_callback_about );
  2. Httpdaddccontent (Webserver, "/wifidog", "status", 0, null, http_callback_status );
  3. // Register the access callback http_callback_auth for/wifidog/auth
  4. Httpdaddccontent (Webserver, "/wifidog", "auth", 0, null, http_callback_auth );

In this way,/wifidog/auth redirected from the access device (or client) enters the http_callback_auth function, as follows:

[CPP]View plaincopy

  1. Http_callback_auth (httpd * Webserver, request * r)
  2. {
  3. T_client * client;
  4. Httpvar * token;
  5. Char * MAC;
  6. // 1. Obtain the logout value in the condition parameter.
  7. Httpvar * logout = httpdgetvariablebyname (R, "logout ");
  8. // 2. Obtain the token value in the condition parameter.
  9. If (token = httpdgetvariablebyname (R, "token "))){
  10. /* They supplied variable "token "*/
  11. // 3. You can see that the MAC address of the access device must be obtained through arp.
  12. If (! (MAC = arp_get (R-> clientaddr ))){
  13. /* We cocould not get their MAC address */
  14. Debug (log_err, "failed to retrieve MAC address for IP % s", R-> clientaddr );
  15. Send_http_page (R, "wifidog error", "failed to retrieve your MAC address ");
  16. } Else {
  17. /* We have their MAC address */
  18. Lock_client_list ();
  19. // 4. Check whether the client (access device) is in the access client list maintained by wifidog.
  20. If (client = client_list_find (R-> clientaddr, Mac) = NULL ){
  21. Debug (log_debug, "new client for % s", R-> clientaddr );
  22. Client_list_append (R-> clientaddr, Mac, Token-> value );
  23. } Else if (logout ){
  24. // 5. Exit the processing.
  25. T_authresponse authresponse;
  26. S_config * Config = config_get_config ();
  27. Unsigned long incoming = client-> counters. Incoming;
  28. Unsigned long outgoing = client-> counters. Outgoing;
  29. Char * IP = safe_strdup (client-> ip );
  30. Char * urlfragment = NULL;
  31. T_auth_serv * auth_server = get_auth_server ();
  32. Fw_deny (client-> ip, client-> Mac, client-> fw_connection_state );
  33. Client_list_delete (client );
  34. Debug (log_debug, "Got logout from % s", client-> ip );
  35. /* Advertise the logout if we have an Auth Server */
  36. If (config-> auth_servers! = NULL ){
  37. Unlock_client_list ();
  38. Auth_server_request (& authresponse, request_type_logout, IP, Mac, Token-> value,
  39. Incoming, outgoing );
  40. Lock_client_list ();
  41. /* Re-direct them to Auth Server */
  42. Debug (log_info, "Got manual logout from Client IP % s, Mac % s, Token % s"
  43. "-Redirecting them to logout message", client-> ip, client-> Mac, client-> token );
  44. Safe_asprintf (& urlfragment, "% smessage = % s ",
  45. Auth_server-> authserv_msg_script_path_fragment,
  46. Gateway_message_account_logged_out
  47. );
  48. Http_send_redirect_to_auth (R, urlfragment, "redirect to logout message ");
  49. Free (urlfragment );
  50. }
  51. Free (IP );
  52. }
  53. Else {
  54. // 6. the logon has been verified
  55. Debug (log_debug, "client for % s is already in the client list", client-> ip );
  56. }
  57. Unlock_client_list ();
  58. If (! Logout ){
  59. // 7. Verify the token on The Auth Server.
  60. Authenticate_client (R );
  61. }
  62. Free (MAC );
  63. }
  64. } Else {
  65. /* They did not supply variable "token "*/
  66. // 8. the token is not included and is rejected directly.
  67. Send_http_page (R, "wifidog error", "invalid token ");
  68. }
  69. }

This function mainly handles client exit, illegal verification, and client verification processes. The following describes the steps in the annotations:

-

1. If the client exits, it will carry the logout parameter information and go to step 1 (of course, if there is no token parameter, it will go directly to step 2, that is, reject );

2. According to the normal authentication process, the token parameter assigned by the authentication server will be carried;

3. As described in the remarks, the MAC address of the access device must be obtained through the ARP Protocol. (In fact, you can view the implementation of arg_get, you can see that the/proc/NET/arp file -- ARP cache -- is directly parsed to obtain the MAC information of the corresponding Client IP address), similar to the following:

[[Email protected] ~] $ More/proc/NET/ARP

IP address HW type flags HW Address Mask Device

192.168.1.203 0x1 0x2 18: 03: 73: D5: 1b: A2 * eth0

192.168.1.1 0x1 0x2 00: 21: 27: 63: C0: Ce * eth0

[[Email protected] ~] $

4. After obtaining the MAC address of the client, check whether the client is in the list of access devices (or clients) maintained by wifidog Based on the Client IP address and MAC address, if not, it is appended to this list (the data structure of this list is described later );

5. If the client already exists and logout is required for this access, the process for exiting the client is as follows: disable the outgoing rule of the Client IP/Mac --> Delete the client record from the client list --> notify the authentication server that the client exits (and carry the token of the client, upstream and downstream traffic) --> returns the # define default_authservmsgpathfragment "gw_message.php? "Access path (carrying an exited message );

6. If the client has been logged on and verified, and this access is not logged out, the client will jump directly to Step 1;

7. This step is the token verification process. The specific implementation is in the authenticate_client function:

[CPP]View plaincopy

  1. Authenticate_client (Request * r)
  2. {
  3. T_client * client;
  4. T_authresponse auth_response;
  5. Char * Mac,
  6. * Token;
  7. Char * urlfragment = NULL;
  8. S_config * Config = NULL;
  9. T_auth_serv * auth_server = NULL;
  10. Lock_client_list ();
  11. // Obtain the MAC address of the client and the token allocated for this session based on the IP address
  12. // Mainly used for token Verification
  13. Client = client_list_find_by_ip (R-> clientaddr );
  14. If (client = NULL ){
  15. Debug (log_err, "authenticate_client (): cocould not find client for % s", R-> clientaddr );
  16. Unlock_client_list ();
  17. Return;
  18. }
  19. MAC = safe_strdup (client-> Mac );
  20. Token = safe_strdup (client-> token );
  21. Unlock_client_list ();
  22. /*
  23. * At this point we 've ve released the lock while we do an HTTP request since it cocould
  24. * Take multiple seconds to do and the gateway wo'd should be tively be frozen if we
  25. * Kept the lock.
  26. */
  27. // Use login to verify the token of the client on the authentication server
  28. Auth_server_request (& auth_response, request_type_login, R-> clientaddr, Mac, Token, 0, 0 );
  29. Lock_client_list ();
  30. /* Can't trust the client to still exist after n seconds have passed */
  31. // Here, it mainly prevents token verification on the authentication server.
  32. // When the client has exited, it does not need to be processed.
  33. Client = client_list_find (R-> clientaddr, Mac );
  34. If (client = NULL ){
  35. Debug (log_err, "authenticate_client (): cocould not find client node for % s (% s)", R-> clientaddr, Mac );
  36. Unlock_client_list ();
  37. Free (token );
  38. Free (MAC );
  39. Return;
  40. }
  41. Free (token );
  42. Free (MAC );
  43. /* Prepare some variables we'll need below */
  44. Config = config_get_config ();
  45. Auth_server = get_auth_server ();
  46. // Perform different processing based on the returned verification results
  47. Switch (auth_response.authcode ){
  48. Case auth_error:
  49. Case auth_denied:
  50. Case auth_validation:
  51. Case auth_validation_failed:
  52. ......
  53. Break;
  54. Case auth_allowed:
  55. /* Logged in successfully as a regular account */
  56. Debug (log_info, "Got allowed from central server authenticating token % s from % s at % s -"
  57. "Adding to firewall and redirecting them to portal", client-> token, client-> ip, client-> Mac );
  58. Client-> fw_connection_state = fw_mark_known;
  59. Fw_allow (client-> ip, client-> Mac, fw_mark_known );
  60. Served_this_session ++;
  61. Safe_asprintf (& urlfragment, "% sgw_id = % s ",
  62. Auth_server-> authserv_portal_script_path_fragment,
  63. Config-> gw_id
  64. );
  65. Http_send_redirect_to_auth (R, urlfragment, "redirect to portal ");
  66. Free (urlfragment );
  67. Break;
  68. }
  69. Unlock_client_list ();
  70. Return;
  71. }

Here are two major steps:

-

1. Check the token of the client by calling auth_server_request (& auth_response, request_type_login, R-> clientaddr, Mac, Token, 0, 0;

2. Perform different processing based on the token verification results returned by the authentication server (mainly to set different firewall filtering rules for the client). Here we analyze the auth_allowed verification results, here there are two main actions:

2.1. Call the fw_allow function to "release" the client ";

2.2. the system returns the response to the portal path redirect to the authentication server;

-

Here, we will briefly analyze the implementation of the fw_allow function, and view the implementation of fw_allow. We can see that the action of setting the Allow client to use the firewall is implemented in iptables_fw_access, as shown below:

[CPP]View plaincopy

  1. /** Set if a specific client has access through the firewall */
  2. // For the above process, input parameters here
  3. // The type is fw_access_allow, And the tag is fw_mark_known.
  4. Int iptables_fw_access (fw_access_t type, const char * IP, const char * Mac, int tag)
  5. {
  6. Int RC;
  7. Fw_quiet = 0;
  8. Switch (type ){
  9. Case fw_access_allow:
  10. Iptables_do_command ("-T mangle-a" table_wifidog_outgoing "-S % s-M Mac -- Mac-source % s-J mark -- Set-mark % d", IP, Mac, tag );
  11. Rc = iptables_do_command ("-T mangle-a" table_wifidog_incoming "-D % s-J accept", ip );
  12. Break;
  13. Case fw_access_deny:
  14. Iptables_do_command ("-T mangle-d" table_wifidog_outgoing "-S % s-M Mac -- Mac-source % s-J mark -- Set-mark % d", IP, Mac, tag );
  15. Rc = iptables_do_command ("-T mangle-d" table_wifidog_incoming "-D % s-J accept", ip );
  16. Break;
  17. Default:
  18. Rc =-1;
  19. Break;
  20. }
  21. Return RC;
  22. }

Similarly, here we mainly analyze the firewall setting rules of iptables in allow. The two iptables commands executed are as follows:

-

1) append the wifidog _ $ ID $ _ outgoing outbound filter chain to the mangle table. The rules for this chain are as follows:

A) the IP address is the IP address of the client;

B) the MAC address is the MAC address of the client;

C) Set mark to fw_mark_known;

-

Iptables-T mangle-awifidog _ $ ID $ _ outgoing-s Client IP address-M Mac -- Mac-source client MAC address-J mark -- set-markFW_MARK_KNOWN

-

2) append an entry in the mangle table that [accepts all destination addresses and IP addresses of this client] wifidog _ $ ID $ _ incoming and input the filter chain;

-

Iptables-T mangle-awifidog _ $ ID $ _ incoming-D Client IP address-J accept

-

Finally, let's take a look at the redirect request sent from the wifidog to the authentication server and the response message sent from the authentication server to the client (redirected to the original access Baidu.com:

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.