770-radius_server.patch 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. From: Felix Fietkau <[email protected]>
  2. Date: Thu, 16 Mar 2023 11:35:50 +0100
  3. Subject: [PATCH] hostapd: add experimental radius server
  4. This can be used to run a standalone EAP server that can be used from
  5. other APs. It uses json as user database format and can automatically
  6. handle reload.
  7. --- a/hostapd/Makefile
  8. +++ b/hostapd/Makefile
  9. @@ -63,6 +63,10 @@ endif
  10. OBJS += main.o
  11. OBJS += config_file.o
  12. +ifdef CONFIG_RADIUS_SERVER
  13. +OBJS += radius.o
  14. +endif
  15. +
  16. OBJS += ../src/ap/hostapd.o
  17. OBJS += ../src/ap/wpa_auth_glue.o
  18. OBJS += ../src/ap/drv_callbacks.o
  19. --- a/hostapd/main.c
  20. +++ b/hostapd/main.c
  21. @@ -40,6 +40,7 @@ struct hapd_global {
  22. static struct hapd_global global;
  23. +extern int radius_main(int argc, char **argv);
  24. #ifndef CONFIG_NO_HOSTAPD_LOGGER
  25. static void hostapd_logger_cb(void *ctx, const u8 *addr, unsigned int module,
  26. @@ -838,6 +839,11 @@ int main(int argc, char *argv[])
  27. if (os_program_init())
  28. return -1;
  29. +#ifdef RADIUS_SERVER
  30. + if (strstr(argv[0], "radius"))
  31. + return radius_main(argc, argv);
  32. +#endif
  33. +
  34. os_memset(&interfaces, 0, sizeof(interfaces));
  35. interfaces.reload_config = hostapd_reload_config;
  36. interfaces.config_read_cb = hostapd_config_read;
  37. --- a/src/radius/radius_server.c
  38. +++ b/src/radius/radius_server.c
  39. @@ -63,6 +63,12 @@ struct radius_server_counters {
  40. u32 unknown_acct_types;
  41. };
  42. +struct radius_accept_attr {
  43. + u8 type;
  44. + u16 len;
  45. + void *data;
  46. +};
  47. +
  48. /**
  49. * struct radius_session - Internal RADIUS server data for a session
  50. */
  51. @@ -89,7 +95,7 @@ struct radius_session {
  52. unsigned int macacl:1;
  53. unsigned int t_c_filtering:1;
  54. - struct hostapd_radius_attr *accept_attr;
  55. + struct radius_accept_attr *accept_attr;
  56. u32 t_c_timestamp; /* Last read T&C timestamp from user DB */
  57. };
  58. @@ -373,6 +379,7 @@ static void radius_server_session_free(s
  59. radius_msg_free(sess->last_reply);
  60. os_free(sess->username);
  61. os_free(sess->nas_ip);
  62. + os_free(sess->accept_attr);
  63. os_free(sess);
  64. data->num_sess--;
  65. }
  66. @@ -533,6 +540,36 @@ radius_server_erp_find_key(struct radius
  67. }
  68. #endif /* CONFIG_ERP */
  69. +static struct radius_accept_attr *
  70. +radius_server_copy_attr(const struct hostapd_radius_attr *data)
  71. +{
  72. + const struct hostapd_radius_attr *attr;
  73. + struct radius_accept_attr *attr_new;
  74. + size_t data_size = 0;
  75. + void *data_buf;
  76. + int n_attr = 1;
  77. +
  78. + for (attr = data; attr; attr = attr->next) {
  79. + n_attr++;
  80. + data_size += wpabuf_len(attr->val);
  81. + }
  82. +
  83. + attr_new = os_zalloc(n_attr * sizeof(*attr) + data_size);
  84. + if (!attr_new)
  85. + return NULL;
  86. +
  87. + data_buf = &attr_new[n_attr];
  88. + for (n_attr = 0, attr = data; attr; attr = attr->next) {
  89. + struct radius_accept_attr *cur = &attr_new[n_attr++];
  90. +
  91. + cur->type = attr->type;
  92. + cur->len = wpabuf_len(attr->val);
  93. + cur->data = memcpy(data_buf, wpabuf_head(attr->val), cur->len);
  94. + data_buf += cur->len;
  95. + }
  96. +
  97. + return attr_new;
  98. +}
  99. static struct radius_session *
  100. radius_server_get_new_session(struct radius_server_data *data,
  101. @@ -586,7 +623,7 @@ radius_server_get_new_session(struct rad
  102. eap_user_free(tmp);
  103. return NULL;
  104. }
  105. - sess->accept_attr = tmp->accept_attr;
  106. + sess->accept_attr = radius_server_copy_attr(tmp->accept_attr);
  107. sess->macacl = tmp->macacl;
  108. eap_user_free(tmp);
  109. @@ -923,11 +960,10 @@ radius_server_encapsulate_eap(struct rad
  110. }
  111. if (code == RADIUS_CODE_ACCESS_ACCEPT) {
  112. - struct hostapd_radius_attr *attr;
  113. - for (attr = sess->accept_attr; attr; attr = attr->next) {
  114. - if (!radius_msg_add_attr(msg, attr->type,
  115. - wpabuf_head(attr->val),
  116. - wpabuf_len(attr->val))) {
  117. + struct radius_accept_attr *attr;
  118. + for (attr = sess->accept_attr; attr->data; attr++) {
  119. + if (!radius_msg_add_attr(msg, attr->type, attr->data,
  120. + attr->len)) {
  121. wpa_printf(MSG_ERROR, "Could not add RADIUS attribute");
  122. radius_msg_free(msg);
  123. return NULL;
  124. @@ -1023,11 +1059,10 @@ radius_server_macacl(struct radius_serve
  125. }
  126. if (code == RADIUS_CODE_ACCESS_ACCEPT) {
  127. - struct hostapd_radius_attr *attr;
  128. - for (attr = sess->accept_attr; attr; attr = attr->next) {
  129. - if (!radius_msg_add_attr(msg, attr->type,
  130. - wpabuf_head(attr->val),
  131. - wpabuf_len(attr->val))) {
  132. + struct radius_accept_attr *attr;
  133. + for (attr = sess->accept_attr; attr->data; attr++) {
  134. + if (!radius_msg_add_attr(msg, attr->type, attr->data,
  135. + attr->len)) {
  136. wpa_printf(MSG_ERROR, "Could not add RADIUS attribute");
  137. radius_msg_free(msg);
  138. return NULL;
  139. @@ -2335,7 +2370,7 @@ static int radius_server_get_eap_user(vo
  140. ret = data->get_eap_user(data->conf_ctx, identity, identity_len,
  141. phase2, user);
  142. if (ret == 0 && user) {
  143. - sess->accept_attr = user->accept_attr;
  144. + sess->accept_attr = radius_server_copy_attr(user->accept_attr);
  145. sess->macacl = user->macacl;
  146. sess->t_c_timestamp = user->t_c_timestamp;
  147. }