No one should be using it.
`rlm_eap/types/rlm_eap_tls` | EAP-TLS based authentication.
`rlm_eap/types/rlm_eap_ttls` | TTLS based authentication.
`rlm_eap/types/rlm_eap_peap` | Windows PEAP based authentication.
-`rlm_eap/types/rlm_eap_leap` | Cisco LEAP authentication.
`rlm_eap/types/rlm_eap_sim` | EAP-SIM (GSM) based authentication
## Configuration
process Access-Request {
eap
}
-
- # If you are proxying EAP-LEAP requests
- # This is required to make LEAP work.
- post-proxy {
- eap
- }
```
2. My Userbase is in LDAP and I want to use EAP-MD5 authentication
## Installation
-EAP, EAP-MD5, and Cisco LEAP do not require any additional packages.
+EAP, EAP-MD5, and EAP-MSCHAPv2 do not require any additional packages.
Freeradius contains all the required packages.
For EAP-TLS, EAP-TTLS, and PEAP, OPENSSL, <http://www.openssl.org/>,
+++ /dev/null
- Cisco LEAP protocol description
-
- CLEAP = Cisco LEAP
- LEAP = Lightweight EAP
- EAP = Extensible Authentication Protocol
-
- _________________________________________________________________
-
-by:
- cameron macnally <descriptive2001@yahoo.com>
-
-date:
- Thu, 6 Sep 2001 03:39:40 -0700 (PDT)
-
-generated from
- http://lists.cistron.nl/pipermail/cistron-radius/2001-September/002042.html
-
-Adam Sulmicki <adam@cfar.umd.edu>
- since I could not find any ASCII version I took above html version
- and formated it as it is below.
-
-Alan DeKok <aland@freeradius.org>
- The information in the original posting wasn't entirely
- correct, but it was close. This updated version is correct,
- and contains additional specifics not found in the original post.
-
- _________________________________________________________________
-
-
-This document describes the LEAP authentication protocol as used by Cisco
-Aironet wireless routers etc. It was deduced by analysis of packets passed
-between an Aironet and Cisco ACS.
-
-Relevant RFCs are: 2284, 2716, 2433.
-
-LEAP is a type of Radius EAP protocol (see RFC draft-ietf-radius-eap-05.txt
-"Extensible Authentication Protocol Support in RADIUS"). The EAP type for
-LEAP is 17 (0x11). It is used to authenticate access by a wireless client
-(typically a laptop or pc) to a wireless router, typically a Cisco Aironet
-base station.
-
-Definitions
-AP: Access Point (the Aironet base station)
-RS: Radius Server
-APC: Access Point Challenge
-APR: Access Point Response
-PC: Peer Challenge
-PR: Peer Response
-PW: Users plaintext ASCII password
-SK: Session Key
-SS: Shared Secret shared between AP (or upstream proxy) and RS
-AUTH: The 16 octet Radius authenticator of the incomintg request
-
-A typical successful LEAP authentication sequence consists of the
-following Radius packets passed between the wireless access point (AP) and
-the Radius server (RS). Each packet contains an EAP-Message as described
-below. The EAP Message-Authenticator attribute is always present as usual
-for EAP.
-
-The general description of the protocol is:
-
-1. AP->RS: Access-Request/EAP Identity, containing the name of the
- user to be authenticated
-
-2. RS->AP: Access-Challenge/EAP Request/LEAP, containing a 8 octet random
- MSCHAP Peer Challenge (PC) + State
-
-3. AP->RS: Access-Request/EAP Response/LEAP, containing the 24 octet MSCHAP
- response to the challenge in 2 above (PR) + State
-
-4. RS->AP: Access-Challenge/EAP Success (with EAP id++)
- + State (may be different than the satate send in <2>)
-
-5. AP->RS: Access-Request/EAP Request/LEAP, containing 8 octet Access Point
- Challenge (APC) + State
-
-6. RS->AP: Radius Access-Accept/EAP Response/LEAP, containing 24 octet
- response to the challenge in 5 above (APR), plus a session key sent
- in a cisco-avpair vendor-specific attribute:
-
- Cisco-AVPair = "leap:session-key=..."
-
- where the '...' are 34 binary octets of encrypted data. This data MUST
- follow the '=', and is NOT in ASCII.
-
-LEAP data is carried in an EAP-Message in the Type-Data subfield. The
-format of the Type-Data subfield is:
-
-1 octet LEAP protocol version number, currently always 0x01.
-1 unused octet, currently always 0x00.
-1 octet byte count for the following binary data
-m octets of binary data
-n octets, the name of the user being authenticated
-
-So, for example, packet 2 in the above sequence, containg the access point
-challenge (APC) would contain an EAP-Message Request (Code 0x01) attribute
-something like this:
-
- 0 1 2 3
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Code 0x01 | Identifier | Length |
-
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Type 0x11 | Version 0x01 | Unused 0x00 | Count 0x08 |
-
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Peer Challenge |
-
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Peer Challenge |
-
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | User Name .....
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-
-
-
-Count is 8 octets since the Peer challenge is 8 bytes.
-count is 24 for EAP response, with MSCHAP response.
-Length is the total number of octets in the EAP-Message.
-
-The Session Key (SK) is sent from RS to AP in the final packet. It is
-carried in a cisco-avpair vendor specific radius attribute. The value of
-the attribute is: "leap:session-key=nnnn" where nnnn is 34 octets of
-binary data as described in SK below.
-
-Algorithms for each field are described below. Function names are those
-from RFC 2433. '+' means concatenation. mppe_encrypt is the algorithm for
-encrypting MS-MPPE-Send-Key as described in RFC 2548.txt, which is
-also the same as the 'Tunnel-Password' encryption.
-
-PC: 8 octets random binary data sent to AP
-
-PR: 24 octets NtChallengeResponse(PC, Unicode(PW))
- e.g. AP sends MS-CHAP response to RADIUS server challenge.
-
-APC: 8 octets random binary data sent by the AP
-
-MPPEHASH: 16 octets NtPasswordHash(NtPasswordHash(Unicode(PW))))
-
-APR: 24 octets ChallengeResponse(APC, MPPEHASH)
- e.g. RADIUS server sends MS-CHAP response to AP challenge.
-
-SK: 34 octets mppe_encrypt(SS, AUTH,MD5Digest(MPPEHASH + APC + APR + PC + PR))
- via rad_tunnel_pwencode()
-
-Notes:
-1. Some versions of Cisco ACS incorrectly drop the first 2 bytes of the
-user name at the end of the EAP-MEssage in the Peer Challenge packet.
-
-2. If the user name does not exist, the response to packet 1 is a
- Radius Access-Reject/EAP Failure
-
- _________________________________________________________________
-
The `+virtual_server+` configuration has been removed from EAP-PWD. The
module now looks for &request.control:Cleartext-Password.
+=== rlm_eap_leap
+
+The LEAP protocol has been removed from the server. It is insecure,
+non-standard, and should not be used.
+
=== rlm_exec
Exec-Program and Exec-Program-Wait have been removed.
#
type = md5
# type = pwd
-# type = leap
type = gtc
type = tls
type = ttls
# fragment_size:: This has the same meaning as for TLS.
#
# fragment_size = 1020
-# }
-
- #
- # ### Cisco LEAP
- #
- # [WARNING]
- # ====
- # We do not recommend using LEAP in new deployments.
- # See: http://www.securiteam.com/tools/5TP012ACKE.html
- # ====
- #
- # Cisco LEAP uses the MS-CHAP algorithm (but not the MS-CHAP
- # attributes) to perform it's authentication.
- #
- # As a result, LEAP *requires* access to the plain-text User-Password,
- # or the NT-Password attributes.
- #
-# leap {
# }
#
CONFIG_EAP_PAX=y
# LEAP
-CONFIG_EAP_LEAP=y
+CONFIG_EAP_LEAP=n
# EAP-AKA (enable CONFIG_PCSC, if EAP-AKA is used)
CONFIG_EAP_AKA=y
CONFIG_EAP_PAX=y
# LEAP
-CONFIG_EAP_LEAP=y
+CONFIG_EAP_LEAP=n
# EAP-AKA (enable CONFIG_PCSC, if EAP-AKA is used)
CONFIG_EAP_AKA=y
CONFIG_EAP_PAX=y
# LEAP
-CONFIG_EAP_LEAP=y
+CONFIG_EAP_LEAP=n
# EAP-AKA (enable CONFIG_PCSC, if EAP-AKA is used)
CONFIG_EAP_AKA=y
/*
* The Id for the EAP packet to the NAS wasn't set.
* Do so now.
- *
- * LEAP requires the Id to be incremented on EAP-Success
- * in Stage 4, so that we can carry on the conversation
- * where the client asks us to authenticate ourselves
- * in stage 5.
*/
if (!eap_round->set_request_id) {
/*
if (!request->reply->code) switch (reply->code) {
case FR_EAP_CODE_RESPONSE:
request->reply->code = FR_CODE_ACCESS_ACCEPT;
- rcode = RLM_MODULE_HANDLED; /* leap weirdness */
+ rcode = RLM_MODULE_HANDLED;
break;
case FR_EAP_CODE_SUCCESS:
rcode = eap_compose(eap_session);
/*
- * Add to the list only if it is EAP-Request, OR if
- * it's LEAP, and a response.
+ * Add to the list only if it is EAP-Request.
*/
- if (((eap_session->this_round->request->code == FR_EAP_CODE_REQUEST) &&
- (eap_session->this_round->request->type.num >= FR_EAP_METHOD_MD5)) ||
-
- /*
- * LEAP is a little different. At Stage 4,
- * it sends an EAP-Success message, but we still
- * need to keep the State attribute & session
- * data structure around for the AP Challenge.
- *
- * At stage 6, LEAP sends an EAP-Response, which
- * isn't put into the list.
- */
- ((eap_session->this_round->response->code == FR_EAP_CODE_RESPONSE) &&
- (eap_session->this_round->response->type.num == FR_EAP_METHOD_LEAP) &&
- (eap_session->this_round->request->code == FR_EAP_CODE_SUCCESS) &&
- (eap_session->this_round->request->type.num == 0))) {
+ if ((eap_session->this_round->request->code == FR_EAP_CODE_REQUEST) &&
+ (eap_session->this_round->request->type.num >= FR_EAP_METHOD_MD5)) {
talloc_free(eap_session->prev_round);
eap_session->prev_round = eap_session->this_round;
eap_session->this_round = NULL;
eap_compose(eap_session);
/*
- * Add to the list only if it is EAP-Request, OR if
- * it's LEAP, and a response.
+ * Add to the list only if it is EAP-Request.
*/
if ((eap_session->this_round->request->code == FR_EAP_CODE_REQUEST) &&
(eap_session->this_round->request->type.num >= FR_EAP_METHOD_MD5)) {
talloc_free(eap_session->prev_round);
eap_session->prev_round = eap_session->this_round;
eap_session->this_round = NULL;
- } else { /* couldn't have been LEAP, there's no tunnel */
+ } else {
RDEBUG2("Freeing eap_session");
eap_session_destroy(&eap_session);
}
/*
* This is allowed.
*/
- if (!request->proxy->reply) return RLM_MODULE_NOOP;
-
- /*
- * Hmm... there's got to be a better way to
- * discover codes for vendor attributes.
- *
- * This is vendor Cisco (9), Cisco-AVPair
- * attribute (1)
- */
- for (vp = fr_cursor_iter_by_da_init(&cursor, &request->proxy->reply->vps, attr_cisco_avpair);
- vp;
- vp = fr_cursor_next(&cursor)) {
- /*
- * If it's "leap:session-key", then stop.
- *
- * The format is VERY specific!
- */
- if (strncasecmp(vp->vp_strvalue, "leap:session-key=", 17) == 0) break;
- }
-
- /*
- * Got to the end without finding "leap:session-key="
- */
- if (!vp) return RLM_MODULE_NOOP;
-
- /*
- * The format is very specific.
- *
- * - 17 bytes are "leap:session-key="
- * - 32 are the hex encoded session key.
- * - 2 bytes are the salt.
- */
- if (vp->vp_length != (17 + 34)) {
- RDEBUG2("&Cisco-AVPair with leap:session-key has incorrect length. Got %zu, expected %d",
- vp->vp_length, 17 + 34);
- return RLM_MODULE_NOOP;
- }
-
- /*
- * Decrypt the session key, using the proxy data.
- *
- * Note that the session key is *binary*, and therefore
- * may contain embedded zeros. So we have to use memdup.
- * However, Cisco-AVPair is a "string", so the rest of the
- * code assumes that it's terminated by a trailing '\0'.
- *
- * So... be sure to (a) use memdup, and (b) include the last
- * zero byte.
- */
- i = 34;
- p = talloc_memdup(vp, vp->vp_strvalue, vp->vp_length + 1);
- talloc_set_type(p, uint8_t);
-/*
- ret = fr_radius_decode_tunnel_password((uint8_t *)p + 17, &i, request->proxy->home_server->secret,
- request->proxy->packet->vector, false);
- if (ret < 0) {
- REDEBUG("Decoding leap:session-key failed");
- talloc_free(p);
- return RLM_MODULE_FAIL;
- }
-*/
- len = i;
- if (len != 16) {
- REDEBUG("Decoded key length is incorrect, must be 16 bytes");
- talloc_free(p);
- return RLM_MODULE_FAIL;
- }
-
- /*
- * Encrypt the session key again, using the request data.
- */
- ret = fr_radius_encode_tunnel_password(p + 17, &len, request->client->secret, request->packet->vector);
- if (ret < 0) {
- REDEBUG("Encoding leap:session-key failed");
- talloc_free(p);
- return RLM_MODULE_FAIL;
- }
-
- fr_pair_value_strsteal(vp, p);
-
- return RLM_MODULE_UPDATED;
+ return RLM_MODULE_NOOP;
}
#endif
+++ /dev/null
-# rlm_eap_leap
-## Metadata
-<dl>
- <dt>category</dt><dd>authentication</dd>
-</dl>
-
-## Summary
-Implements Cisco's EAP-LEAP protocol. EAP-LEAP has multiple critical security vulnerabilities, this method is
-only provided for backwards compatibility.
-
-If you need to use Cisco proprietary EAP methods, it's recommended to use EAP-FAST instead.
+++ /dev/null
-TARGETNAME := rlm_eap_leap
-
-ifneq "$(TARGETNAME)" ""
-TARGET := $(TARGETNAME).a
-endif
-
-SOURCES := $(TARGETNAME).c eap_leap.c smbdes.c
-
-SRC_CFLAGS :=
-TGT_LDLIBS :=
-SRC_INCDIRS := ${top_srcdir}/src/modules/rlm_eap/ ${top_srcdir}/src/modules/rlm_eap/lib/base/
-
-TGT_PREREQS := libfreeradius-radius.a libfreeradius-util.a libfreeradius-eap.a
+++ /dev/null
-/*
- * eap_leap.c EAP LEAP functionality.
- *
- * Version: $Id$
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * @copyright 2003 Alan DeKok (aland@freeradius.org)
- * @copyright 2006 The FreeRADIUS server project
- */
-
-/*
- *
- * LEAP Packet Format in EAP Type-Data
- * --- ------ ------ -- --- ---------
- * 0 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | Type 0x11 | Version 0x01 | Unused 0x00 | Count 0x08 |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | Peer Challenge |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | Peer Challenge |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | User Name .....
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-
- *
- * Count is 8 octets since the Peer challenge is 8 bytes.
- * Count is 24 for EAP response, with MSCHAP response.
- * Length is the total number of octets in the EAP-Message.
- *
- * The LEAP type (0x11) is *not* included in the type data...
- */
-
-RCSID("$Id$")
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <freeradius-devel/eap/base.h>
-#include "eap_leap.h"
-
-#include <freeradius-devel/util/md5.h>
-
-/*
- * Extract the data from the LEAP packet.
- */
-leap_packet_t *eap_leap_extract(REQUEST *request, eap_round_t *eap_round)
-{
- leap_packet_raw_t *data;
- leap_packet_t *packet;
- int name_len;
-
- /*
- * LEAP can have EAP-Response or EAP-Request (step 5)
- * messages sent to it.
- */
- if (!eap_round || !eap_round->response ||
- ((eap_round->response->code != FR_EAP_CODE_RESPONSE) && (eap_round->response->code != FR_EAP_CODE_REQUEST)) ||
- (eap_round->response->type.num != FR_EAP_METHOD_LEAP) || !eap_round->response->type.data ||
- (eap_round->response->length < LEAP_HEADER_LEN) ||
- (eap_round->response->type.data[0] != 0x01)) { /* version 1 */
- REDEBUG("Corrupted data");
- return NULL;
- }
-
- /*
- * Hmm... this cast isn't the best thing to do.
- */
- data = (leap_packet_raw_t *)eap_round->response->type.data;
-
- /*
- * Some simple sanity checks on the incoming packet.
- *
- * See 'leap.txt' in this directory for a description
- * of the stages.
- */
- switch (eap_round->response->code) {
- case FR_EAP_CODE_RESPONSE:
- if (data->count != 24) {
- REDEBUG("Bad NTChallengeResponse in LEAP stage 3");
- return NULL;
- }
- break;
-
- case FR_EAP_CODE_REQUEST:
- if (data->count != 8) {
- REDEBUG("Bad AP Challenge in LEAP stage 5");
- return NULL;
- }
- break;
-
- default:
- REDEBUG("Invalid EAP code %d", eap_round->response->code);
- return NULL;
- }
-
- packet = talloc(eap_round, leap_packet_t);
- if (!packet) return NULL;
-
- /*
- * Remember code, length, and id.
- */
- packet->code = eap_round->response->code;
- packet->id = eap_round->response->id;
-
- /*
- * The size of the LEAP portion of the packet, not
- * counting the EAP header and the type.
- */
- packet->length = eap_round->response->length - EAP_HEADER_LEN - 1;
-
- /*
- * Remember the length of the challenge.
- */
- packet->count = data->count;
-
- packet->challenge = talloc_array(packet, uint8_t, packet->count);
- if (!packet->challenge) {
- talloc_free(packet);
- return NULL;
- }
- memcpy(packet->challenge, data->challenge, packet->count);
-
- /*
- * The User-Name comes after the challenge.
- *
- * Length of the EAP-LEAP portion of the packet, minus
- * 3 octets for data, minus the challenge size, is the
- * length of the user name.
- */
- name_len = packet->length - 3 - packet->count;
- if (name_len > 0) {
- packet->name = talloc_array(packet, char, name_len + 1);
- if (!packet->name) {
- talloc_free(packet);
- return NULL;
- }
- memcpy(packet->name, &data->challenge[packet->count], name_len);
- packet->name[name_len] = '\0';
- packet->name_len = name_len;
- }
-
- return packet;
-}
-
-/*
- * Get the NT-Password hash.
- */
-static int eap_leap_ntpwdhash(uint8_t *out, REQUEST *request, VALUE_PAIR *password)
-{
- if ((password->da == attr_user_password) ||
- (password->da == attr_cleartext_password)) {
- ssize_t len;
- uint8_t ucs2_password[512];
-
- /*
- * Convert the password to NT's weird Unicode format.
- */
- len = fr_utf8_to_ucs2(ucs2_password, sizeof(ucs2_password), password->vp_strvalue, password->vp_length);
- if (len < 0) {
- REDEBUG("Error converting password to UCS2");
- return 0;
- }
-
- /*
- * Get the NT Password hash.
- */
- fr_md4_calc(out, ucs2_password, len);
- } else { /* MUST be NT-Password */
- uint8_t *p = NULL;
-
- if (password->vp_length == 32) {
- p = talloc_array(password, uint8_t, 16);
- password->vp_length = fr_hex2bin(p, 16, password->vp_strvalue, password->vp_length);
- }
- if (password->vp_length != 16) {
- REDEBUG("Bad NT-Password");
- return 0;
- }
-
- if (p) {
- fr_pair_value_memcpy(password, p, 16, password->data.tainted);
- talloc_free(p);
- }
-
- memcpy(out, password->vp_octets, 16);
- }
- return 1;
-}
-
-
-/*
- * Verify the MS-CHAP response from the user.
- */
-int eap_leap_stage4(REQUEST *request, leap_packet_t *packet, VALUE_PAIR *password, leap_session_t *session)
-{
- uint8_t hash[16];
- uint8_t response[24];
-
- /*
- * No password or previous packet. Die.
- */
- if ((!password) || (!session)) {
- return 0;
- }
-
- if (!eap_leap_ntpwdhash(hash, request, password)) {
- return 0;
- }
-
- /*
- * Calculate and verify the CHAP challenge.
- */
- eap_leap_mschap(hash, session->peer_challenge, response);
- if (memcmp(response, packet->challenge, 24) == 0) {
- RDEBUG2("NTChallengeResponse from AP is valid");
- memcpy(session->peer_response, response, sizeof(response));
- return 1;
- }
- REDEBUG("FAILED incorrect NtChallengeResponse from AP");
-
- return 0;
-}
-
-/*
- * Verify ourselves to the AP
- */
-leap_packet_t *eap_leap_stage6(REQUEST *request, leap_packet_t *packet, VALUE_PAIR *user_name, VALUE_PAIR *password,
- leap_session_t *session)
-{
- size_t i;
- uint8_t hash[16], mppe[16];
- uint8_t *p, buffer[256];
- leap_packet_t *reply;
- char *q;
- VALUE_PAIR *vp;
-
- /*
- * No password or previous packet. Die.
- */
- if ((!password) || (!session)) {
- return NULL;
- }
-
- reply = talloc(session, leap_packet_t);
- if (!reply) return NULL;
-
- reply->code = FR_EAP_CODE_RESPONSE;
- reply->length = LEAP_HEADER_LEN + 24 + user_name->vp_length;
- reply->count = 24;
-
- reply->challenge = talloc_array(reply, uint8_t, reply->count);
- if (!reply->challenge) {
- talloc_free(reply);
- return NULL;
- }
-
- /*
- * The LEAP packet also contains the user name.
- */
- reply->name = talloc_array(reply, char, user_name->vp_length + 1);
- if (!reply->name) {
- talloc_free(reply);
- return NULL;
- }
-
- /*
- * Copy the name over, and ensure it's NUL terminated.
- */
- memcpy(reply->name, user_name->vp_strvalue, user_name->vp_length);
- reply->name[user_name->vp_length] = '\0';
- reply->name_len = user_name->vp_length;
-
- /*
- * MPPE hash = ntpwdhash(ntpwdhash(unicode(pw)))
- */
- if (!eap_leap_ntpwdhash(hash, request, password)) {
- talloc_free(reply);
- return NULL;
- }
- fr_md4_calc(mppe, hash, 16);
-
- /*
- * Calculate our response, to authenticate ourselves to the AP.
- */
- eap_leap_mschap(mppe, packet->challenge, reply->challenge);
-
- /*
- * Calculate the leap:session-key attribute
- */
- MEM(pair_add_reply(&vp, attr_cisco_avpair) >= 0);
-
- /*
- * And calculate the MPPE session key.
- */
- p = buffer;
- memcpy(p, mppe, 16); /* MPPEHASH */
- p += 16;
- memcpy(p, packet->challenge, 8); /* APC */
- p += 8;
- memcpy(p, reply->challenge, 24); /* APR */
- p += 24;
- memcpy(p, session->peer_challenge, 8); /* PC */
- p += 8;
- memcpy(p, session->peer_response, 24); /* PR */
-
- /*
- * These 16 bytes are the session key to use.
- */
- fr_md5_calc(hash, buffer, 16 + 8 + 24 + 8 + 24);
-
- q = talloc_array(vp, char, FR_TUNNEL_FR_ENC_LENGTH(16) + sizeof("leap:session-key="));
- strcpy(q, "leap:session-key=");
-
- memcpy(q + 17, hash, 16);
-
- i = 16;
- fr_radius_encode_tunnel_password(q + 17, &i, request->client->secret, request->packet->vector);
- fr_pair_value_strsteal(vp, q);
- vp->vp_length = 17 + i;
-
- return reply;
-}
-
-/*
- * If an EAP LEAP request needs to be initiated then
- * create such a packet.
- */
-leap_packet_t *eap_leap_initiate(REQUEST *request, eap_round_t *eap_round, VALUE_PAIR *user_name)
-{
- int i;
- leap_packet_t *reply;
-
- reply = talloc(eap_round, leap_packet_t);
- if (!reply) {
- return NULL;
- }
-
- reply->code = FR_EAP_CODE_REQUEST;
- reply->length = LEAP_HEADER_LEN + 8 + user_name->vp_length;
- reply->count = 8; /* random challenge */
-
- reply->challenge = talloc_array(reply, uint8_t, reply->count);
- if (!reply->challenge) {
- talloc_free(reply);
- return NULL;
- }
-
- /*
- * Fill the challenge with random bytes.
- */
- for (i = 0; i < reply->count; i++) {
- reply->challenge[i] = fr_rand();
- }
- RDEBUG2("Issuing AP Challenge");
-
- /*
- * The LEAP packet also contains the user name.
- */
- reply->name = talloc_array(reply, char, user_name->vp_length + 1);
- if (!reply->name) {
- talloc_free(reply);
- return NULL;
- }
-
- /*
- * Copy the name over, and ensure it's NUL terminated.
- */
- memcpy(reply->name, user_name->vp_strvalue, user_name->vp_length);
- reply->name[user_name->vp_length] = '\0';
- reply->name_len = user_name->vp_length;
-
- return reply;
-}
-
-/*
- * compose the LEAP reply packet in the EAP reply typedata
- */
-int eap_leap_compose(REQUEST *request, eap_round_t *eap_round, leap_packet_t *reply)
-{
- leap_packet_raw_t *data;
-
- rad_assert(eap_round->request);
- rad_assert(reply);
-
- /*
- * We need the name and the challenge.
- */
- switch (reply->code) {
- case FR_EAP_CODE_REQUEST:
- case FR_EAP_CODE_RESPONSE:
- eap_round->request->type.num = FR_EAP_METHOD_LEAP;
- eap_round->request->type.length = reply->length;
-
- eap_round->request->type.data = talloc_array(eap_round->request, uint8_t, reply->length);
- if (!eap_round->request->type.data) return 0;
-
- data = (leap_packet_raw_t *) eap_round->request->type.data;
- data->version = 0x01;
- data->unused = 0;
- data->count = reply->count;
-
- /*
- * N bytes of the challenge, followed by the user name.
- */
- memcpy(&data->challenge[0], reply->challenge, reply->count);
- memcpy(&data->challenge[reply->count], reply->name, reply->name_len);
- break;
-
- /*
- * EAP-Success packets don't contain any data
- * other than the header.
- */
- case FR_EAP_CODE_SUCCESS:
- eap_round->request->type.length = 0;
- break;
-
- default:
- REDEBUG("Internal sanity check failed");
- return 0;
- }
-
- /*
- * Set the EAP code.
- */
- eap_round->request->code = reply->code;
-
- return 1;
-}
+++ /dev/null
-#pragma once
-RCSIDH(eap_leap_h, "$Id$")
-
-#include <freeradius-devel/eap/base.h>
-
-#define FR_LEAP_CHALLENGE 1
-#define FR_LEAP_RESPONSE 2
-#define FR_LEAP_SUCCESS 3
-#define FR_LEAP_FAILURE 4
-#define FR_LEAP_MAX_CODES 4
-
-/*
- * Version + unused + count
- */
-#define LEAP_HEADER_LEN 3
-
-/*
- ****
- * EAP - LEAP does not specify code, id & length but chap specifies them,
- * for generalization purpose, complete header should be sent
- * and not just value_size, value and name.
- * future implementation.
- */
-
-/* eap packet structure */
-typedef struct {
- /*
- * EAP header, followed by type comes before this.
- */
- uint8_t version;
- uint8_t unused;
- uint8_t count;
- uint8_t challenge[1]; /* 8 or 24, followed by user name */
-} leap_packet_raw_t;
-
-/*
- * Which is decoded into this.
- */
-typedef struct {
- unsigned char code;
- unsigned char id;
- size_t length;
- int count;
- unsigned char *challenge;
- size_t name_len;
- char *name;
-} leap_packet_t;
-
-/*
- * The information which must be kept around
- * during the LEAP session.
- */
-typedef struct {
- int stage;
- uint8_t peer_challenge[8];
- uint8_t peer_response[24];
-} leap_session_t;
-
-extern fr_dict_attr_t const *attr_cleartext_password;
-extern fr_dict_attr_t const *attr_nt_password;
-extern fr_dict_attr_t const *attr_cisco_avpair;
-extern fr_dict_attr_t const *attr_user_password;
-
-/* function declarations here */
-
-int eap_leap_compose(REQUEST *request, eap_round_t *auth, leap_packet_t *reply);
-leap_packet_t *eap_leap_extract(REQUEST *request, eap_round_t *eap_round);
-leap_packet_t *eap_leap_initiate(REQUEST *request, eap_round_t *eap_round, VALUE_PAIR *user_name);
-int eap_leap_stage4(REQUEST *request, leap_packet_t *packet, VALUE_PAIR* password, leap_session_t *session);
-leap_packet_t *eap_leap_stage6(REQUEST *request, leap_packet_t *packet, VALUE_PAIR *user_name, VALUE_PAIR* password,
- leap_session_t *session);
-
-void eap_leap_mschap(unsigned char const *win_password, unsigned char const *challenge, unsigned char *response);
+++ /dev/null
-/*
- * rlm_eap_leap.c Handles that are called from eap
- *
- * Version: $Id$
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * @copyright 2003 Alan DeKok (aland@freeradius.org)
- * @copyright 2006 The FreeRADIUS server project
- */
-
-RCSID("$Id$")
-
-#include "eap_leap.h"
-
-static fr_dict_t *dict_freeradius;
-static fr_dict_t *dict_radius;
-
-extern fr_dict_autoload_t rlm_eap_leap_dict[];
-fr_dict_autoload_t rlm_eap_leap_dict[] = {
- { .out = &dict_freeradius, .proto = "freeradius" },
- { .out = &dict_radius, .proto = "radius" },
- { NULL }
-};
-
-fr_dict_attr_t const *attr_cleartext_password;
-fr_dict_attr_t const *attr_nt_password;
-fr_dict_attr_t const *attr_cisco_avpair;
-fr_dict_attr_t const *attr_user_password;
-
-extern fr_dict_attr_autoload_t rlm_eap_leap_dict_attr[];
-fr_dict_attr_autoload_t rlm_eap_leap_dict_attr[] = {
- { .out = &attr_cleartext_password, .name = "Cleartext-Password", .type = FR_TYPE_STRING, .dict = &dict_freeradius },
- { .out = &attr_nt_password, .name = "NT-Password", .type = FR_TYPE_OCTETS, .dict = &dict_freeradius },
- { .out = &attr_cisco_avpair, .name = "Cisco-AVPair", .type = FR_TYPE_STRING, .dict = &dict_radius },
- { .out = &attr_user_password, .name = "User-Password", .type = FR_TYPE_STRING, .dict = &dict_radius },
- { NULL }
-};
-
-static rlm_rcode_t mod_process(UNUSED void *instance, UNUSED void *thread, REQUEST *request)
-{
- rlm_rcode_t rcode;
-
- eap_session_t *eap_session = eap_session_get(request);
- leap_session_t *session;
- leap_packet_t *packet;
- leap_packet_t *reply;
-
- VALUE_PAIR *password;
-
- if (!eap_session->opaque) {
- REDEBUG("Cannot authenticate without LEAP history");
- return RLM_MODULE_INVALID;
- }
- session = talloc_get_type_abort(eap_session->opaque, leap_session_t);
- reply = NULL;
-
- /*
- * Extract the LEAP packet.
- */
- packet = eap_leap_extract(request, eap_session->this_round);
- if (!packet) return RLM_MODULE_INVALID;
-
- /*
- * The password is never sent over the wire.
- * Always get the configured password, for each user.
- */
- password = fr_pair_find_by_da(eap_session->request->control, attr_cleartext_password, TAG_ANY);
- if (!password) password = fr_pair_find_by_da(eap_session->request->control, attr_nt_password, TAG_ANY);
- if (!password) {
- REDEBUG("No Cleartext-Password or NT-Password configured for this user");
- talloc_free(packet);
- return RLM_MODULE_REJECT;
- }
-
- /*
- * We've already sent the AP challenge. This packet
- * should contain the NtChallengeResponse
- */
- switch (session->stage) {
- case 4: /* Verify NtChallengeResponse */
- RDEBUG2("Stage 4");
- rcode = eap_leap_stage4(request, packet, password, session);
- session->stage = 6;
-
- /*
- * We send EAP-Success or EAP-Fail, and not
- * any LEAP packet. So we return here.
- */
- if (!rcode) {
- eap_session->this_round->request->code = FR_EAP_CODE_FAILURE;
- talloc_free(packet);
- return 0;
- }
-
- eap_session->this_round->request->code = FR_EAP_CODE_SUCCESS;
-
- /*
- * Do this only for Success.
- */
- eap_session->this_round->request->id = eap_session->this_round->response->id + 1;
- eap_session->this_round->set_request_id = true;
-
- /*
- * LEAP requires a challenge in stage 4, not
- * an Access-Accept, which is normally returned
- * by eap_compose() in eap.c, when the EAP reply code
- * is EAP_SUCCESS.
- */
- eap_session->request->reply->code = FR_CODE_ACCESS_CHALLENGE;
- talloc_free(packet);
- return RLM_MODULE_OK;
-
- case 6: /* Issue session key */
- RDEBUG2("Stage 6");
- reply = eap_leap_stage6(request, packet, eap_session->request->username, password, session);
- break;
-
- /*
- * Stages 1, 3, and 5 are requests from the AP.
- * Stage 2 is handled by initiate()
- */
- default:
- REDEBUG("Internal sanity check failed on stage");
- break;
- }
-
- talloc_free(packet);
-
- /*
- * Process the packet. We don't care about any previous
- * EAP packets, as
- */
- if (!reply) return RLM_MODULE_FAIL;
-
- eap_leap_compose(request, eap_session->this_round, reply);
- talloc_free(reply);
-
- return RLM_MODULE_HANDLED;
-}
-
-/*
- * send an initial eap-leap request
- * ie access challenge to the user/peer.
-
- * Frame eap reply packet.
- * len = header + type + leap_methoddata
- * leap_methoddata = value_size + value
- */
-static rlm_rcode_t CC_HINT(nonnull) mod_session_init(UNUSED void *instance, UNUSED void *thread, REQUEST *request)
-{
- eap_session_t *eap_session = eap_session_get(request);
- leap_session_t *session;
- leap_packet_t *reply;
-
- RDEBUG2("Stage 2");
-
- /*
- * LEAP requires a User-Name attribute
- */
- if (!eap_session->request->username) {
- REDEBUG("User-Name is required for EAP-LEAP authentication");
- return RLM_MODULE_REJECT;
- }
-
- reply = eap_leap_initiate(request, eap_session->this_round, request->username);
- if (!reply) return RLM_MODULE_FAIL;
-
- eap_leap_compose(request, eap_session->this_round, reply);
-
- MEM(eap_session->opaque = session = talloc(eap_session, leap_session_t));
-
- /*
- * Remember which stage we're in, and which challenge
- * we sent to the AP. The later stages will take care
- * of filling in the peer response.
- */
- session->stage = 4; /* the next stage we're in */
- memcpy(session->peer_challenge, reply->challenge, reply->count);
-
- RDEBUG2("Successfully initiated");
-
- talloc_free(reply);
-
- eap_session->process = mod_process;
-
- return RLM_MODULE_HANDLED;
-}
-
-/*
- * The module name should be the only globally exported symbol.
- * That is, everything else should be 'static'.
- */
-extern rlm_eap_submodule_t rlm_eap_leap;
-rlm_eap_submodule_t rlm_eap_leap = {
- .name = "eap_leap",
- .magic = RLM_MODULE_INIT,
-
- .provides = { FR_EAP_METHOD_LEAP },
- .session_init = mod_session_init, /* Initialise a new EAP session */
- .entry_point = mod_process /* Process next round of EAP method */
-};
+++ /dev/null
-/*
- Unix SMB/CIFS implementation.
-
- a partial implementation of DES designed for use in the
- SMB authentication protocol
-
- @copyright Andrew Tridgell 1998
- @copyright 2006 The FreeRADIUS server project
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-
-/* NOTES:
-
- This code makes no attempt to be fast! In fact, it is a very
- slow implementation
-
- This code is NOT a complete DES implementation. It implements only
- the minimum necessary for SMB authentication, as used by all SMB
- products (including every copy of Microsoft Windows95 ever sold)
-
- In particular, it can only do a unchained forward DES pass. This
- means it is not possible to use this code for encryption/decryption
- of data, instead it is only useful as a "hash" algorithm.
-
- There is no entry point into this code that allows normal DES operation.
-
- I believe this means that this code does not come under ITAR
- regulations but this is NOT a legal opinion. If you are concerned
- about the applicability of ITAR regulations to this code then you
- should confirm it for yourself (and maybe let me know if you come
- up with a different answer to the one above)
-*/
-
-RCSID("$Id$")
-
-#include <string.h>
-#include <ctype.h>
-#include "eap_leap.h"
-
-#define uchar unsigned char
-
-static const uchar perm1[56] = {57, 49, 41, 33, 25, 17, 9,
- 1, 58, 50, 42, 34, 26, 18,
- 10, 2, 59, 51, 43, 35, 27,
- 19, 11, 3, 60, 52, 44, 36,
- 63, 55, 47, 39, 31, 23, 15,
- 7, 62, 54, 46, 38, 30, 22,
- 14, 6, 61, 53, 45, 37, 29,
- 21, 13, 5, 28, 20, 12, 4};
-
-static const uchar perm2[48] = {14, 17, 11, 24, 1, 5,
- 3, 28, 15, 6, 21, 10,
- 23, 19, 12, 4, 26, 8,
- 16, 7, 27, 20, 13, 2,
- 41, 52, 31, 37, 47, 55,
- 30, 40, 51, 45, 33, 48,
- 44, 49, 39, 56, 34, 53,
- 46, 42, 50, 36, 29, 32};
-
-static const uchar perm3[64] = {58, 50, 42, 34, 26, 18, 10, 2,
- 60, 52, 44, 36, 28, 20, 12, 4,
- 62, 54, 46, 38, 30, 22, 14, 6,
- 64, 56, 48, 40, 32, 24, 16, 8,
- 57, 49, 41, 33, 25, 17, 9, 1,
- 59, 51, 43, 35, 27, 19, 11, 3,
- 61, 53, 45, 37, 29, 21, 13, 5,
- 63, 55, 47, 39, 31, 23, 15, 7};
-
-static const uchar perm4[48] = { 32, 1, 2, 3, 4, 5,
- 4, 5, 6, 7, 8, 9,
- 8, 9, 10, 11, 12, 13,
- 12, 13, 14, 15, 16, 17,
- 16, 17, 18, 19, 20, 21,
- 20, 21, 22, 23, 24, 25,
- 24, 25, 26, 27, 28, 29,
- 28, 29, 30, 31, 32, 1};
-
-static const uchar perm5[32] = { 16, 7, 20, 21,
- 29, 12, 28, 17,
- 1, 15, 23, 26,
- 5, 18, 31, 10,
- 2, 8, 24, 14,
- 32, 27, 3, 9,
- 19, 13, 30, 6,
- 22, 11, 4, 25};
-
-
-static const uchar perm6[64] ={ 40, 8, 48, 16, 56, 24, 64, 32,
- 39, 7, 47, 15, 55, 23, 63, 31,
- 38, 6, 46, 14, 54, 22, 62, 30,
- 37, 5, 45, 13, 53, 21, 61, 29,
- 36, 4, 44, 12, 52, 20, 60, 28,
- 35, 3, 43, 11, 51, 19, 59, 27,
- 34, 2, 42, 10, 50, 18, 58, 26,
- 33, 1, 41, 9, 49, 17, 57, 25};
-
-
-static const uchar sc[16] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1};
-
-static const uchar sbox[8][4][16] = {
- {{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7},
- {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8},
- {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0},
- {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}},
-
- {{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10},
- {3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5},
- {0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15},
- {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}},
-
- {{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8},
- {13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1},
- {13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7},
- {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}},
-
- {{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15},
- {13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9},
- {10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4},
- {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}},
-
- {{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9},
- {14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6},
- {4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14},
- {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}},
-
- {{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11},
- {10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8},
- {9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6},
- {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}},
-
- {{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1},
- {13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6},
- {1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2},
- {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}},
-
- {{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7},
- {1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2},
- {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8},
- {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}}};
-
-static void permute(char *out, char const *in, uchar const *p, int n)
-{
- int i;
- for (i=0;i<n;i++)
- out[i] = in[p[i]-1];
-}
-
-static void lshift(char *d, int count, int n)
-{
- char out[64];
- int i;
- for (i=0;i<n;i++)
- out[i] = d[(i+count)%n];
- for (i=0;i<n;i++)
- d[i] = out[i];
-}
-
-static void concat(char *out, char *in1, char *in2, int l1, int l2)
-{
- while (l1--)
- *out++ = *in1++;
- while (l2--)
- *out++ = *in2++;
-}
-
-static void xor(char *out, char *in1, char *in2, int n)
-{
- int i;
- for (i=0;i<n;i++)
- out[i] = in1[i] ^ in2[i];
-}
-
-static void dohash(char *out, char *in, char *key)
-{
- int i, j, k;
- char pk1[56];
- char c[28];
- char d[28];
- char cd[56];
- char ki[16][48];
- char pd1[64];
- char l[32], r[32];
- char rl[64];
-
- permute(pk1, key, perm1, 56);
-
- for (i=0;i<28;i++)
- c[i] = pk1[i];
- for (i=0;i<28;i++)
- d[i] = pk1[i+28];
-
- for (i=0;i<16;i++) {
- lshift(c, sc[i], 28);
- lshift(d, sc[i], 28);
-
- concat(cd, c, d, 28, 28);
- permute(ki[i], cd, perm2, 48);
- }
-
- permute(pd1, in, perm3, 64);
-
- for (j=0;j<32;j++) {
- l[j] = pd1[j];
- r[j] = pd1[j+32];
- }
-
- for (i=0;i<16;i++) {
- char er[48];
- char erk[48];
- char b[8][6];
- char cb[32];
- char pcb[32];
- char r2[32];
-
- permute(er, r, perm4, 48);
-
- xor(erk, er, ki[i], 48);
-
- for (j=0;j<8;j++)
- for (k=0;k<6;k++)
- b[j][k] = erk[j*6 + k];
-
- for (j=0;j<8;j++) {
- int m, n;
- m = (b[j][0]<<1) | b[j][5];
-
- n = (b[j][1]<<3) | (b[j][2]<<2) | (b[j][3]<<1) | b[j][4];
-
- for (k=0;k<4;k++)
- b[j][k] = (sbox[j][m][n] & (1<<(3-k)))?1:0;
- }
-
- for (j=0;j<8;j++)
- for (k=0;k<4;k++)
- cb[j*4+k] = b[j][k];
- permute(pcb, cb, perm5, 32);
-
- xor(r2, l, pcb, 32);
-
- for (j=0;j<32;j++)
- l[j] = r[j];
-
- for (j=0;j<32;j++)
- r[j] = r2[j];
- }
-
- concat(rl, r, l, 32, 32);
-
- permute(out, rl, perm6, 64);
-}
-
-static void str_to_key(unsigned char *str,unsigned char *key)
-{
- int i;
-
- key[0] = str[0]>>1;
- key[1] = ((str[0]&0x01)<<6) | (str[1]>>2);
- key[2] = ((str[1]&0x03)<<5) | (str[2]>>3);
- key[3] = ((str[2]&0x07)<<4) | (str[3]>>4);
- key[4] = ((str[3]&0x0F)<<3) | (str[4]>>5);
- key[5] = ((str[4]&0x1F)<<2) | (str[5]>>6);
- key[6] = ((str[5]&0x3F)<<1) | (str[6]>>7);
- key[7] = str[6]&0x7F;
- for (i=0;i<8;i++) {
- key[i] = (key[i]<<1);
- }
-}
-
-
-static void smbhash(unsigned char *out, unsigned char const *in, unsigned char *key)
-{
- int i;
- char outb[64];
- char inb[64];
- char keyb[64];
- unsigned char key2[8];
-
- str_to_key(key, key2);
-
- for (i=0;i<64;i++) {
- inb[i] = (in[i/8] & (1<<(7-(i%8)))) ? 1 : 0;
- keyb[i] = (key2[i/8] & (1<<(7-(i%8)))) ? 1 : 0;
- outb[i] = 0;
- }
-
- dohash(outb, inb, keyb);
-
- for (i=0;i<8;i++) {
- out[i] = 0;
- }
-
- for (i=0;i<64;i++) {
- if (outb[i])
- out[i/8] |= (1<<(7-(i%8)));
- }
-}
-
-/*
- * Take the NT or LM password, and return the MSCHAP response
- *
- * The win_password MUST be exactly 16 bytes long.
- */
-void eap_leap_mschap(unsigned char const *win_password, unsigned char const *challenge, unsigned char *response)
-{
- unsigned char p21[21];
-
- memset(p21, 0, sizeof(p21));
- memcpy(p21, win_password, 16);
-
- smbhash(response, challenge, p21);
- smbhash(response+8, challenge, p21+7);
- smbhash(response+16, challenge, p21+14);
-}
default_eap_type = md5
type = md5
- type = leap
type = gtc
type = mschapv2
md5 {
}
- leap {
- }
-
gtc {
auth_type = PAP
}
+++ /dev/null
-type = leap
-
-leap {
-}
+++ /dev/null
-#
-# eapol_test -c leap.conf -s testing123
-#
-network={
- ssid="example"
- key_mgmt=WPA-EAP
- eap=LEAP
- identity="bob"
- password="bob"
-}