eap_server_identity.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. /*
  2. * hostapd / EAP-Identity
  3. * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi>
  4. *
  5. * This software may be distributed under the terms of the BSD license.
  6. * See README for more details.
  7. */
  8. #include "includes.h"
  9. #include "common.h"
  10. #include "eap_i.h"
  11. struct eap_identity_data {
  12. enum { CONTINUE, SUCCESS, FAILURE } state;
  13. int pick_up;
  14. };
  15. static void * eap_identity_init(struct eap_sm *sm)
  16. {
  17. struct eap_identity_data *data;
  18. data = os_zalloc(sizeof(*data));
  19. if (data == NULL)
  20. return NULL;
  21. data->state = CONTINUE;
  22. return data;
  23. }
  24. static void * eap_identity_initPickUp(struct eap_sm *sm)
  25. {
  26. struct eap_identity_data *data;
  27. data = eap_identity_init(sm);
  28. if (data) {
  29. data->pick_up = 1;
  30. }
  31. return data;
  32. }
  33. static void eap_identity_reset(struct eap_sm *sm, void *priv)
  34. {
  35. struct eap_identity_data *data = priv;
  36. os_free(data);
  37. }
  38. static struct wpabuf * eap_identity_buildReq(struct eap_sm *sm, void *priv,
  39. u8 id)
  40. {
  41. struct eap_identity_data *data = priv;
  42. struct wpabuf *req;
  43. const char *req_data;
  44. size_t req_data_len;
  45. if (sm->eapol_cb->get_eap_req_id_text) {
  46. req_data = sm->eapol_cb->get_eap_req_id_text(sm->eapol_ctx,
  47. &req_data_len);
  48. } else {
  49. req_data = NULL;
  50. req_data_len = 0;
  51. }
  52. req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_IDENTITY, req_data_len,
  53. EAP_CODE_REQUEST, id);
  54. if (req == NULL) {
  55. wpa_printf(MSG_ERROR, "EAP-Identity: Failed to allocate "
  56. "memory for request");
  57. data->state = FAILURE;
  58. return NULL;
  59. }
  60. wpabuf_put_data(req, req_data, req_data_len);
  61. return req;
  62. }
  63. static Boolean eap_identity_check(struct eap_sm *sm, void *priv,
  64. struct wpabuf *respData)
  65. {
  66. const u8 *pos;
  67. size_t len;
  68. pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_IDENTITY,
  69. respData, &len);
  70. if (pos == NULL) {
  71. wpa_printf(MSG_INFO, "EAP-Identity: Invalid frame");
  72. return TRUE;
  73. }
  74. return FALSE;
  75. }
  76. static void eap_identity_process(struct eap_sm *sm, void *priv,
  77. struct wpabuf *respData)
  78. {
  79. struct eap_identity_data *data = priv;
  80. const u8 *pos;
  81. size_t len;
  82. char *buf;
  83. if (data->pick_up) {
  84. if (eap_identity_check(sm, data, respData)) {
  85. wpa_printf(MSG_DEBUG, "EAP-Identity: failed to pick "
  86. "up already started negotiation");
  87. data->state = FAILURE;
  88. return;
  89. }
  90. data->pick_up = 0;
  91. }
  92. pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_IDENTITY,
  93. respData, &len);
  94. if (pos == NULL)
  95. return; /* Should not happen - frame already validated */
  96. wpa_hexdump_ascii(MSG_DEBUG, "EAP-Identity: Peer identity", pos, len);
  97. buf = os_malloc(len * 4 + 1);
  98. if (buf) {
  99. printf_encode(buf, len * 4 + 1, pos, len);
  100. eap_log_msg(sm, "EAP-Response/Identity '%s'", buf);
  101. os_free(buf);
  102. }
  103. if (sm->identity)
  104. sm->update_user = TRUE;
  105. os_free(sm->identity);
  106. sm->identity = os_malloc(len ? len : 1);
  107. if (sm->identity == NULL) {
  108. data->state = FAILURE;
  109. } else {
  110. os_memcpy(sm->identity, pos, len);
  111. sm->identity_len = len;
  112. data->state = SUCCESS;
  113. }
  114. }
  115. static Boolean eap_identity_isDone(struct eap_sm *sm, void *priv)
  116. {
  117. struct eap_identity_data *data = priv;
  118. return data->state != CONTINUE;
  119. }
  120. static Boolean eap_identity_isSuccess(struct eap_sm *sm, void *priv)
  121. {
  122. struct eap_identity_data *data = priv;
  123. return data->state == SUCCESS;
  124. }
  125. int eap_server_identity_register(void)
  126. {
  127. struct eap_method *eap;
  128. int ret;
  129. eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,
  130. EAP_VENDOR_IETF, EAP_TYPE_IDENTITY,
  131. "Identity");
  132. if (eap == NULL)
  133. return -1;
  134. eap->init = eap_identity_init;
  135. eap->initPickUp = eap_identity_initPickUp;
  136. eap->reset = eap_identity_reset;
  137. eap->buildReq = eap_identity_buildReq;
  138. eap->check = eap_identity_check;
  139. eap->process = eap_identity_process;
  140. eap->isDone = eap_identity_isDone;
  141. eap->isSuccess = eap_identity_isSuccess;
  142. ret = eap_server_method_register(eap);
  143. if (ret)
  144. eap_server_method_free(eap);
  145. return ret;
  146. }