eap_otp.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. /*
  2. * EAP peer method: EAP-OTP (RFC 3748)
  3. * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License version 2 as
  7. * published by the Free Software Foundation.
  8. *
  9. * Alternatively, this software may be distributed under the terms of BSD
  10. * license.
  11. *
  12. * See README and COPYING for more details.
  13. */
  14. #include "includes.h"
  15. #include "common.h"
  16. #include "eap_i.h"
  17. static void * eap_otp_init(struct eap_sm *sm)
  18. {
  19. /* No need for private data. However, must return non-NULL to indicate
  20. * success. */
  21. return (void *) 1;
  22. }
  23. static void eap_otp_deinit(struct eap_sm *sm, void *priv)
  24. {
  25. }
  26. static struct wpabuf * eap_otp_process(struct eap_sm *sm, void *priv,
  27. struct eap_method_ret *ret,
  28. const struct wpabuf *reqData)
  29. {
  30. struct wpabuf *resp;
  31. const u8 *pos, *password;
  32. size_t password_len, len;
  33. int otp;
  34. pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_OTP, reqData, &len);
  35. if (pos == NULL) {
  36. ret->ignore = TRUE;
  37. return NULL;
  38. }
  39. wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-OTP: Request message",
  40. pos, len);
  41. password = eap_get_config_otp(sm, &password_len);
  42. if (password)
  43. otp = 1;
  44. else {
  45. password = eap_get_config_password(sm, &password_len);
  46. otp = 0;
  47. }
  48. if (password == NULL) {
  49. wpa_printf(MSG_INFO, "EAP-OTP: Password not configured");
  50. eap_sm_request_otp(sm, (const char *) pos, len);
  51. ret->ignore = TRUE;
  52. return NULL;
  53. }
  54. ret->ignore = FALSE;
  55. ret->methodState = METHOD_DONE;
  56. ret->decision = DECISION_COND_SUCC;
  57. ret->allowNotifications = FALSE;
  58. resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_OTP, password_len,
  59. EAP_CODE_RESPONSE, eap_get_id(reqData));
  60. if (resp == NULL)
  61. return NULL;
  62. wpabuf_put_data(resp, password, password_len);
  63. wpa_hexdump_ascii_key(MSG_MSGDUMP, "EAP-OTP: Response",
  64. password, password_len);
  65. if (otp) {
  66. wpa_printf(MSG_DEBUG, "EAP-OTP: Forgetting used password");
  67. eap_clear_config_otp(sm);
  68. }
  69. return resp;
  70. }
  71. int eap_peer_otp_register(void)
  72. {
  73. struct eap_method *eap;
  74. int ret;
  75. eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION,
  76. EAP_VENDOR_IETF, EAP_TYPE_OTP, "OTP");
  77. if (eap == NULL)
  78. return -1;
  79. eap->init = eap_otp_init;
  80. eap->deinit = eap_otp_deinit;
  81. eap->process = eap_otp_process;
  82. ret = eap_peer_method_register(eap);
  83. if (ret)
  84. eap_peer_method_free(eap);
  85. return ret;
  86. }