eap_example_peer.c 7.4 KB

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