eap_example_peer.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. /*
  2. * Example application showing how EAP peer code from wpa_supplicant can be
  3. * used as a library.
  4. * Copyright (c) 2007, Jouni Malinen <j@w1.fi>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License version 2 as
  8. * published by the Free Software Foundation.
  9. *
  10. * Alternatively, this software may be distributed under the terms of BSD
  11. * license.
  12. *
  13. * See README and COPYING for more details.
  14. */
  15. #include "includes.h"
  16. #include "common.h"
  17. #include "eap_peer/eap.h"
  18. #include "eap_peer/eap_config.h"
  19. #include "wpabuf.h"
  20. void eap_example_server_rx(const u8 *data, size_t data_len);
  21. struct eap_peer_ctx {
  22. Boolean eapSuccess;
  23. Boolean eapRestart;
  24. Boolean eapFail;
  25. Boolean eapResp;
  26. Boolean eapNoResp;
  27. Boolean eapReq;
  28. Boolean portEnabled;
  29. Boolean altAccept; /* for EAP */
  30. Boolean altReject; /* for EAP */
  31. struct wpabuf *eapReqData; /* for EAP */
  32. unsigned int idleWhile; /* for EAP state machine */
  33. struct eap_peer_config eap_config;
  34. struct eap_sm *eap;
  35. };
  36. static struct eap_peer_ctx eap_ctx;
  37. static struct eap_peer_config * peer_get_config(void *ctx)
  38. {
  39. struct eap_peer_ctx *peer = ctx;
  40. return &peer->eap_config;
  41. }
  42. static Boolean peer_get_bool(void *ctx, enum eapol_bool_var variable)
  43. {
  44. struct eap_peer_ctx *peer = ctx;
  45. if (peer == NULL)
  46. return FALSE;
  47. switch (variable) {
  48. case EAPOL_eapSuccess:
  49. return peer->eapSuccess;
  50. case EAPOL_eapRestart:
  51. return peer->eapRestart;
  52. case EAPOL_eapFail:
  53. return peer->eapFail;
  54. case EAPOL_eapResp:
  55. return peer->eapResp;
  56. case EAPOL_eapNoResp:
  57. return peer->eapNoResp;
  58. case EAPOL_eapReq:
  59. return peer->eapReq;
  60. case EAPOL_portEnabled:
  61. return peer->portEnabled;
  62. case EAPOL_altAccept:
  63. return peer->altAccept;
  64. case EAPOL_altReject:
  65. return peer->altReject;
  66. }
  67. return FALSE;
  68. }
  69. static void peer_set_bool(void *ctx, enum eapol_bool_var variable,
  70. Boolean value)
  71. {
  72. struct eap_peer_ctx *peer = ctx;
  73. if (peer == NULL)
  74. return;
  75. switch (variable) {
  76. case EAPOL_eapSuccess:
  77. peer->eapSuccess = value;
  78. break;
  79. case EAPOL_eapRestart:
  80. peer->eapRestart = value;
  81. break;
  82. case EAPOL_eapFail:
  83. peer->eapFail = value;
  84. break;
  85. case EAPOL_eapResp:
  86. peer->eapResp = value;
  87. break;
  88. case EAPOL_eapNoResp:
  89. peer->eapNoResp = value;
  90. break;
  91. case EAPOL_eapReq:
  92. peer->eapReq = value;
  93. break;
  94. case EAPOL_portEnabled:
  95. peer->portEnabled = value;
  96. break;
  97. case EAPOL_altAccept:
  98. peer->altAccept = value;
  99. break;
  100. case EAPOL_altReject:
  101. peer->altReject = value;
  102. break;
  103. }
  104. }
  105. static unsigned int peer_get_int(void *ctx, enum eapol_int_var variable)
  106. {
  107. struct eap_peer_ctx *peer = ctx;
  108. if (peer == NULL)
  109. return 0;
  110. switch (variable) {
  111. case EAPOL_idleWhile:
  112. return peer->idleWhile;
  113. }
  114. return 0;
  115. }
  116. static void peer_set_int(void *ctx, enum eapol_int_var variable,
  117. unsigned int value)
  118. {
  119. struct eap_peer_ctx *peer = ctx;
  120. if (peer == NULL)
  121. return;
  122. switch (variable) {
  123. case EAPOL_idleWhile:
  124. peer->idleWhile = value;
  125. break;
  126. }
  127. }
  128. static struct wpabuf * peer_get_eapReqData(void *ctx)
  129. {
  130. struct eap_peer_ctx *peer = ctx;
  131. if (peer == NULL || peer->eapReqData == NULL)
  132. return NULL;
  133. return peer->eapReqData;
  134. }
  135. static void peer_set_config_blob(void *ctx, struct wpa_config_blob *blob)
  136. {
  137. printf("TODO: %s\n", __func__);
  138. }
  139. static const struct wpa_config_blob *
  140. peer_get_config_blob(void *ctx, const char *name)
  141. {
  142. printf("TODO: %s\n", __func__);
  143. return NULL;
  144. }
  145. static void peer_notify_pending(void *ctx)
  146. {
  147. printf("TODO: %s\n", __func__);
  148. }
  149. static struct eapol_callbacks eap_cb;
  150. static struct eap_config eap_conf;
  151. int eap_example_peer_init(void)
  152. {
  153. if (eap_peer_register_methods() < 0)
  154. return -1;
  155. os_memset(&eap_ctx, 0, sizeof(eap_ctx));
  156. eap_ctx.eap_config.identity = (u8 *) os_strdup("user");
  157. eap_ctx.eap_config.identity_len = 4;
  158. eap_ctx.eap_config.password = (u8 *) os_strdup("password");
  159. eap_ctx.eap_config.password_len = 8;
  160. eap_ctx.eap_config.ca_cert = (u8 *) os_strdup("ca.pem");
  161. eap_ctx.eap_config.fragment_size = 1398;
  162. os_memset(&eap_cb, 0, sizeof(eap_cb));
  163. eap_cb.get_config = peer_get_config;
  164. eap_cb.get_bool = peer_get_bool;
  165. eap_cb.set_bool = peer_set_bool;
  166. eap_cb.get_int = peer_get_int;
  167. eap_cb.set_int = peer_set_int;
  168. eap_cb.get_eapReqData = peer_get_eapReqData;
  169. eap_cb.set_config_blob = peer_set_config_blob;
  170. eap_cb.get_config_blob = peer_get_config_blob;
  171. eap_cb.notify_pending = peer_notify_pending;
  172. os_memset(&eap_conf, 0, sizeof(eap_conf));
  173. eap_ctx.eap = eap_peer_sm_init(&eap_ctx, &eap_cb, &eap_ctx, &eap_conf);
  174. if (eap_ctx.eap == NULL)
  175. return -1;
  176. /* Enable "port" to allow authentication */
  177. eap_ctx.portEnabled = TRUE;
  178. return 0;
  179. }
  180. void eap_example_peer_deinit(void)
  181. {
  182. eap_peer_sm_deinit(eap_ctx.eap);
  183. eap_peer_unregister_methods();
  184. wpabuf_free(eap_ctx.eapReqData);
  185. os_free(eap_ctx.eap_config.identity);
  186. os_free(eap_ctx.eap_config.password);
  187. os_free(eap_ctx.eap_config.ca_cert);
  188. }
  189. int eap_example_peer_step(void)
  190. {
  191. int res;
  192. res = eap_peer_sm_step(eap_ctx.eap);
  193. if (eap_ctx.eapResp) {
  194. struct wpabuf *resp;
  195. printf("==> Response\n");
  196. eap_ctx.eapResp = FALSE;
  197. resp = eap_get_eapRespData(eap_ctx.eap);
  198. if (resp) {
  199. /* Send EAP response to the server */
  200. eap_example_server_rx(wpabuf_head(resp),
  201. wpabuf_len(resp));
  202. wpabuf_free(resp);
  203. }
  204. }
  205. if (eap_ctx.eapSuccess) {
  206. res = 0;
  207. if (eap_key_available(eap_ctx.eap)) {
  208. const u8 *key;
  209. size_t key_len;
  210. key = eap_get_eapKeyData(eap_ctx.eap, &key_len);
  211. wpa_hexdump(MSG_DEBUG, "EAP keying material",
  212. key, key_len);
  213. }
  214. }
  215. return res;
  216. }
  217. void eap_example_peer_rx(const u8 *data, size_t data_len)
  218. {
  219. /* Make received EAP message available to the EAP library */
  220. eap_ctx.eapReq = TRUE;
  221. wpabuf_free(eap_ctx.eapReqData);
  222. eap_ctx.eapReqData = wpabuf_alloc_copy(data, data_len);
  223. }