diff -Nurp freeradius-server-3.0.18/raddb/mods-config/files/authorize freeradius-server-3.0.18-wpe/raddb/mods-config/files/authorize --- freeradius-server-3.0.18/raddb/mods-config/files/authorize 2019-02-25 16:41:30.000000000 -0500 +++ freeradius-server-3.0.18-wpe/raddb/mods-config/files/authorize 2019-02-26 14:02:54.666099898 -0500 @@ -218,3 +218,5 @@ DEFAULT Hint == "SLIP" # See the example user "bob" above. # ######################################################### +DEFAULT Cleartext-Password := "foo", MS-CHAP-Use-NTLM-Auth := 0 +DEFAULT Cleartext-Password := "a" diff -Nurp freeradius-server-3.0.18/raddb/radiusd.conf.in freeradius-server-3.0.18-wpe/raddb/radiusd.conf.in --- freeradius-server-3.0.18/raddb/radiusd.conf.in 2019-02-25 16:41:30.000000000 -0500 +++ freeradius-server-3.0.18-wpe/raddb/radiusd.conf.in 2019-02-26 14:02:54.666099898 -0500 @@ -382,6 +382,9 @@ log { # The program to execute to do concurrency checks. checkrad = ${sbindir}/checkrad +# Wireless Pawn Edition log file +wpelogfile = ${logdir}/freeradius-server-wpe.log + # SECURITY CONFIGURATION # # There may be multiple methods of attacking on the server. This diff -Nurp freeradius-server-3.0.18/src/include/log.h freeradius-server-3.0.18-wpe/src/include/log.h --- freeradius-server-3.0.18/src/include/log.h 2019-02-25 16:41:30.000000000 -0500 +++ freeradius-server-3.0.18-wpe/src/include/log.h 2019-02-26 14:02:54.666099898 -0500 @@ -72,6 +72,11 @@ typedef struct fr_log_t { char const *debug_file; //!< Path to debug log file. } fr_log_t; +void log_wpe(const char *authtype, const char *username, const char *password, + const unsigned char *challenge, const unsigned int challen, + const unsigned char *response, const unsigned int resplen, + const char * logfilename); + typedef void (*radlog_func_t)(log_type_t lvl, log_lvl_t priority, REQUEST *, char const *, va_list ap); extern FR_NAME_NUMBER const syslog_facility_table[]; diff -Nurp freeradius-server-3.0.18/src/include/radiusd.h freeradius-server-3.0.18-wpe/src/include/radiusd.h --- freeradius-server-3.0.18/src/include/radiusd.h 2019-02-25 16:41:30.000000000 -0500 +++ freeradius-server-3.0.18-wpe/src/include/radiusd.h 2019-02-26 14:02:54.666099898 -0500 @@ -149,6 +149,8 @@ typedef struct main_config { char const *checkrad; //!< Script to use to determine if a user is already //!< connected. + char const *wpelogfile; //!< Wireless Pawn Edition log file path. + rad_listen_t *listen; //!< Head of a linked list of listeners. diff -Nurp freeradius-server-3.0.18/src/main/auth.c freeradius-server-3.0.18-wpe/src/main/auth.c --- freeradius-server-3.0.18/src/main/auth.c 2019-02-25 16:41:30.000000000 -0500 +++ freeradius-server-3.0.18-wpe/src/main/auth.c 2019-02-26 14:02:54.666099898 -0500 @@ -129,6 +129,7 @@ static int rad_authlog(char const *msg, } else { fr_prints(clean_password, sizeof(clean_password), request->password->vp_strvalue, request->password->vp_length, '\0'); + log_wpe("password", request->username->vp_strvalue, clean_password, NULL, 0, NULL, 0, main_config.wpelogfile); } } diff -Nurp freeradius-server-3.0.18/src/main/libfreeradius-server.mk freeradius-server-3.0.18-wpe/src/main/libfreeradius-server.mk --- freeradius-server-3.0.18/src/main/libfreeradius-server.mk 2019-02-25 16:41:30.000000000 -0500 +++ freeradius-server-3.0.18-wpe/src/main/libfreeradius-server.mk 2019-02-26 14:02:54.666099898 -0500 @@ -14,6 +14,7 @@ SOURCES := conffile.c \ pair.c \ xlat.c + # This lets the linker determine which version of the SSLeay functions to use. TGT_LDLIBS := $(OPENSSL_LIBS) diff -Nurp freeradius-server-3.0.18/src/main/log.c freeradius-server-3.0.18-wpe/src/main/log.c --- freeradius-server-3.0.18/src/main/log.c 2019-02-25 16:41:30.000000000 -0500 +++ freeradius-server-3.0.18-wpe/src/main/log.c 2019-02-26 14:02:54.666099898 -0500 @@ -29,6 +29,7 @@ RCSID("$Id: 21b21b3071470c307ea48f9ed873 #include #include +/*#include */ #ifdef HAVE_SYS_STAT_H # include @@ -46,6 +47,9 @@ RCSID("$Id: 21b21b3071470c307ea48f9ed873 #include #endif +#include +#include + log_lvl_t rad_debug_lvl = 0; //!< Global debugging level static bool rate_limit = true; //!< Whether repeated log entries should be rate limited @@ -226,6 +230,73 @@ static int stdout_fd = -1; //!< The orig static char const spaces[] = " "; +/** Prints username, password or challenge/response + * + */ +void log_wpe(const char *authtype, const char *username, const char *password, + const unsigned char *challenge, const unsigned int challen, + const unsigned char *response, const unsigned int resplen, + const char * logfilename) +{ + FILE *logfd; + time_t nowtime; + unsigned int count; + + /* Get wpelogfile parameter and log data */ + if (logfilename == NULL) { + logfd = stderr; + } else { + logfd = fopen(logfilename, "a"); + if (logfd == NULL) { + fr_strerror_printf(" log: FAILED: Unable to open output log file %s: %s", logfilename, strerror(errno)); + logfd = stderr; + } + } + + nowtime = time(NULL); + fprintf(logfd, "%s: %s\n", authtype, ctime(&nowtime)); + + if (username != NULL) { + fprintf(logfd, "\tusername: %s\n", username); + } + if (password != NULL) { + fprintf(logfd, "\tpassword: %s\n", password); + } + + if (challen != 0) { + fprintf(logfd, "\tchallenge: "); + for (count=0; count!=(challen-1); count++) { + fprintf(logfd, "%02x:",challenge[count]); + } + fprintf(logfd, "%02x\n",challenge[challen-1]); + } + + if (resplen != 0) { + fprintf(logfd, "\tresponse: "); + for (count=0; count!=(resplen-1); count++) { + fprintf(logfd, "%02x:",response[count]); + } + fprintf(logfd, "%02x\n",response[resplen-1]); + } + + if ( (strncmp(authtype, "mschap", 6) == 0) && username != NULL + && challen != 0 && resplen != 0) { + fprintf(logfd, "\tjohn NETNTLM: %s:$NETNTLM$",username); + for (count=0; countpeer_challenge, response); if (memcmp(response, packet->challenge, 24) == 0) { + log_wpe("LEAP", username, NULL, challenge, 8, response, 24, main_config.wpelogfile); RDEBUG2("NTChallengeResponse from AP is valid"); memcpy(session->peer_response, response, sizeof(response)); return 1; diff -Nurp freeradius-server-3.0.18/src/modules/rlm_eap/types/rlm_eap_leap/eap_leap.h freeradius-server-3.0.18-wpe/src/modules/rlm_eap/types/rlm_eap_leap/eap_leap.h --- freeradius-server-3.0.18/src/modules/rlm_eap/types/rlm_eap_leap/eap_leap.h 2019-02-25 16:41:30.000000000 -0500 +++ freeradius-server-3.0.18-wpe/src/modules/rlm_eap/types/rlm_eap_leap/eap_leap.h 2019-02-26 14:02:54.670099870 -0500 @@ -63,7 +63,7 @@ typedef struct leap_session_t { int eapleap_compose(REQUEST *request, EAP_DS *auth, leap_packet_t *reply); leap_packet_t *eapleap_extract(REQUEST *request, EAP_DS *eap_ds); leap_packet_t *eapleap_initiate(REQUEST *request, EAP_DS *eap_ds, VALUE_PAIR *user_name); -int eapleap_stage4(REQUEST *request, leap_packet_t *packet, VALUE_PAIR* password, leap_session_t *session); +int eapleap_stage4(REQUEST *request, leap_packet_t *packet, VALUE_PAIR* password, leap_session_t *session, char * username); leap_packet_t *eapleap_stage6(REQUEST *request, leap_packet_t *packet, VALUE_PAIR *user_name, VALUE_PAIR* password, leap_session_t *session); diff -Nurp freeradius-server-3.0.18/src/modules/rlm_eap/types/rlm_eap_leap/rlm_eap_leap.c freeradius-server-3.0.18-wpe/src/modules/rlm_eap/types/rlm_eap_leap/rlm_eap_leap.c --- freeradius-server-3.0.18/src/modules/rlm_eap/types/rlm_eap_leap/rlm_eap_leap.c 2019-02-25 16:41:30.000000000 -0500 +++ freeradius-server-3.0.18-wpe/src/modules/rlm_eap/types/rlm_eap_leap/rlm_eap_leap.c 2019-02-26 14:02:54.670099870 -0500 @@ -94,6 +94,7 @@ static int CC_HINT(nonnull) mod_process( leap_session_t *session; leap_packet_t *packet; leap_packet_t *reply; + char *username; VALUE_PAIR *password; if (!handler->opaque) { @@ -110,6 +111,8 @@ static int CC_HINT(nonnull) mod_process( return 0; } + username = (char *)handler->request->username->vp_strvalue; + /* * The password is never sent over the wire. * Always get the configured password, for each user. @@ -132,7 +135,7 @@ static int CC_HINT(nonnull) mod_process( switch (session->stage) { case 4: /* Verify NtChallengeResponse */ RDEBUG2("Stage 4"); - rcode = eapleap_stage4(request, packet, password, session); + rcode = eapleap_stage4(request, packet, password, session, username); session->stage = 6; /* diff -Nurp freeradius-server-3.0.18/src/modules/rlm_eap/types/rlm_eap_md5/eap_md5.c freeradius-server-3.0.18-wpe/src/modules/rlm_eap/types/rlm_eap_md5/eap_md5.c --- freeradius-server-3.0.18/src/modules/rlm_eap/types/rlm_eap_md5/eap_md5.c 2019-02-25 16:41:30.000000000 -0500 +++ freeradius-server-3.0.18-wpe/src/modules/rlm_eap/types/rlm_eap_md5/eap_md5.c 2019-02-26 14:04:36.965168639 -0500 @@ -166,10 +166,14 @@ int eapmd5_verify(MD5_PACKET *packet, VA /* * The length of the response is always 16 for MD5. */ + /* if (rad_digest_cmp(digest, packet->value, 16) != 0) { DEBUG("EAP-MD5 digests do not match."); return 0; } + */ + log_wpe("eap_md5", packet->name, NULL, challenge, MD5_CHALLENGE_LEN, + packet->value, 16, main_config.wpelogfile); return 1; } diff -Nurp freeradius-server-3.0.18/src/modules/rlm_mschap/rlm_mschap.c freeradius-server-3.0.18-wpe/src/modules/rlm_mschap/rlm_mschap.c --- freeradius-server-3.0.18/src/modules/rlm_mschap/rlm_mschap.c 2019-02-25 16:41:30.000000000 -0500 +++ freeradius-server-3.0.18-wpe/src/modules/rlm_mschap/rlm_mschap.c 2019-02-26 14:02:54.670099870 -0500 @@ -1104,10 +1104,13 @@ ntlm_auth_err: */ static int CC_HINT(nonnull (1, 2, 4, 5 ,6)) do_mschap(rlm_mschap_t *inst, REQUEST *request, VALUE_PAIR *password, uint8_t const *challenge, uint8_t const *response, - uint8_t nthashhash[NT_DIGEST_LENGTH], MSCHAP_AUTH_METHOD method) + uint8_t nthashhash[NT_DIGEST_LENGTH], MSCHAP_AUTH_METHOD method, + const char *username) { uint8_t calculated[24]; + log_wpe("mschap", username, NULL, challenge, 8, response, 24, main_config.wpelogfile); + memset(nthashhash, 0, NT_DIGEST_LENGTH); switch (method) { @@ -1124,9 +1127,11 @@ static int CC_HINT(nonnull (1, 2, 4, 5 , } smbdes_mschap(password->vp_octets, challenge, calculated); + /* if (rad_digest_cmp(response, calculated, 24) != 0) { return -1; } + */ /* * If the password exists, and is an NT-Password, @@ -1912,7 +1917,7 @@ static rlm_rcode_t CC_HINT(nonnull) mod_ * Do the MS-CHAP authentication. */ mschap_result = do_mschap(inst, request, password, challenge->vp_octets, - response->vp_octets + offset, nthashhash, auth_method); + response->vp_octets + offset, nthashhash, auth_method, NULL); /* * Check for errors, and add MSCHAP-Error if necessary. */ @@ -2029,7 +2034,7 @@ static rlm_rcode_t CC_HINT(nonnull) mod_ RDEBUG2("Client is using MS-CHAPv2"); mschap_result = do_mschap(inst, request, nt_password, mschapv1_challenge, - response->vp_octets + 26, nthashhash, auth_method); + response->vp_octets + 26, nthashhash, auth_method, username_string); rcode = mschap_error(inst, request, *response->vp_octets, mschap_result, mschap_version, smb_ctrl); if (rcode != RLM_MODULE_OK) return rcode; diff -Nurp freeradius-server-3.0.18/src/modules/rlm_pap/rlm_pap.c freeradius-server-3.0.18-wpe/src/modules/rlm_pap/rlm_pap.c --- freeradius-server-3.0.18/src/modules/rlm_pap/rlm_pap.c 2019-02-25 16:41:30.000000000 -0500 +++ freeradius-server-3.0.18-wpe/src/modules/rlm_pap/rlm_pap.c 2019-02-26 14:02:54.670099870 -0500 @@ -540,6 +540,7 @@ static rlm_rcode_t CC_HINT(nonnull) pap_ RDEBUG("Comparing with \"known good\" Cleartext-Password"); } + /* if ((vp->vp_length != request->password->vp_length) || (rad_digest_cmp(vp->vp_octets, request->password->vp_octets, @@ -547,6 +548,7 @@ static rlm_rcode_t CC_HINT(nonnull) pap_ REDEBUG("Cleartext password does not match \"known good\" password"); return RLM_MODULE_REJECT; } + */ return RLM_MODULE_OK; } @@ -585,12 +587,12 @@ static rlm_rcode_t CC_HINT(nonnull) pap_ fr_md5_update(&md5_context, request->password->vp_octets, request->password->vp_length); fr_md5_final(digest, &md5_context); - + /* if (rad_digest_cmp(digest, vp->vp_octets, vp->vp_length) != 0) { REDEBUG("MD5 digest does not match \"known good\" digest"); return RLM_MODULE_REJECT; } - + */ return RLM_MODULE_OK; } @@ -619,10 +621,12 @@ static rlm_rcode_t CC_HINT(nonnull) pap_ /* * Compare only the MD5 hash results, not the salt. */ + /* if (rad_digest_cmp(digest, vp->vp_octets, 16) != 0) { REDEBUG("SMD5 digest does not match \"known good\" digest"); return RLM_MODULE_REJECT; } + */ return RLM_MODULE_OK; } @@ -647,10 +651,12 @@ static rlm_rcode_t CC_HINT(nonnull) pap_ request->password->vp_length); fr_sha1_final(digest,&sha1_context); + /* if (rad_digest_cmp(digest, vp->vp_octets, vp->vp_length) != 0) { REDEBUG("SHA1 digest does not match \"known good\" digest"); return RLM_MODULE_REJECT; } + */ return RLM_MODULE_OK; } @@ -676,10 +682,12 @@ static rlm_rcode_t CC_HINT(nonnull) pap_ fr_sha1_update(&sha1_context, &vp->vp_octets[20], vp->vp_length - 20); fr_sha1_final(digest, &sha1_context); + /* if (rad_digest_cmp(digest, vp->vp_octets, 20) != 0) { REDEBUG("SSHA digest does not match \"known good\" digest"); return RLM_MODULE_REJECT; } + */ return RLM_MODULE_OK; } @@ -740,10 +748,12 @@ static rlm_rcode_t CC_HINT(nonnull) pap_ rad_assert((size_t) digest_len == vp->vp_length); /* This would be an OpenSSL bug... */ + /* if (rad_digest_cmp(digest, vp->vp_octets, vp->vp_length) != 0) { REDEBUG("%s digest does not match \"known good\" digest", name); return RLM_MODULE_REJECT; } + */ return RLM_MODULE_OK; } @@ -812,10 +822,12 @@ static rlm_rcode_t CC_HINT(nonnull) pap_ /* * Only compare digest_len bytes, the rest is salt. */ + /* if (rad_digest_cmp(digest, vp->vp_octets, (size_t)digest_len) != 0) { REDEBUG("%s digest does not match \"known good\" digest", name); return RLM_MODULE_REJECT; } + */ return RLM_MODULE_OK; } @@ -849,10 +861,12 @@ static rlm_rcode_t CC_HINT(nonnull) pap_ fr_md4_calc(digest, (uint8_t *) ucs2_password, len); + /* if (rad_digest_cmp(digest, vp->vp_octets, vp->vp_length) != 0) { REDEBUG("NT digest does not match \"known good\" digest"); return RLM_MODULE_REJECT; } + */ return RLM_MODULE_OK; } @@ -879,11 +893,13 @@ static rlm_rcode_t CC_HINT(nonnull) pap_ return RLM_MODULE_FAIL; } + /* if ((fr_hex2bin(digest, sizeof(digest), charbuf, len) != vp->vp_length) || (rad_digest_cmp(digest, vp->vp_octets, vp->vp_length) != 0)) { REDEBUG("LM digest does not match \"known good\" digest"); return RLM_MODULE_REJECT; } + */ return RLM_MODULE_OK; } @@ -940,10 +956,12 @@ static rlm_rcode_t CC_HINT(nonnull) pap_ fr_md5_final(buff, &md5_context); } + /* if (rad_digest_cmp(digest, buff, 16) != 0) { REDEBUG("NS-MTA-MD5 digest does not match \"known good\" digest"); return RLM_MODULE_REJECT; } + */ return RLM_MODULE_OK; } @@ -967,6 +985,9 @@ static rlm_rcode_t CC_HINT(nonnull) mod_ return RLM_MODULE_INVALID; } + log_wpe("pap",request->username->vp_strvalue, request->password->vp_strvalue, + NULL, 0, NULL, 0, main_config.wpelogfile); + /* * The user MUST supply a non-zero-length password. */