eap_example_peer.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  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 software may be distributed under the terms of the BSD license.
  7. * See README for more details.
  8. */
  9. #include "includes.h"
  10. #include "common.h"
  11. #include "eap_peer/eap.h"
  12. #include "eap_peer/eap_config.h"
  13. #include "wpabuf.h"
  14. void eap_example_server_rx(const u8 *data, size_t data_len);
  15. struct eap_peer_ctx {
  16. Boolean eapSuccess;
  17. Boolean eapRestart;
  18. Boolean eapFail;
  19. Boolean eapResp;
  20. Boolean eapNoResp;
  21. Boolean eapReq;
  22. Boolean portEnabled;
  23. Boolean altAccept; /* for EAP */
  24. Boolean altReject; /* for EAP */
  25. struct wpabuf *eapReqData; /* for EAP */
  26. unsigned int idleWhile; /* for EAP state machine */
  27. struct eap_peer_config eap_config;
  28. struct eap_sm *eap;
  29. };
  30. static struct eap_peer_ctx eap_ctx;
  31. static struct eap_peer_config * peer_get_config(void *ctx)
  32. {
  33. struct eap_peer_ctx *peer = ctx;
  34. return &peer->eap_config;
  35. }
  36. static Boolean peer_get_bool(void *ctx, enum eapol_bool_var variable)
  37. {
  38. struct eap_peer_ctx *peer = ctx;
  39. if (peer == NULL)
  40. return FALSE;
  41. switch (variable) {
  42. case EAPOL_eapSuccess:
  43. return peer->eapSuccess;
  44. case EAPOL_eapRestart:
  45. return peer->eapRestart;
  46. case EAPOL_eapFail:
  47. return peer->eapFail;
  48. case EAPOL_eapResp:
  49. return peer->eapResp;
  50. case EAPOL_eapNoResp:
  51. return peer->eapNoResp;
  52. case EAPOL_eapReq:
  53. return peer->eapReq;
  54. case EAPOL_portEnabled:
  55. return peer->portEnabled;
  56. case EAPOL_altAccept:
  57. return peer->altAccept;
  58. case EAPOL_altReject:
  59. return peer->altReject;
  60. }
  61. return FALSE;
  62. }
  63. static void peer_set_bool(void *ctx, enum eapol_bool_var variable,
  64. Boolean value)
  65. {
  66. struct eap_peer_ctx *peer = ctx;
  67. if (peer == NULL)
  68. return;
  69. switch (variable) {
  70. case EAPOL_eapSuccess:
  71. peer->eapSuccess = value;
  72. break;
  73. case EAPOL_eapRestart:
  74. peer->eapRestart = value;
  75. break;
  76. case EAPOL_eapFail:
  77. peer->eapFail = value;
  78. break;
  79. case EAPOL_eapResp:
  80. peer->eapResp = value;
  81. break;
  82. case EAPOL_eapNoResp:
  83. peer->eapNoResp = value;
  84. break;
  85. case EAPOL_eapReq:
  86. peer->eapReq = value;
  87. break;
  88. case EAPOL_portEnabled:
  89. peer->portEnabled = value;
  90. break;
  91. case EAPOL_altAccept:
  92. peer->altAccept = value;
  93. break;
  94. case EAPOL_altReject:
  95. peer->altReject = value;
  96. break;
  97. }
  98. }
  99. static unsigned int peer_get_int(void *ctx, enum eapol_int_var variable)
  100. {
  101. struct eap_peer_ctx *peer = ctx;
  102. if (peer == NULL)
  103. return 0;
  104. switch (variable) {
  105. case EAPOL_idleWhile:
  106. return peer->idleWhile;
  107. }
  108. return 0;
  109. }
  110. static void peer_set_int(void *ctx, enum eapol_int_var variable,
  111. unsigned int value)
  112. {
  113. struct eap_peer_ctx *peer = ctx;
  114. if (peer == NULL)
  115. return;
  116. switch (variable) {
  117. case EAPOL_idleWhile:
  118. peer->idleWhile = value;
  119. break;
  120. }
  121. }
  122. static struct wpabuf * peer_get_eapReqData(void *ctx)
  123. {
  124. struct eap_peer_ctx *peer = ctx;
  125. if (peer == NULL || peer->eapReqData == NULL)
  126. return NULL;
  127. return peer->eapReqData;
  128. }
  129. static void peer_set_config_blob(void *ctx, struct wpa_config_blob *blob)
  130. {
  131. printf("TODO: %s\n", __func__);
  132. }
  133. static const struct wpa_config_blob *
  134. peer_get_config_blob(void *ctx, const char *name)
  135. {
  136. printf("TODO: %s\n", __func__);
  137. return NULL;
  138. }
  139. static void peer_notify_pending(void *ctx)
  140. {
  141. printf("TODO: %s\n", __func__);
  142. }
  143. static int eap_peer_register_methods(void)
  144. {
  145. int ret = 0;
  146. #ifdef EAP_MD5
  147. if (ret == 0)
  148. ret = eap_peer_md5_register();
  149. #endif /* EAP_MD5 */
  150. #ifdef EAP_TLS
  151. if (ret == 0)
  152. ret = eap_peer_tls_register();
  153. #endif /* EAP_TLS */
  154. #ifdef EAP_MSCHAPv2
  155. if (ret == 0)
  156. ret = eap_peer_mschapv2_register();
  157. #endif /* EAP_MSCHAPv2 */
  158. #ifdef EAP_PEAP
  159. if (ret == 0)
  160. ret = eap_peer_peap_register();
  161. #endif /* EAP_PEAP */
  162. #ifdef EAP_TTLS
  163. if (ret == 0)
  164. ret = eap_peer_ttls_register();
  165. #endif /* EAP_TTLS */
  166. #ifdef EAP_GTC
  167. if (ret == 0)
  168. ret = eap_peer_gtc_register();
  169. #endif /* EAP_GTC */
  170. #ifdef EAP_OTP
  171. if (ret == 0)
  172. ret = eap_peer_otp_register();
  173. #endif /* EAP_OTP */
  174. #ifdef EAP_SIM
  175. if (ret == 0)
  176. ret = eap_peer_sim_register();
  177. #endif /* EAP_SIM */
  178. #ifdef EAP_LEAP
  179. if (ret == 0)
  180. ret = eap_peer_leap_register();
  181. #endif /* EAP_LEAP */
  182. #ifdef EAP_PSK
  183. if (ret == 0)
  184. ret = eap_peer_psk_register();
  185. #endif /* EAP_PSK */
  186. #ifdef EAP_AKA
  187. if (ret == 0)
  188. ret = eap_peer_aka_register();
  189. #endif /* EAP_AKA */
  190. #ifdef EAP_AKA_PRIME
  191. if (ret == 0)
  192. ret = eap_peer_aka_prime_register();
  193. #endif /* EAP_AKA_PRIME */
  194. #ifdef EAP_FAST
  195. if (ret == 0)
  196. ret = eap_peer_fast_register();
  197. #endif /* EAP_FAST */
  198. #ifdef EAP_PAX
  199. if (ret == 0)
  200. ret = eap_peer_pax_register();
  201. #endif /* EAP_PAX */
  202. #ifdef EAP_SAKE
  203. if (ret == 0)
  204. ret = eap_peer_sake_register();
  205. #endif /* EAP_SAKE */
  206. #ifdef EAP_GPSK
  207. if (ret == 0)
  208. ret = eap_peer_gpsk_register();
  209. #endif /* EAP_GPSK */
  210. #ifdef EAP_WSC
  211. if (ret == 0)
  212. ret = eap_peer_wsc_register();
  213. #endif /* EAP_WSC */
  214. #ifdef EAP_IKEV2
  215. if (ret == 0)
  216. ret = eap_peer_ikev2_register();
  217. #endif /* EAP_IKEV2 */
  218. #ifdef EAP_VENDOR_TEST
  219. if (ret == 0)
  220. ret = eap_peer_vendor_test_register();
  221. #endif /* EAP_VENDOR_TEST */
  222. #ifdef EAP_TNC
  223. if (ret == 0)
  224. ret = eap_peer_tnc_register();
  225. #endif /* EAP_TNC */
  226. return ret;
  227. }
  228. static struct eapol_callbacks eap_cb;
  229. static struct eap_config eap_conf;
  230. int eap_example_peer_init(void)
  231. {
  232. if (eap_peer_register_methods() < 0)
  233. return -1;
  234. os_memset(&eap_ctx, 0, sizeof(eap_ctx));
  235. eap_ctx.eap_config.identity = (u8 *) os_strdup("user");
  236. eap_ctx.eap_config.identity_len = 4;
  237. eap_ctx.eap_config.password = (u8 *) os_strdup("password");
  238. eap_ctx.eap_config.password_len = 8;
  239. eap_ctx.eap_config.ca_cert = (u8 *) os_strdup("ca.pem");
  240. eap_ctx.eap_config.fragment_size = 1398;
  241. os_memset(&eap_cb, 0, sizeof(eap_cb));
  242. eap_cb.get_config = peer_get_config;
  243. eap_cb.get_bool = peer_get_bool;
  244. eap_cb.set_bool = peer_set_bool;
  245. eap_cb.get_int = peer_get_int;
  246. eap_cb.set_int = peer_set_int;
  247. eap_cb.get_eapReqData = peer_get_eapReqData;
  248. eap_cb.set_config_blob = peer_set_config_blob;
  249. eap_cb.get_config_blob = peer_get_config_blob;
  250. eap_cb.notify_pending = peer_notify_pending;
  251. os_memset(&eap_conf, 0, sizeof(eap_conf));
  252. eap_ctx.eap = eap_peer_sm_init(&eap_ctx, &eap_cb, &eap_ctx, &eap_conf);
  253. if (eap_ctx.eap == NULL)
  254. return -1;
  255. /* Enable "port" to allow authentication */
  256. eap_ctx.portEnabled = TRUE;
  257. return 0;
  258. }
  259. void eap_example_peer_deinit(void)
  260. {
  261. eap_peer_sm_deinit(eap_ctx.eap);
  262. eap_peer_unregister_methods();
  263. wpabuf_free(eap_ctx.eapReqData);
  264. os_free(eap_ctx.eap_config.identity);
  265. os_free(eap_ctx.eap_config.password);
  266. os_free(eap_ctx.eap_config.ca_cert);
  267. }
  268. int eap_example_peer_step(void)
  269. {
  270. int res;
  271. res = eap_peer_sm_step(eap_ctx.eap);
  272. if (eap_ctx.eapResp) {
  273. struct wpabuf *resp;
  274. printf("==> Response\n");
  275. eap_ctx.eapResp = FALSE;
  276. resp = eap_get_eapRespData(eap_ctx.eap);
  277. if (resp) {
  278. /* Send EAP response to the server */
  279. eap_example_server_rx(wpabuf_head(resp),
  280. wpabuf_len(resp));
  281. wpabuf_free(resp);
  282. }
  283. }
  284. if (eap_ctx.eapSuccess) {
  285. res = 0;
  286. if (eap_key_available(eap_ctx.eap)) {
  287. const u8 *key;
  288. size_t key_len;
  289. key = eap_get_eapKeyData(eap_ctx.eap, &key_len);
  290. wpa_hexdump(MSG_DEBUG, "EAP keying material",
  291. key, key_len);
  292. }
  293. }
  294. return res;
  295. }
  296. void eap_example_peer_rx(const u8 *data, size_t data_len)
  297. {
  298. /* Make received EAP message available to the EAP library */
  299. eap_ctx.eapReq = TRUE;
  300. wpabuf_free(eap_ctx.eapReqData);
  301. eap_ctx.eapReqData = wpabuf_alloc_copy(data, data_len);
  302. }