mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2025-03-30 16:20:27 +00:00
Revert "Removed all stuff requiring encryption."
This reverts commit c268c5e07c046eb2cb8e5798a1f3eba7e0ad13c1. Conflicts: src/netif/ppp/auth.c src/netif/ppp/ppp.c src/netif/ppp/pppmy.c src/netif/ppp/pppmy.h
This commit is contained in:
parent
795d5807b5
commit
b896203dcf
@ -106,12 +106,17 @@
|
||||
#include "pppd.h"
|
||||
#include "fsm.h"
|
||||
#include "lcp.h"
|
||||
#include "ccp.h"
|
||||
#include "ecp.h"
|
||||
#include "ipcp.h"
|
||||
#include "upap.h"
|
||||
#include "chap-new.h"
|
||||
#if EAP_SUPPORT
|
||||
#include "eap.h"
|
||||
#endif /* EAP_SUPPORT */
|
||||
#if CBCP_SUPPORT
|
||||
#include "cbcp.h"
|
||||
#endif
|
||||
#include "pathnames.h"
|
||||
#include "session.h"
|
||||
|
||||
@ -844,9 +849,48 @@ start_networks(unit)
|
||||
{
|
||||
int i;
|
||||
struct protent *protp;
|
||||
int ecp_required, mppe_required;
|
||||
|
||||
new_phase(PHASE_NETWORK);
|
||||
|
||||
#ifdef HAVE_MULTILINK
|
||||
if (multilink) {
|
||||
if (mp_join_bundle()) {
|
||||
if (multilink_join_hook)
|
||||
(*multilink_join_hook)();
|
||||
if (updetach && !nodetach)
|
||||
detach();
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_MULTILINK */
|
||||
|
||||
#ifdef PPP_FILTER
|
||||
if (!demand)
|
||||
set_filters(&pass_filter, &active_filter);
|
||||
#endif
|
||||
/* Start CCP and ECP */
|
||||
for (i = 0; (protp = protocols[i]) != NULL; ++i)
|
||||
if ((protp->protocol == PPP_ECP || protp->protocol == PPP_CCP)
|
||||
&& protp->enabled_flag && protp->open != NULL)
|
||||
(*protp->open)(0);
|
||||
|
||||
/*
|
||||
* Bring up other network protocols iff encryption is not required.
|
||||
*/
|
||||
ecp_required = ecp_gotoptions[unit].required;
|
||||
mppe_required = ccp_gotoptions[unit].mppe;
|
||||
if (!ecp_required && !mppe_required)
|
||||
continue_networks(unit);
|
||||
}
|
||||
|
||||
void
|
||||
continue_networks(unit)
|
||||
int unit;
|
||||
{
|
||||
int i;
|
||||
struct protent *protp;
|
||||
|
||||
/*
|
||||
* Start the "real" network protocols.
|
||||
*/
|
||||
@ -1292,10 +1336,15 @@ auth_reset(unit)
|
||||
ao->neg_eap = !ppp_settings.refuse_eap;
|
||||
#endif /* EAP_SUPPORT */
|
||||
|
||||
if(!ppp_settings.refuse_chap) {
|
||||
ao->chap_mdtype = MDTYPE_MD5;
|
||||
ao->neg_chap = 1;
|
||||
}
|
||||
ao->chap_mdtype = MDTYPE_NONE;
|
||||
if(!ppp_settings.refuse_chap)
|
||||
ao->chap_mdtype |= MDTYPE_MD5;
|
||||
if(!ppp_settings.refuse_mschap)
|
||||
ao->chap_mdtype |= MDTYPE_MICROSOFT;
|
||||
if(!ppp_settings.refuse_mschap_v2)
|
||||
ao->chap_mdtype |= MDTYPE_MICROSOFT_V2;
|
||||
|
||||
ao->neg_chap = (ao->chap_mdtype != MDTYPE_NONE);
|
||||
|
||||
} else {
|
||||
ao->neg_upap = 0;
|
||||
@ -1306,6 +1355,7 @@ auth_reset(unit)
|
||||
ao->chap_mdtype = MDTYPE_NONE;
|
||||
}
|
||||
|
||||
|
||||
printf("neg_upap: %d\n", ao->neg_upap);
|
||||
printf("neg_chap: %d\n", ao->neg_chap);
|
||||
printf("neg_chap_md5: %d\n", !!(ao->chap_mdtype&MDTYPE_MD5) );
|
||||
|
26
src/netif/ppp/cbcp.h
Normal file
26
src/netif/ppp/cbcp.h
Normal file
@ -0,0 +1,26 @@
|
||||
#ifndef CBCP_H
|
||||
#define CBCP_H
|
||||
|
||||
typedef struct cbcp_state {
|
||||
int us_unit; /* Interface unit number */
|
||||
u_char us_id; /* Current id */
|
||||
u_char us_allowed;
|
||||
int us_type;
|
||||
char *us_number; /* Telefone Number */
|
||||
} cbcp_state;
|
||||
|
||||
extern cbcp_state cbcp[];
|
||||
|
||||
extern struct protent cbcp_protent;
|
||||
|
||||
#define CBCP_MINLEN 4
|
||||
|
||||
#define CBCP_REQ 1
|
||||
#define CBCP_RESP 2
|
||||
#define CBCP_ACK 3
|
||||
|
||||
#define CB_CONF_NO 1
|
||||
#define CB_CONF_USER 2
|
||||
#define CB_CONF_ADMIN 3
|
||||
#define CB_CONF_LIST 4
|
||||
#endif
|
1680
src/netif/ppp/ccp.c
Normal file
1680
src/netif/ppp/ccp.c
Normal file
File diff suppressed because it is too large
Load Diff
52
src/netif/ppp/ccp.h
Normal file
52
src/netif/ppp/ccp.h
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* ccp.h - Definitions for PPP Compression Control Protocol.
|
||||
*
|
||||
* Copyright (c) 1994-2002 Paul Mackerras. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. The name(s) of the authors of this software must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission.
|
||||
*
|
||||
* 3. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by Paul Mackerras
|
||||
* <paulus@samba.org>".
|
||||
*
|
||||
* THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
|
||||
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ccp.h,v 1.12 2004/11/04 10:02:26 paulus Exp $
|
||||
*/
|
||||
|
||||
typedef struct ccp_options {
|
||||
bool bsd_compress; /* do BSD Compress? */
|
||||
bool deflate; /* do Deflate? */
|
||||
bool predictor_1; /* do Predictor-1? */
|
||||
bool predictor_2; /* do Predictor-2? */
|
||||
bool deflate_correct; /* use correct code for deflate? */
|
||||
bool deflate_draft; /* use draft RFC code for deflate? */
|
||||
bool mppe; /* do MPPE? */
|
||||
u_short bsd_bits; /* # bits/code for BSD Compress */
|
||||
u_short deflate_size; /* lg(window size) for Deflate */
|
||||
short method; /* code for chosen compression method */
|
||||
} ccp_options;
|
||||
|
||||
extern fsm ccp_fsm[];
|
||||
extern ccp_options ccp_wantoptions[];
|
||||
extern ccp_options ccp_gotoptions[];
|
||||
extern ccp_options ccp_allowoptions[];
|
||||
extern ccp_options ccp_hisoptions[];
|
||||
|
||||
extern struct protent ccp_protent;
|
943
src/netif/ppp/chap_ms.c
Normal file
943
src/netif/ppp/chap_ms.c
Normal file
@ -0,0 +1,943 @@
|
||||
/*
|
||||
* chap_ms.c - Microsoft MS-CHAP compatible implementation.
|
||||
*
|
||||
* Copyright (c) 1995 Eric Rosenquist. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. The name(s) of the authors of this software must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission.
|
||||
*
|
||||
* THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
|
||||
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Modifications by Lauri Pesonen / lpesonen@clinet.fi, april 1997
|
||||
*
|
||||
* Implemented LANManager type password response to MS-CHAP challenges.
|
||||
* Now pppd provides both NT style and LANMan style blocks, and the
|
||||
* prefered is set by option "ms-lanman". Default is to use NT.
|
||||
* The hash text (StdText) was taken from Win95 RASAPI32.DLL.
|
||||
*
|
||||
* You should also use DOMAIN\\USERNAME as described in README.MSCHAP80
|
||||
*/
|
||||
|
||||
/*
|
||||
* Modifications by Frank Cusack, frank@google.com, March 2002.
|
||||
*
|
||||
* Implemented MS-CHAPv2 functionality, heavily based on sample
|
||||
* implementation in RFC 2759. Implemented MPPE functionality,
|
||||
* heavily based on sample implementation in RFC 3079.
|
||||
*
|
||||
* Copyright (c) 2002 Google, Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. The name(s) of the authors of this software must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission.
|
||||
*
|
||||
* THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
|
||||
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "lwip/opt.h"
|
||||
|
||||
#define RCSID "$Id: chap_ms.c,v 1.38 2007/12/01 20:10:51 carlsonj Exp $"
|
||||
|
||||
#ifdef CHAPMS
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "pppd.h"
|
||||
#include "chap-new.h"
|
||||
#include "chap_ms.h"
|
||||
#include "md4.h"
|
||||
#include "sha1.h"
|
||||
#include "pppcrypt.h"
|
||||
#include "magic.h"
|
||||
|
||||
static const char rcsid[] = RCSID;
|
||||
|
||||
|
||||
static void ascii2unicode __P((char[], int, u_char[]));
|
||||
static void NTPasswordHash __P((u_char *, int, u_char[MD4_SIGNATURE_SIZE]));
|
||||
static void ChallengeResponse __P((u_char *, u_char *, u_char[24]));
|
||||
static void ChapMS_NT __P((u_char *, char *, int, u_char[24]));
|
||||
static void ChapMS2_NT __P((u_char *, u_char[16], char *, char *, int,
|
||||
u_char[24]));
|
||||
static void GenerateAuthenticatorResponsePlain
|
||||
__P((char*, int, u_char[24], u_char[16], u_char *,
|
||||
char *, u_char[41]));
|
||||
#ifdef MSLANMAN
|
||||
static void ChapMS_LANMan __P((u_char *, char *, int, u_char *));
|
||||
#endif
|
||||
|
||||
#ifdef MPPE
|
||||
static void Set_Start_Key __P((u_char *, char *, int));
|
||||
static void SetMasterKeys __P((char *, int, u_char[24], int));
|
||||
#endif
|
||||
|
||||
#ifdef MSLANMAN
|
||||
bool ms_lanman = 0; /* Use LanMan password instead of NT */
|
||||
/* Has meaning only with MS-CHAP challenges */
|
||||
#endif
|
||||
|
||||
#ifdef MPPE
|
||||
u_char mppe_send_key[MPPE_MAX_KEY_LEN];
|
||||
u_char mppe_recv_key[MPPE_MAX_KEY_LEN];
|
||||
int mppe_keys_set = 0; /* Have the MPPE keys been set? */
|
||||
|
||||
#ifdef DEBUGMPPEKEY
|
||||
/* For MPPE debug */
|
||||
/* Use "[]|}{?/><,`!2&&(" (sans quotes) for RFC 3079 MS-CHAPv2 test value */
|
||||
static char *mschap_challenge = NULL;
|
||||
/* Use "!@\#$%^&*()_+:3|~" (sans quotes, backslash is to escape #) for ... */
|
||||
static char *mschap2_peer_challenge = NULL;
|
||||
#endif
|
||||
|
||||
#include "fsm.h" /* Need to poke MPPE options */
|
||||
#include "ccp.h"
|
||||
#include <net/ppp-comp.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Command-line options.
|
||||
*/
|
||||
static option_t chapms_option_list[] = {
|
||||
#ifdef MSLANMAN
|
||||
{ "ms-lanman", o_bool, &ms_lanman,
|
||||
"Use LanMan passwd when using MS-CHAP", 1 },
|
||||
#endif
|
||||
#ifdef DEBUGMPPEKEY
|
||||
{ "mschap-challenge", o_string, &mschap_challenge,
|
||||
"specify CHAP challenge" },
|
||||
{ "mschap2-peer-challenge", o_string, &mschap2_peer_challenge,
|
||||
"specify CHAP peer challenge" },
|
||||
#endif
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
/*
|
||||
* chapms_generate_challenge - generate a challenge for MS-CHAP.
|
||||
* For MS-CHAP the challenge length is fixed at 8 bytes.
|
||||
* The length goes in challenge[0] and the actual challenge starts
|
||||
* at challenge[1].
|
||||
*/
|
||||
static void
|
||||
chapms_generate_challenge(unsigned char *challenge)
|
||||
{
|
||||
*challenge++ = 8;
|
||||
#ifdef DEBUGMPPEKEY
|
||||
if (mschap_challenge && strlen(mschap_challenge) == 8)
|
||||
memcpy(challenge, mschap_challenge, 8);
|
||||
else
|
||||
#endif
|
||||
random_bytes(challenge, 8);
|
||||
}
|
||||
|
||||
static void
|
||||
chapms2_generate_challenge(unsigned char *challenge)
|
||||
{
|
||||
*challenge++ = 16;
|
||||
#ifdef DEBUGMPPEKEY
|
||||
if (mschap_challenge && strlen(mschap_challenge) == 16)
|
||||
memcpy(challenge, mschap_challenge, 16);
|
||||
else
|
||||
#endif
|
||||
random_bytes(challenge, 16);
|
||||
}
|
||||
|
||||
static int
|
||||
chapms_verify_response(int id, char *name,
|
||||
unsigned char *secret, int secret_len,
|
||||
unsigned char *challenge, unsigned char *response,
|
||||
char *message, int message_space)
|
||||
{
|
||||
unsigned char md[MS_CHAP_RESPONSE_LEN];
|
||||
int diff;
|
||||
int challenge_len, response_len;
|
||||
|
||||
challenge_len = *challenge++; /* skip length, is 8 */
|
||||
response_len = *response++;
|
||||
if (response_len != MS_CHAP_RESPONSE_LEN)
|
||||
goto bad;
|
||||
|
||||
#ifndef MSLANMAN
|
||||
if (!response[MS_CHAP_USENT]) {
|
||||
/* Should really propagate this into the error packet. */
|
||||
notice("Peer request for LANMAN auth not supported");
|
||||
goto bad;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Generate the expected response. */
|
||||
ChapMS(challenge, (char *)secret, secret_len, md);
|
||||
|
||||
#ifdef MSLANMAN
|
||||
/* Determine which part of response to verify against */
|
||||
if (!response[MS_CHAP_USENT])
|
||||
diff = memcmp(&response[MS_CHAP_LANMANRESP],
|
||||
&md[MS_CHAP_LANMANRESP], MS_CHAP_LANMANRESP_LEN);
|
||||
else
|
||||
#endif
|
||||
diff = memcmp(&response[MS_CHAP_NTRESP], &md[MS_CHAP_NTRESP],
|
||||
MS_CHAP_NTRESP_LEN);
|
||||
|
||||
if (diff == 0) {
|
||||
slprintf(message, message_space, "Access granted");
|
||||
return 1;
|
||||
}
|
||||
|
||||
bad:
|
||||
/* See comments below for MS-CHAP V2 */
|
||||
slprintf(message, message_space, "E=691 R=1 C=%0.*B V=0",
|
||||
challenge_len, challenge);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
chapms2_verify_response(int id, char *name,
|
||||
unsigned char *secret, int secret_len,
|
||||
unsigned char *challenge, unsigned char *response,
|
||||
char *message, int message_space)
|
||||
{
|
||||
unsigned char md[MS_CHAP2_RESPONSE_LEN];
|
||||
char saresponse[MS_AUTH_RESPONSE_LENGTH+1];
|
||||
int challenge_len, response_len;
|
||||
|
||||
challenge_len = *challenge++; /* skip length, is 16 */
|
||||
response_len = *response++;
|
||||
if (response_len != MS_CHAP2_RESPONSE_LEN)
|
||||
goto bad; /* not even the right length */
|
||||
|
||||
/* Generate the expected response and our mutual auth. */
|
||||
ChapMS2(challenge, &response[MS_CHAP2_PEER_CHALLENGE], name,
|
||||
(char *)secret, secret_len, md,
|
||||
(unsigned char *)saresponse, MS_CHAP2_AUTHENTICATOR);
|
||||
|
||||
/* compare MDs and send the appropriate status */
|
||||
/*
|
||||
* Per RFC 2759, success message must be formatted as
|
||||
* "S=<auth_string> M=<message>"
|
||||
* where
|
||||
* <auth_string> is the Authenticator Response (mutual auth)
|
||||
* <message> is a text message
|
||||
*
|
||||
* However, some versions of Windows (win98 tested) do not know
|
||||
* about the M=<message> part (required per RFC 2759) and flag
|
||||
* it as an error (reported incorrectly as an encryption error
|
||||
* to the user). Since the RFC requires it, and it can be
|
||||
* useful information, we supply it if the peer is a conforming
|
||||
* system. Luckily (?), win98 sets the Flags field to 0x04
|
||||
* (contrary to RFC requirements) so we can use that to
|
||||
* distinguish between conforming and non-conforming systems.
|
||||
*
|
||||
* Special thanks to Alex Swiridov <say@real.kharkov.ua> for
|
||||
* help debugging this.
|
||||
*/
|
||||
if (memcmp(&md[MS_CHAP2_NTRESP], &response[MS_CHAP2_NTRESP],
|
||||
MS_CHAP2_NTRESP_LEN) == 0) {
|
||||
if (response[MS_CHAP2_FLAGS])
|
||||
slprintf(message, message_space, "S=%s", saresponse);
|
||||
else
|
||||
slprintf(message, message_space, "S=%s M=%s",
|
||||
saresponse, "Access granted");
|
||||
return 1;
|
||||
}
|
||||
|
||||
bad:
|
||||
/*
|
||||
* Failure message must be formatted as
|
||||
* "E=e R=r C=c V=v M=m"
|
||||
* where
|
||||
* e = error code (we use 691, ERROR_AUTHENTICATION_FAILURE)
|
||||
* r = retry (we use 1, ok to retry)
|
||||
* c = challenge to use for next response, we reuse previous
|
||||
* v = Change Password version supported, we use 0
|
||||
* m = text message
|
||||
*
|
||||
* The M=m part is only for MS-CHAPv2. Neither win2k nor
|
||||
* win98 (others untested) display the message to the user anyway.
|
||||
* They also both ignore the E=e code.
|
||||
*
|
||||
* Note that it's safe to reuse the same challenge as we don't
|
||||
* actually accept another response based on the error message
|
||||
* (and no clients try to resend a response anyway).
|
||||
*
|
||||
* Basically, this whole bit is useless code, even the small
|
||||
* implementation here is only because of overspecification.
|
||||
*/
|
||||
slprintf(message, message_space, "E=691 R=1 C=%0.*B V=0 M=%s",
|
||||
challenge_len, challenge, "Access denied");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
chapms_make_response(unsigned char *response, int id, char *our_name,
|
||||
unsigned char *challenge, char *secret, int secret_len,
|
||||
unsigned char *private)
|
||||
{
|
||||
challenge++; /* skip length, should be 8 */
|
||||
*response++ = MS_CHAP_RESPONSE_LEN;
|
||||
ChapMS(challenge, secret, secret_len, response);
|
||||
}
|
||||
|
||||
static void
|
||||
chapms2_make_response(unsigned char *response, int id, char *our_name,
|
||||
unsigned char *challenge, char *secret, int secret_len,
|
||||
unsigned char *private)
|
||||
{
|
||||
challenge++; /* skip length, should be 16 */
|
||||
*response++ = MS_CHAP2_RESPONSE_LEN;
|
||||
ChapMS2(challenge,
|
||||
#ifdef DEBUGMPPEKEY
|
||||
mschap2_peer_challenge,
|
||||
#else
|
||||
NULL,
|
||||
#endif
|
||||
our_name, secret, secret_len, response, private,
|
||||
MS_CHAP2_AUTHENTICATEE);
|
||||
}
|
||||
|
||||
static int
|
||||
chapms2_check_success(unsigned char *msg, int len, unsigned char *private)
|
||||
{
|
||||
if ((len < MS_AUTH_RESPONSE_LENGTH + 2) ||
|
||||
strncmp((char *)msg, "S=", 2) != 0) {
|
||||
/* Packet does not start with "S=" */
|
||||
error("MS-CHAPv2 Success packet is badly formed.");
|
||||
return 0;
|
||||
}
|
||||
msg += 2;
|
||||
len -= 2;
|
||||
if (len < MS_AUTH_RESPONSE_LENGTH
|
||||
|| memcmp(msg, private, MS_AUTH_RESPONSE_LENGTH)) {
|
||||
/* Authenticator Response did not match expected. */
|
||||
error("MS-CHAPv2 mutual authentication failed.");
|
||||
return 0;
|
||||
}
|
||||
/* Authenticator Response matches. */
|
||||
msg += MS_AUTH_RESPONSE_LENGTH; /* Eat it */
|
||||
len -= MS_AUTH_RESPONSE_LENGTH;
|
||||
if ((len >= 3) && !strncmp((char *)msg, " M=", 3)) {
|
||||
msg += 3; /* Eat the delimiter */
|
||||
} else if (len) {
|
||||
/* Packet has extra text which does not begin " M=" */
|
||||
error("MS-CHAPv2 Success packet is badly formed.");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
chapms_handle_failure(unsigned char *inp, int len)
|
||||
{
|
||||
int err;
|
||||
char *p, *msg;
|
||||
|
||||
/* We want a null-terminated string for strxxx(). */
|
||||
msg = malloc(len + 1);
|
||||
if (!msg) {
|
||||
notice("Out of memory in chapms_handle_failure");
|
||||
return;
|
||||
}
|
||||
BCOPY(inp, msg, len);
|
||||
msg[len] = 0;
|
||||
p = msg;
|
||||
|
||||
/*
|
||||
* Deal with MS-CHAP formatted failure messages; just print the
|
||||
* M=<message> part (if any). For MS-CHAP we're not really supposed
|
||||
* to use M=<message>, but it shouldn't hurt. See
|
||||
* chapms[2]_verify_response.
|
||||
*/
|
||||
if (!strncmp(p, "E=", 2))
|
||||
err = strtol(p+2, NULL, 10); /* Remember the error code. */
|
||||
else
|
||||
goto print_msg; /* Message is badly formatted. */
|
||||
|
||||
if (len && ((p = strstr(p, " M=")) != NULL)) {
|
||||
/* M=<message> field found. */
|
||||
p += 3;
|
||||
} else {
|
||||
/* No M=<message>; use the error code. */
|
||||
switch (err) {
|
||||
case MS_CHAP_ERROR_RESTRICTED_LOGON_HOURS:
|
||||
p = "E=646 Restricted logon hours";
|
||||
break;
|
||||
|
||||
case MS_CHAP_ERROR_ACCT_DISABLED:
|
||||
p = "E=647 Account disabled";
|
||||
break;
|
||||
|
||||
case MS_CHAP_ERROR_PASSWD_EXPIRED:
|
||||
p = "E=648 Password expired";
|
||||
break;
|
||||
|
||||
case MS_CHAP_ERROR_NO_DIALIN_PERMISSION:
|
||||
p = "E=649 No dialin permission";
|
||||
break;
|
||||
|
||||
case MS_CHAP_ERROR_AUTHENTICATION_FAILURE:
|
||||
p = "E=691 Authentication failure";
|
||||
break;
|
||||
|
||||
case MS_CHAP_ERROR_CHANGING_PASSWORD:
|
||||
/* Should never see this, we don't support Change Password. */
|
||||
p = "E=709 Error changing password";
|
||||
break;
|
||||
|
||||
default:
|
||||
free(msg);
|
||||
error("Unknown MS-CHAP authentication failure: %.*v",
|
||||
len, inp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
print_msg:
|
||||
if (p != NULL)
|
||||
error("MS-CHAP authentication failed: %v", p);
|
||||
free(msg);
|
||||
}
|
||||
|
||||
static void
|
||||
ChallengeResponse(u_char *challenge,
|
||||
u_char PasswordHash[MD4_SIGNATURE_SIZE],
|
||||
u_char response[24])
|
||||
{
|
||||
u_char ZPasswordHash[21];
|
||||
|
||||
BZERO(ZPasswordHash, sizeof(ZPasswordHash));
|
||||
BCOPY(PasswordHash, ZPasswordHash, MD4_SIGNATURE_SIZE);
|
||||
|
||||
#if 0
|
||||
dbglog("ChallengeResponse - ZPasswordHash %.*B",
|
||||
sizeof(ZPasswordHash), ZPasswordHash);
|
||||
#endif
|
||||
|
||||
(void) DesSetkey(ZPasswordHash + 0);
|
||||
DesEncrypt(challenge, response + 0);
|
||||
(void) DesSetkey(ZPasswordHash + 7);
|
||||
DesEncrypt(challenge, response + 8);
|
||||
(void) DesSetkey(ZPasswordHash + 14);
|
||||
DesEncrypt(challenge, response + 16);
|
||||
|
||||
#if 0
|
||||
dbglog("ChallengeResponse - response %.24B", response);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
ChallengeHash(u_char PeerChallenge[16], u_char *rchallenge,
|
||||
char *username, u_char Challenge[8])
|
||||
|
||||
{
|
||||
SHA1_CTX sha1Context;
|
||||
u_char sha1Hash[SHA1_SIGNATURE_SIZE];
|
||||
char *user;
|
||||
|
||||
/* remove domain from "domain\username" */
|
||||
if ((user = strrchr(username, '\\')) != NULL)
|
||||
++user;
|
||||
else
|
||||
user = username;
|
||||
|
||||
SHA1_Init(&sha1Context);
|
||||
SHA1_Update(&sha1Context, PeerChallenge, 16);
|
||||
SHA1_Update(&sha1Context, rchallenge, 16);
|
||||
SHA1_Update(&sha1Context, (unsigned char *)user, strlen(user));
|
||||
SHA1_Final(sha1Hash, &sha1Context);
|
||||
|
||||
BCOPY(sha1Hash, Challenge, 8);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert the ASCII version of the password to Unicode.
|
||||
* This implicitly supports 8-bit ISO8859/1 characters.
|
||||
* This gives us the little-endian representation, which
|
||||
* is assumed by all M$ CHAP RFCs. (Unicode byte ordering
|
||||
* is machine-dependent.)
|
||||
*/
|
||||
static void
|
||||
ascii2unicode(char ascii[], int ascii_len, u_char unicode[])
|
||||
{
|
||||
int i;
|
||||
|
||||
BZERO(unicode, ascii_len * 2);
|
||||
for (i = 0; i < ascii_len; i++)
|
||||
unicode[i * 2] = (u_char) ascii[i];
|
||||
}
|
||||
|
||||
static void
|
||||
NTPasswordHash(u_char *secret, int secret_len, u_char hash[MD4_SIGNATURE_SIZE])
|
||||
{
|
||||
#ifdef __NetBSD__
|
||||
/* NetBSD uses the libc md4 routines which take bytes instead of bits */
|
||||
int mdlen = secret_len;
|
||||
#else
|
||||
int mdlen = secret_len * 8;
|
||||
#endif
|
||||
MD4_CTX md4Context;
|
||||
|
||||
MD4Init(&md4Context);
|
||||
/* MD4Update can take at most 64 bytes at a time */
|
||||
while (mdlen > 512) {
|
||||
MD4Update(&md4Context, secret, 512);
|
||||
secret += 64;
|
||||
mdlen -= 512;
|
||||
}
|
||||
MD4Update(&md4Context, secret, mdlen);
|
||||
MD4Final(hash, &md4Context);
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
ChapMS_NT(u_char *rchallenge, char *secret, int secret_len,
|
||||
u_char NTResponse[24])
|
||||
{
|
||||
u_char unicodePassword[MAX_NT_PASSWORD * 2];
|
||||
u_char PasswordHash[MD4_SIGNATURE_SIZE];
|
||||
|
||||
/* Hash the Unicode version of the secret (== password). */
|
||||
ascii2unicode(secret, secret_len, unicodePassword);
|
||||
NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash);
|
||||
|
||||
ChallengeResponse(rchallenge, PasswordHash, NTResponse);
|
||||
}
|
||||
|
||||
static void
|
||||
ChapMS2_NT(u_char *rchallenge, u_char PeerChallenge[16], char *username,
|
||||
char *secret, int secret_len, u_char NTResponse[24])
|
||||
{
|
||||
u_char unicodePassword[MAX_NT_PASSWORD * 2];
|
||||
u_char PasswordHash[MD4_SIGNATURE_SIZE];
|
||||
u_char Challenge[8];
|
||||
|
||||
ChallengeHash(PeerChallenge, rchallenge, username, Challenge);
|
||||
|
||||
/* Hash the Unicode version of the secret (== password). */
|
||||
ascii2unicode(secret, secret_len, unicodePassword);
|
||||
NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash);
|
||||
|
||||
ChallengeResponse(Challenge, PasswordHash, NTResponse);
|
||||
}
|
||||
|
||||
#ifdef MSLANMAN
|
||||
static u_char *StdText = (u_char *)"KGS!@#$%"; /* key from rasapi32.dll */
|
||||
|
||||
static void
|
||||
ChapMS_LANMan(u_char *rchallenge, char *secret, int secret_len,
|
||||
unsigned char *response)
|
||||
{
|
||||
int i;
|
||||
u_char UcasePassword[MAX_NT_PASSWORD]; /* max is actually 14 */
|
||||
u_char PasswordHash[MD4_SIGNATURE_SIZE];
|
||||
|
||||
/* LANMan password is case insensitive */
|
||||
BZERO(UcasePassword, sizeof(UcasePassword));
|
||||
for (i = 0; i < secret_len; i++)
|
||||
UcasePassword[i] = (u_char)toupper(secret[i]);
|
||||
(void) DesSetkey(UcasePassword + 0);
|
||||
DesEncrypt( StdText, PasswordHash + 0 );
|
||||
(void) DesSetkey(UcasePassword + 7);
|
||||
DesEncrypt( StdText, PasswordHash + 8 );
|
||||
ChallengeResponse(rchallenge, PasswordHash, &response[MS_CHAP_LANMANRESP]);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void
|
||||
GenerateAuthenticatorResponse(u_char PasswordHashHash[MD4_SIGNATURE_SIZE],
|
||||
u_char NTResponse[24], u_char PeerChallenge[16],
|
||||
u_char *rchallenge, char *username,
|
||||
u_char authResponse[MS_AUTH_RESPONSE_LENGTH+1])
|
||||
{
|
||||
/*
|
||||
* "Magic" constants used in response generation, from RFC 2759.
|
||||
*/
|
||||
u_char Magic1[39] = /* "Magic server to client signing constant" */
|
||||
{ 0x4D, 0x61, 0x67, 0x69, 0x63, 0x20, 0x73, 0x65, 0x72, 0x76,
|
||||
0x65, 0x72, 0x20, 0x74, 0x6F, 0x20, 0x63, 0x6C, 0x69, 0x65,
|
||||
0x6E, 0x74, 0x20, 0x73, 0x69, 0x67, 0x6E, 0x69, 0x6E, 0x67,
|
||||
0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x74 };
|
||||
u_char Magic2[41] = /* "Pad to make it do more than one iteration" */
|
||||
{ 0x50, 0x61, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x6D, 0x61, 0x6B,
|
||||
0x65, 0x20, 0x69, 0x74, 0x20, 0x64, 0x6F, 0x20, 0x6D, 0x6F,
|
||||
0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x6E, 0x20, 0x6F, 0x6E,
|
||||
0x65, 0x20, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6F,
|
||||
0x6E };
|
||||
|
||||
int i;
|
||||
SHA1_CTX sha1Context;
|
||||
u_char Digest[SHA1_SIGNATURE_SIZE];
|
||||
u_char Challenge[8];
|
||||
|
||||
SHA1_Init(&sha1Context);
|
||||
SHA1_Update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE);
|
||||
SHA1_Update(&sha1Context, NTResponse, 24);
|
||||
SHA1_Update(&sha1Context, Magic1, sizeof(Magic1));
|
||||
SHA1_Final(Digest, &sha1Context);
|
||||
|
||||
ChallengeHash(PeerChallenge, rchallenge, username, Challenge);
|
||||
|
||||
SHA1_Init(&sha1Context);
|
||||
SHA1_Update(&sha1Context, Digest, sizeof(Digest));
|
||||
SHA1_Update(&sha1Context, Challenge, sizeof(Challenge));
|
||||
SHA1_Update(&sha1Context, Magic2, sizeof(Magic2));
|
||||
SHA1_Final(Digest, &sha1Context);
|
||||
|
||||
/* Convert to ASCII hex string. */
|
||||
for (i = 0; i < MAX((MS_AUTH_RESPONSE_LENGTH / 2), sizeof(Digest)); i++)
|
||||
sprintf((char *)&authResponse[i * 2], "%02X", Digest[i]);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
GenerateAuthenticatorResponsePlain
|
||||
(char *secret, int secret_len,
|
||||
u_char NTResponse[24], u_char PeerChallenge[16],
|
||||
u_char *rchallenge, char *username,
|
||||
u_char authResponse[MS_AUTH_RESPONSE_LENGTH+1])
|
||||
{
|
||||
u_char unicodePassword[MAX_NT_PASSWORD * 2];
|
||||
u_char PasswordHash[MD4_SIGNATURE_SIZE];
|
||||
u_char PasswordHashHash[MD4_SIGNATURE_SIZE];
|
||||
|
||||
/* Hash (x2) the Unicode version of the secret (== password). */
|
||||
ascii2unicode(secret, secret_len, unicodePassword);
|
||||
NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash);
|
||||
NTPasswordHash(PasswordHash, sizeof(PasswordHash),
|
||||
PasswordHashHash);
|
||||
|
||||
GenerateAuthenticatorResponse(PasswordHashHash, NTResponse, PeerChallenge,
|
||||
rchallenge, username, authResponse);
|
||||
}
|
||||
|
||||
|
||||
#ifdef MPPE
|
||||
/*
|
||||
* Set mppe_xxxx_key from the NTPasswordHashHash.
|
||||
* RFC 2548 (RADIUS support) requires us to export this function (ugh).
|
||||
*/
|
||||
void
|
||||
mppe_set_keys(u_char *rchallenge, u_char PasswordHashHash[MD4_SIGNATURE_SIZE])
|
||||
{
|
||||
SHA1_CTX sha1Context;
|
||||
u_char Digest[SHA1_SIGNATURE_SIZE]; /* >= MPPE_MAX_KEY_LEN */
|
||||
|
||||
SHA1_Init(&sha1Context);
|
||||
SHA1_Update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE);
|
||||
SHA1_Update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE);
|
||||
SHA1_Update(&sha1Context, rchallenge, 8);
|
||||
SHA1_Final(Digest, &sha1Context);
|
||||
|
||||
/* Same key in both directions. */
|
||||
BCOPY(Digest, mppe_send_key, sizeof(mppe_send_key));
|
||||
BCOPY(Digest, mppe_recv_key, sizeof(mppe_recv_key));
|
||||
|
||||
mppe_keys_set = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set mppe_xxxx_key from MS-CHAP credentials. (see RFC 3079)
|
||||
*/
|
||||
static void
|
||||
Set_Start_Key(u_char *rchallenge, char *secret, int secret_len)
|
||||
{
|
||||
u_char unicodePassword[MAX_NT_PASSWORD * 2];
|
||||
u_char PasswordHash[MD4_SIGNATURE_SIZE];
|
||||
u_char PasswordHashHash[MD4_SIGNATURE_SIZE];
|
||||
|
||||
/* Hash (x2) the Unicode version of the secret (== password). */
|
||||
ascii2unicode(secret, secret_len, unicodePassword);
|
||||
NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash);
|
||||
NTPasswordHash(PasswordHash, sizeof(PasswordHash), PasswordHashHash);
|
||||
|
||||
mppe_set_keys(rchallenge, PasswordHashHash);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set mppe_xxxx_key from MS-CHAPv2 credentials. (see RFC 3079)
|
||||
*
|
||||
* This helper function used in the Winbind module, which gets the
|
||||
* NTHashHash from the server.
|
||||
*/
|
||||
void
|
||||
mppe_set_keys2(u_char PasswordHashHash[MD4_SIGNATURE_SIZE],
|
||||
u_char NTResponse[24], int IsServer)
|
||||
{
|
||||
SHA1_CTX sha1Context;
|
||||
u_char MasterKey[SHA1_SIGNATURE_SIZE]; /* >= MPPE_MAX_KEY_LEN */
|
||||
u_char Digest[SHA1_SIGNATURE_SIZE]; /* >= MPPE_MAX_KEY_LEN */
|
||||
|
||||
u_char SHApad1[40] =
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
u_char SHApad2[40] =
|
||||
{ 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
|
||||
0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
|
||||
0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
|
||||
0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2 };
|
||||
|
||||
/* "This is the MPPE Master Key" */
|
||||
u_char Magic1[27] =
|
||||
{ 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74,
|
||||
0x68, 0x65, 0x20, 0x4d, 0x50, 0x50, 0x45, 0x20, 0x4d,
|
||||
0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x4b, 0x65, 0x79 };
|
||||
/* "On the client side, this is the send key; "
|
||||
"on the server side, it is the receive key." */
|
||||
u_char Magic2[84] =
|
||||
{ 0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69,
|
||||
0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20,
|
||||
0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68,
|
||||
0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20, 0x6b, 0x65, 0x79,
|
||||
0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73,
|
||||
0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73, 0x69, 0x64, 0x65,
|
||||
0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68,
|
||||
0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20,
|
||||
0x6b, 0x65, 0x79, 0x2e };
|
||||
/* "On the client side, this is the receive key; "
|
||||
"on the server side, it is the send key." */
|
||||
u_char Magic3[84] =
|
||||
{ 0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69,
|
||||
0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20,
|
||||
0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68,
|
||||
0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20,
|
||||
0x6b, 0x65, 0x79, 0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68,
|
||||
0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73,
|
||||
0x69, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73,
|
||||
0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20,
|
||||
0x6b, 0x65, 0x79, 0x2e };
|
||||
u_char *s;
|
||||
|
||||
SHA1_Init(&sha1Context);
|
||||
SHA1_Update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE);
|
||||
SHA1_Update(&sha1Context, NTResponse, 24);
|
||||
SHA1_Update(&sha1Context, Magic1, sizeof(Magic1));
|
||||
SHA1_Final(MasterKey, &sha1Context);
|
||||
|
||||
/*
|
||||
* generate send key
|
||||
*/
|
||||
if (IsServer)
|
||||
s = Magic3;
|
||||
else
|
||||
s = Magic2;
|
||||
SHA1_Init(&sha1Context);
|
||||
SHA1_Update(&sha1Context, MasterKey, 16);
|
||||
SHA1_Update(&sha1Context, SHApad1, sizeof(SHApad1));
|
||||
SHA1_Update(&sha1Context, s, 84);
|
||||
SHA1_Update(&sha1Context, SHApad2, sizeof(SHApad2));
|
||||
SHA1_Final(Digest, &sha1Context);
|
||||
|
||||
BCOPY(Digest, mppe_send_key, sizeof(mppe_send_key));
|
||||
|
||||
/*
|
||||
* generate recv key
|
||||
*/
|
||||
if (IsServer)
|
||||
s = Magic2;
|
||||
else
|
||||
s = Magic3;
|
||||
SHA1_Init(&sha1Context);
|
||||
SHA1_Update(&sha1Context, MasterKey, 16);
|
||||
SHA1_Update(&sha1Context, SHApad1, sizeof(SHApad1));
|
||||
SHA1_Update(&sha1Context, s, 84);
|
||||
SHA1_Update(&sha1Context, SHApad2, sizeof(SHApad2));
|
||||
SHA1_Final(Digest, &sha1Context);
|
||||
|
||||
BCOPY(Digest, mppe_recv_key, sizeof(mppe_recv_key));
|
||||
|
||||
mppe_keys_set = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set mppe_xxxx_key from MS-CHAPv2 credentials. (see RFC 3079)
|
||||
*/
|
||||
static void
|
||||
SetMasterKeys(char *secret, int secret_len, u_char NTResponse[24], int IsServer)
|
||||
{
|
||||
u_char unicodePassword[MAX_NT_PASSWORD * 2];
|
||||
u_char PasswordHash[MD4_SIGNATURE_SIZE];
|
||||
u_char PasswordHashHash[MD4_SIGNATURE_SIZE];
|
||||
/* Hash (x2) the Unicode version of the secret (== password). */
|
||||
ascii2unicode(secret, secret_len, unicodePassword);
|
||||
NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash);
|
||||
NTPasswordHash(PasswordHash, sizeof(PasswordHash), PasswordHashHash);
|
||||
mppe_set_keys2(PasswordHashHash, NTResponse, IsServer);
|
||||
}
|
||||
|
||||
#endif /* MPPE */
|
||||
|
||||
|
||||
void
|
||||
ChapMS(u_char *rchallenge, char *secret, int secret_len,
|
||||
unsigned char *response)
|
||||
{
|
||||
BZERO(response, MS_CHAP_RESPONSE_LEN);
|
||||
|
||||
ChapMS_NT(rchallenge, secret, secret_len, &response[MS_CHAP_NTRESP]);
|
||||
|
||||
#ifdef MSLANMAN
|
||||
ChapMS_LANMan(rchallenge, secret, secret_len,
|
||||
&response[MS_CHAP_LANMANRESP]);
|
||||
|
||||
/* preferred method is set by option */
|
||||
response[MS_CHAP_USENT] = !ms_lanman;
|
||||
#else
|
||||
response[MS_CHAP_USENT] = 1;
|
||||
#endif
|
||||
|
||||
#ifdef MPPE
|
||||
Set_Start_Key(rchallenge, secret, secret_len);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* If PeerChallenge is NULL, one is generated and the PeerChallenge
|
||||
* field of response is filled in. Call this way when generating a response.
|
||||
* If PeerChallenge is supplied, it is copied into the PeerChallenge field.
|
||||
* Call this way when verifying a response (or debugging).
|
||||
* Do not call with PeerChallenge = response.
|
||||
*
|
||||
* The PeerChallenge field of response is then used for calculation of the
|
||||
* Authenticator Response.
|
||||
*/
|
||||
void
|
||||
ChapMS2(u_char *rchallenge, u_char *PeerChallenge,
|
||||
char *user, char *secret, int secret_len, unsigned char *response,
|
||||
u_char authResponse[], int authenticator)
|
||||
{
|
||||
/* ARGSUSED */
|
||||
u_char *p = &response[MS_CHAP2_PEER_CHALLENGE];
|
||||
int i;
|
||||
|
||||
BZERO(response, MS_CHAP2_RESPONSE_LEN);
|
||||
|
||||
/* Generate the Peer-Challenge if requested, or copy it if supplied. */
|
||||
if (!PeerChallenge)
|
||||
for (i = 0; i < MS_CHAP2_PEER_CHAL_LEN; i++)
|
||||
*p++ = (u_char) (drand48() * 0xff);
|
||||
else
|
||||
BCOPY(PeerChallenge, &response[MS_CHAP2_PEER_CHALLENGE],
|
||||
MS_CHAP2_PEER_CHAL_LEN);
|
||||
|
||||
/* Generate the NT-Response */
|
||||
ChapMS2_NT(rchallenge, &response[MS_CHAP2_PEER_CHALLENGE], user,
|
||||
secret, secret_len, &response[MS_CHAP2_NTRESP]);
|
||||
|
||||
/* Generate the Authenticator Response. */
|
||||
GenerateAuthenticatorResponsePlain(secret, secret_len,
|
||||
&response[MS_CHAP2_NTRESP],
|
||||
&response[MS_CHAP2_PEER_CHALLENGE],
|
||||
rchallenge, user, authResponse);
|
||||
|
||||
#ifdef MPPE
|
||||
SetMasterKeys(secret, secret_len,
|
||||
&response[MS_CHAP2_NTRESP], authenticator);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef MPPE
|
||||
/*
|
||||
* Set MPPE options from plugins.
|
||||
*/
|
||||
void
|
||||
set_mppe_enc_types(int policy, int types)
|
||||
{
|
||||
/* Early exit for unknown policies. */
|
||||
if (policy != MPPE_ENC_POL_ENC_ALLOWED ||
|
||||
policy != MPPE_ENC_POL_ENC_REQUIRED)
|
||||
return;
|
||||
|
||||
/* Don't modify MPPE if it's optional and wasn't already configured. */
|
||||
if (policy == MPPE_ENC_POL_ENC_ALLOWED && !ccp_wantoptions[0].mppe)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Disable undesirable encryption types. Note that we don't ENABLE
|
||||
* any encryption types, to avoid overriding manual configuration.
|
||||
*/
|
||||
switch(types) {
|
||||
case MPPE_ENC_TYPES_RC4_40:
|
||||
ccp_wantoptions[0].mppe &= ~MPPE_OPT_128; /* disable 128-bit */
|
||||
break;
|
||||
case MPPE_ENC_TYPES_RC4_128:
|
||||
ccp_wantoptions[0].mppe &= ~MPPE_OPT_40; /* disable 40-bit */
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* MPPE */
|
||||
|
||||
static struct chap_digest_type chapms_digest = {
|
||||
CHAP_MICROSOFT, /* code */
|
||||
chapms_generate_challenge,
|
||||
chapms_verify_response,
|
||||
chapms_make_response,
|
||||
NULL, /* check_success */
|
||||
chapms_handle_failure,
|
||||
};
|
||||
|
||||
static struct chap_digest_type chapms2_digest = {
|
||||
CHAP_MICROSOFT_V2, /* code */
|
||||
chapms2_generate_challenge,
|
||||
chapms2_verify_response,
|
||||
chapms2_make_response,
|
||||
chapms2_check_success,
|
||||
chapms_handle_failure,
|
||||
};
|
||||
|
||||
void
|
||||
chapms_init(void)
|
||||
{
|
||||
chap_register_digest(&chapms_digest);
|
||||
chap_register_digest(&chapms2_digest);
|
||||
add_options(chapms_option_list);
|
||||
}
|
||||
|
||||
#endif /* CHAPMS */
|
109
src/netif/ppp/chap_ms.h
Normal file
109
src/netif/ppp/chap_ms.h
Normal file
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* chap_ms.h - Challenge Handshake Authentication Protocol definitions.
|
||||
*
|
||||
* Copyright (c) 1995 Eric Rosenquist. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. The name(s) of the authors of this software must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission.
|
||||
*
|
||||
* THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
|
||||
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: chap_ms.h,v 1.13 2004/11/15 22:13:26 paulus Exp $
|
||||
*/
|
||||
|
||||
#ifndef __CHAPMS_INCLUDE__
|
||||
|
||||
#define MD4_SIGNATURE_SIZE 16 /* 16 bytes in a MD4 message digest */
|
||||
#define MAX_NT_PASSWORD 256 /* Max (Unicode) chars in an NT pass */
|
||||
|
||||
#define MS_CHAP_RESPONSE_LEN 49 /* Response length for MS-CHAP */
|
||||
#define MS_CHAP2_RESPONSE_LEN 49 /* Response length for MS-CHAPv2 */
|
||||
#define MS_AUTH_RESPONSE_LENGTH 40 /* MS-CHAPv2 authenticator response, */
|
||||
/* as ASCII */
|
||||
|
||||
/* E=eeeeeeeeee error codes for MS-CHAP failure messages. */
|
||||
#define MS_CHAP_ERROR_RESTRICTED_LOGON_HOURS 646
|
||||
#define MS_CHAP_ERROR_ACCT_DISABLED 647
|
||||
#define MS_CHAP_ERROR_PASSWD_EXPIRED 648
|
||||
#define MS_CHAP_ERROR_NO_DIALIN_PERMISSION 649
|
||||
#define MS_CHAP_ERROR_AUTHENTICATION_FAILURE 691
|
||||
#define MS_CHAP_ERROR_CHANGING_PASSWORD 709
|
||||
|
||||
/*
|
||||
* Offsets within the response field for MS-CHAP
|
||||
*/
|
||||
#define MS_CHAP_LANMANRESP 0
|
||||
#define MS_CHAP_LANMANRESP_LEN 24
|
||||
#define MS_CHAP_NTRESP 24
|
||||
#define MS_CHAP_NTRESP_LEN 24
|
||||
#define MS_CHAP_USENT 48
|
||||
|
||||
/*
|
||||
* Offsets within the response field for MS-CHAP2
|
||||
*/
|
||||
#define MS_CHAP2_PEER_CHALLENGE 0
|
||||
#define MS_CHAP2_PEER_CHAL_LEN 16
|
||||
#define MS_CHAP2_RESERVED_LEN 8
|
||||
#define MS_CHAP2_NTRESP 24
|
||||
#define MS_CHAP2_NTRESP_LEN 24
|
||||
#define MS_CHAP2_FLAGS 48
|
||||
|
||||
#ifdef MPPE
|
||||
#include "mppe.h" /* MPPE_MAX_KEY_LEN */
|
||||
extern u_char mppe_send_key[MPPE_MAX_KEY_LEN];
|
||||
extern u_char mppe_recv_key[MPPE_MAX_KEY_LEN];
|
||||
extern int mppe_keys_set;
|
||||
|
||||
/* These values are the RADIUS attribute values--see RFC 2548. */
|
||||
#define MPPE_ENC_POL_ENC_ALLOWED 1
|
||||
#define MPPE_ENC_POL_ENC_REQUIRED 2
|
||||
#define MPPE_ENC_TYPES_RC4_40 2
|
||||
#define MPPE_ENC_TYPES_RC4_128 4
|
||||
|
||||
/* used by plugins (using above values) */
|
||||
extern void set_mppe_enc_types(int, int);
|
||||
#endif
|
||||
|
||||
/* Are we the authenticator or authenticatee? For MS-CHAPv2 key derivation. */
|
||||
#define MS_CHAP2_AUTHENTICATEE 0
|
||||
#define MS_CHAP2_AUTHENTICATOR 1
|
||||
|
||||
void ChapMS __P((u_char *, char *, int, u_char *));
|
||||
void ChapMS2 __P((u_char *, u_char *, char *, char *, int,
|
||||
u_char *, u_char[MS_AUTH_RESPONSE_LENGTH+1], int));
|
||||
#ifdef MPPE
|
||||
void mppe_set_keys __P((u_char *, u_char[MD4_SIGNATURE_SIZE]));
|
||||
void mppe_set_keys2(u_char PasswordHashHash[MD4_SIGNATURE_SIZE],
|
||||
u_char NTResponse[24], int IsServer);
|
||||
#endif
|
||||
|
||||
void ChallengeHash __P((u_char[16], u_char *, char *, u_char[8]));
|
||||
|
||||
void GenerateAuthenticatorResponse(u_char PasswordHashHash[MD4_SIGNATURE_SIZE],
|
||||
u_char NTResponse[24], u_char PeerChallenge[16],
|
||||
u_char *rchallenge, char *username,
|
||||
u_char authResponse[MS_AUTH_RESPONSE_LENGTH+1]);
|
||||
|
||||
void chapms_init(void);
|
||||
|
||||
#define __CHAPMS_INCLUDE__
|
||||
#endif /* __CHAPMS_INCLUDE__ */
|
530
src/netif/ppp/des.c
Normal file
530
src/netif/ppp/des.c
Normal file
@ -0,0 +1,530 @@
|
||||
/* $OpenBSD: crypt.c,v 1.20 2005/08/08 08:05:33 espie Exp $ */
|
||||
|
||||
/*
|
||||
* FreeSec: libcrypt
|
||||
*
|
||||
* Copyright (c) 1994 David Burren
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 4. Neither the name of the author nor the names of other contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
* This is an original implementation of the DES and the crypt(3) interfaces
|
||||
* by David Burren <davidb@werj.com.au>.
|
||||
*
|
||||
* An excellent reference on the underlying algorithm (and related
|
||||
* algorithms) is:
|
||||
*
|
||||
* B. Schneier, Applied Cryptography: protocols, algorithms,
|
||||
* and source code in C, John Wiley & Sons, 1994.
|
||||
*
|
||||
* Note that in that book's description of DES the lookups for the initial,
|
||||
* pbox, and final permutations are inverted (this has been brought to the
|
||||
* attention of the author). A list of errata for this book has been
|
||||
* posted to the sci.crypt newsgroup by the author and is available for FTP.
|
||||
*/
|
||||
|
||||
#include "lwip/opt.h"
|
||||
/* FIXME: don't build if not necessary */
|
||||
|
||||
#include "lwip/def.h"
|
||||
|
||||
static const u_char IP[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 u_char inv_key_perm[64];
|
||||
static u_char u_key_perm[56];
|
||||
static u_char const key_perm[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 u_char key_shifts[16] = {
|
||||
1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
|
||||
};
|
||||
|
||||
static u_char inv_comp_perm[56];
|
||||
static const u_char comp_perm[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
|
||||
};
|
||||
|
||||
/*
|
||||
* No E box is used, as it's replaced by some ANDs, shifts, and ORs.
|
||||
*/
|
||||
|
||||
static u_char u_sbox[8][64];
|
||||
static const u_char sbox[8][64] = {
|
||||
{
|
||||
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 u_char un_pbox[32];
|
||||
static const u_char pbox[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
|
||||
};
|
||||
|
||||
const u_int32_t _des_bits32[32] =
|
||||
{
|
||||
0x80000000, 0x40000000, 0x20000000, 0x10000000,
|
||||
0x08000000, 0x04000000, 0x02000000, 0x01000000,
|
||||
0x00800000, 0x00400000, 0x00200000, 0x00100000,
|
||||
0x00080000, 0x00040000, 0x00020000, 0x00010000,
|
||||
0x00008000, 0x00004000, 0x00002000, 0x00001000,
|
||||
0x00000800, 0x00000400, 0x00000200, 0x00000100,
|
||||
0x00000080, 0x00000040, 0x00000020, 0x00000010,
|
||||
0x00000008, 0x00000004, 0x00000002, 0x00000001
|
||||
};
|
||||
|
||||
const u_char _des_bits8[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
|
||||
|
||||
static const u_int32_t *bits28, *bits24;
|
||||
static u_char init_perm[64], final_perm[64];
|
||||
static u_int32_t en_keysl[16], en_keysr[16];
|
||||
static u_int32_t de_keysl[16], de_keysr[16];
|
||||
int _des_initialised = 0;
|
||||
static u_char m_sbox[4][4096];
|
||||
static u_int32_t psbox[4][256];
|
||||
static u_int32_t ip_maskl[8][256], ip_maskr[8][256];
|
||||
static u_int32_t fp_maskl[8][256], fp_maskr[8][256];
|
||||
static u_int32_t key_perm_maskl[8][128], key_perm_maskr[8][128];
|
||||
static u_int32_t comp_maskl[8][128], comp_maskr[8][128];
|
||||
static u_int32_t old_rawkey0, old_rawkey1;
|
||||
|
||||
void
|
||||
_des_init(void)
|
||||
{
|
||||
int i, j, b, k, inbit, obit;
|
||||
u_int32_t *p, *il, *ir, *fl, *fr;
|
||||
|
||||
old_rawkey0 = old_rawkey1 = 0;
|
||||
bits24 = (bits28 = _des_bits32 + 4) + 4;
|
||||
|
||||
/*
|
||||
* Invert the S-boxes, reordering the input bits.
|
||||
*/
|
||||
for (i = 0; i < 8; i++)
|
||||
for (j = 0; j < 64; j++) {
|
||||
b = (j & 0x20) | ((j & 1) << 4) | ((j >> 1) & 0xf);
|
||||
u_sbox[i][j] = sbox[i][b];
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert the inverted S-boxes into 4 arrays of 8 bits.
|
||||
* Each will handle 12 bits of the S-box input.
|
||||
*/
|
||||
for (b = 0; b < 4; b++)
|
||||
for (i = 0; i < 64; i++)
|
||||
for (j = 0; j < 64; j++)
|
||||
m_sbox[b][(i << 6) | j] =
|
||||
(u_sbox[(b << 1)][i] << 4) |
|
||||
u_sbox[(b << 1) + 1][j];
|
||||
|
||||
/*
|
||||
* Set up the initial & final permutations into a useful form, and
|
||||
* initialise the inverted key permutation.
|
||||
*/
|
||||
for (i = 0; i < 64; i++) {
|
||||
init_perm[final_perm[i] = IP[i] - 1] = i;
|
||||
inv_key_perm[i] = 255;
|
||||
}
|
||||
|
||||
/*
|
||||
* Invert the key permutation and initialise the inverted key
|
||||
* compression permutation.
|
||||
*/
|
||||
for (i = 0; i < 56; i++) {
|
||||
u_key_perm[i] = key_perm[i] - 1;
|
||||
inv_key_perm[key_perm[i] - 1] = i;
|
||||
inv_comp_perm[i] = 255;
|
||||
}
|
||||
|
||||
/*
|
||||
* Invert the key compression permutation.
|
||||
*/
|
||||
for (i = 0; i < 48; i++) {
|
||||
inv_comp_perm[comp_perm[i] - 1] = i;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up the OR-mask arrays for the initial and final permutations,
|
||||
* and for the key initial and compression permutations.
|
||||
*/
|
||||
for (k = 0; k < 8; k++) {
|
||||
for (i = 0; i < 256; i++) {
|
||||
*(il = &ip_maskl[k][i]) = 0;
|
||||
*(ir = &ip_maskr[k][i]) = 0;
|
||||
*(fl = &fp_maskl[k][i]) = 0;
|
||||
*(fr = &fp_maskr[k][i]) = 0;
|
||||
for (j = 0; j < 8; j++) {
|
||||
inbit = 8 * k + j;
|
||||
if (i & _des_bits8[j]) {
|
||||
if ((obit = init_perm[inbit]) < 32)
|
||||
*il |= _des_bits32[obit];
|
||||
else
|
||||
*ir |= _des_bits32[obit-32];
|
||||
if ((obit = final_perm[inbit]) < 32)
|
||||
*fl |= _des_bits32[obit];
|
||||
else
|
||||
*fr |= _des_bits32[obit - 32];
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = 0; i < 128; i++) {
|
||||
*(il = &key_perm_maskl[k][i]) = 0;
|
||||
*(ir = &key_perm_maskr[k][i]) = 0;
|
||||
for (j = 0; j < 7; j++) {
|
||||
inbit = 8 * k + j;
|
||||
if (i & _des_bits8[j + 1]) {
|
||||
if ((obit = inv_key_perm[inbit]) == 255)
|
||||
continue;
|
||||
if (obit < 28)
|
||||
*il |= bits28[obit];
|
||||
else
|
||||
*ir |= bits28[obit - 28];
|
||||
}
|
||||
}
|
||||
*(il = &comp_maskl[k][i]) = 0;
|
||||
*(ir = &comp_maskr[k][i]) = 0;
|
||||
for (j = 0; j < 7; j++) {
|
||||
inbit = 7 * k + j;
|
||||
if (i & _des_bits8[j + 1]) {
|
||||
if ((obit=inv_comp_perm[inbit]) == 255)
|
||||
continue;
|
||||
if (obit < 24)
|
||||
*il |= bits24[obit];
|
||||
else
|
||||
*ir |= bits24[obit - 24];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Invert the P-box permutation, and convert into OR-masks for
|
||||
* handling the output of the S-box arrays setup above.
|
||||
*/
|
||||
for (i = 0; i < 32; i++)
|
||||
un_pbox[pbox[i] - 1] = i;
|
||||
|
||||
for (b = 0; b < 4; b++)
|
||||
for (i = 0; i < 256; i++) {
|
||||
*(p = &psbox[b][i]) = 0;
|
||||
for (j = 0; j < 8; j++) {
|
||||
if (i & _des_bits8[j])
|
||||
*p |= _des_bits32[un_pbox[8 * b + j]];
|
||||
}
|
||||
}
|
||||
|
||||
_des_initialised = 1;
|
||||
}
|
||||
|
||||
int
|
||||
des_setkey(const char *key)
|
||||
{
|
||||
u_int32_t k0, k1, rawkey0, rawkey1;
|
||||
int shifts, round;
|
||||
|
||||
if (!_des_initialised)
|
||||
_des_init();
|
||||
|
||||
rawkey0 = ntohl(*(u_int32_t *) key);
|
||||
rawkey1 = ntohl(*(u_int32_t *) (key + 4));
|
||||
|
||||
if ((rawkey0 | rawkey1)
|
||||
&& rawkey0 == old_rawkey0
|
||||
&& rawkey1 == old_rawkey1) {
|
||||
/*
|
||||
* Already setup for this key.
|
||||
* This optimisation fails on a zero key (which is weak and
|
||||
* has bad parity anyway) in order to simplify the starting
|
||||
* conditions.
|
||||
*/
|
||||
return(0);
|
||||
}
|
||||
old_rawkey0 = rawkey0;
|
||||
old_rawkey1 = rawkey1;
|
||||
|
||||
/*
|
||||
* Do key permutation and split into two 28-bit subkeys.
|
||||
*/
|
||||
k0 = key_perm_maskl[0][rawkey0 >> 25]
|
||||
| key_perm_maskl[1][(rawkey0 >> 17) & 0x7f]
|
||||
| key_perm_maskl[2][(rawkey0 >> 9) & 0x7f]
|
||||
| key_perm_maskl[3][(rawkey0 >> 1) & 0x7f]
|
||||
| key_perm_maskl[4][rawkey1 >> 25]
|
||||
| key_perm_maskl[5][(rawkey1 >> 17) & 0x7f]
|
||||
| key_perm_maskl[6][(rawkey1 >> 9) & 0x7f]
|
||||
| key_perm_maskl[7][(rawkey1 >> 1) & 0x7f];
|
||||
k1 = key_perm_maskr[0][rawkey0 >> 25]
|
||||
| key_perm_maskr[1][(rawkey0 >> 17) & 0x7f]
|
||||
| key_perm_maskr[2][(rawkey0 >> 9) & 0x7f]
|
||||
| key_perm_maskr[3][(rawkey0 >> 1) & 0x7f]
|
||||
| key_perm_maskr[4][rawkey1 >> 25]
|
||||
| key_perm_maskr[5][(rawkey1 >> 17) & 0x7f]
|
||||
| key_perm_maskr[6][(rawkey1 >> 9) & 0x7f]
|
||||
| key_perm_maskr[7][(rawkey1 >> 1) & 0x7f];
|
||||
/*
|
||||
* Rotate subkeys and do compression permutation.
|
||||
*/
|
||||
shifts = 0;
|
||||
for (round = 0; round < 16; round++) {
|
||||
u_int32_t t0, t1;
|
||||
|
||||
shifts += key_shifts[round];
|
||||
|
||||
t0 = (k0 << shifts) | (k0 >> (28 - shifts));
|
||||
t1 = (k1 << shifts) | (k1 >> (28 - shifts));
|
||||
|
||||
de_keysl[15 - round] =
|
||||
en_keysl[round] = comp_maskl[0][(t0 >> 21) & 0x7f]
|
||||
| comp_maskl[1][(t0 >> 14) & 0x7f]
|
||||
| comp_maskl[2][(t0 >> 7) & 0x7f]
|
||||
| comp_maskl[3][t0 & 0x7f]
|
||||
| comp_maskl[4][(t1 >> 21) & 0x7f]
|
||||
| comp_maskl[5][(t1 >> 14) & 0x7f]
|
||||
| comp_maskl[6][(t1 >> 7) & 0x7f]
|
||||
| comp_maskl[7][t1 & 0x7f];
|
||||
|
||||
de_keysr[15 - round] =
|
||||
en_keysr[round] = comp_maskr[0][(t0 >> 21) & 0x7f]
|
||||
| comp_maskr[1][(t0 >> 14) & 0x7f]
|
||||
| comp_maskr[2][(t0 >> 7) & 0x7f]
|
||||
| comp_maskr[3][t0 & 0x7f]
|
||||
| comp_maskr[4][(t1 >> 21) & 0x7f]
|
||||
| comp_maskr[5][(t1 >> 14) & 0x7f]
|
||||
| comp_maskr[6][(t1 >> 7) & 0x7f]
|
||||
| comp_maskr[7][t1 & 0x7f];
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
int
|
||||
_des_do_des(u_int32_t l_in, u_int32_t r_in, u_int32_t *l_out, u_int32_t *r_out,
|
||||
int count)
|
||||
{
|
||||
/*
|
||||
* l_in, r_in, l_out, and r_out are in pseudo-"big-endian" format.
|
||||
*/
|
||||
u_int32_t l, r, *kl, *kr, *kl1, *kr1;
|
||||
u_int32_t f, r48l, r48r;
|
||||
int round;
|
||||
|
||||
if (count == 0) {
|
||||
return(1);
|
||||
} else if (count > 0) {
|
||||
/*
|
||||
* Encrypting
|
||||
*/
|
||||
kl1 = en_keysl;
|
||||
kr1 = en_keysr;
|
||||
} else {
|
||||
/*
|
||||
* Decrypting
|
||||
*/
|
||||
count = -count;
|
||||
kl1 = de_keysl;
|
||||
kr1 = de_keysr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Do initial permutation (IP).
|
||||
*/
|
||||
l = ip_maskl[0][l_in >> 24]
|
||||
| ip_maskl[1][(l_in >> 16) & 0xff]
|
||||
| ip_maskl[2][(l_in >> 8) & 0xff]
|
||||
| ip_maskl[3][l_in & 0xff]
|
||||
| ip_maskl[4][r_in >> 24]
|
||||
| ip_maskl[5][(r_in >> 16) & 0xff]
|
||||
| ip_maskl[6][(r_in >> 8) & 0xff]
|
||||
| ip_maskl[7][r_in & 0xff];
|
||||
r = ip_maskr[0][l_in >> 24]
|
||||
| ip_maskr[1][(l_in >> 16) & 0xff]
|
||||
| ip_maskr[2][(l_in >> 8) & 0xff]
|
||||
| ip_maskr[3][l_in & 0xff]
|
||||
| ip_maskr[4][r_in >> 24]
|
||||
| ip_maskr[5][(r_in >> 16) & 0xff]
|
||||
| ip_maskr[6][(r_in >> 8) & 0xff]
|
||||
| ip_maskr[7][r_in & 0xff];
|
||||
|
||||
while (count--) {
|
||||
/*
|
||||
* Do each round.
|
||||
*/
|
||||
kl = kl1;
|
||||
kr = kr1;
|
||||
round = 16;
|
||||
while (round--) {
|
||||
/*
|
||||
* Expand R to 48 bits (simulate the E-box).
|
||||
*/
|
||||
r48l = ((r & 0x00000001) << 23)
|
||||
| ((r & 0xf8000000) >> 9)
|
||||
| ((r & 0x1f800000) >> 11)
|
||||
| ((r & 0x01f80000) >> 13)
|
||||
| ((r & 0x001f8000) >> 15);
|
||||
|
||||
r48r = ((r & 0x0001f800) << 7)
|
||||
| ((r & 0x00001f80) << 5)
|
||||
| ((r & 0x000001f8) << 3)
|
||||
| ((r & 0x0000001f) << 1)
|
||||
| ((r & 0x80000000) >> 31);
|
||||
/*
|
||||
* Do XOR with the permuted key.
|
||||
*/
|
||||
r48l ^= *kl++;
|
||||
r48r ^= *kr++;
|
||||
/*
|
||||
* Do sbox lookups (which shrink it back to 32 bits)
|
||||
* and do the pbox permutation at the same time.
|
||||
*/
|
||||
f = psbox[0][m_sbox[0][r48l >> 12]]
|
||||
| psbox[1][m_sbox[1][r48l & 0xfff]]
|
||||
| psbox[2][m_sbox[2][r48r >> 12]]
|
||||
| psbox[3][m_sbox[3][r48r & 0xfff]];
|
||||
/*
|
||||
* Now that we've permuted things, complete f().
|
||||
*/
|
||||
f ^= l;
|
||||
l = r;
|
||||
r = f;
|
||||
}
|
||||
r = l;
|
||||
l = f;
|
||||
}
|
||||
/*
|
||||
* Do final permutation (inverse of IP).
|
||||
*/
|
||||
*l_out = fp_maskl[0][l >> 24]
|
||||
| fp_maskl[1][(l >> 16) & 0xff]
|
||||
| fp_maskl[2][(l >> 8) & 0xff]
|
||||
| fp_maskl[3][l & 0xff]
|
||||
| fp_maskl[4][r >> 24]
|
||||
| fp_maskl[5][(r >> 16) & 0xff]
|
||||
| fp_maskl[6][(r >> 8) & 0xff]
|
||||
| fp_maskl[7][r & 0xff];
|
||||
*r_out = fp_maskr[0][l >> 24]
|
||||
| fp_maskr[1][(l >> 16) & 0xff]
|
||||
| fp_maskr[2][(l >> 8) & 0xff]
|
||||
| fp_maskr[3][l & 0xff]
|
||||
| fp_maskr[4][r >> 24]
|
||||
| fp_maskr[5][(r >> 16) & 0xff]
|
||||
| fp_maskr[6][(r >> 8) & 0xff]
|
||||
| fp_maskr[7][r & 0xff];
|
||||
return(0);
|
||||
}
|
||||
|
||||
int setkey(const char *key) {
|
||||
int i, j;
|
||||
u_int32_t packed_keys[2];
|
||||
u_char *p;
|
||||
|
||||
p = (u_char *) packed_keys;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
p[i] = 0;
|
||||
for (j = 0; j < 8; j++)
|
||||
if (*key++ & 1)
|
||||
p[i] |= _des_bits8[j];
|
||||
}
|
||||
return(des_setkey((char *)p));
|
||||
}
|
||||
|
||||
int encrypt(char *block, int flag) {
|
||||
u_int32_t io[2];
|
||||
u_char *p;
|
||||
int i, j, retval;
|
||||
|
||||
if (!_des_initialised)
|
||||
_des_init();
|
||||
|
||||
p = (u_char *)block;
|
||||
for (i = 0; i < 2; i++) {
|
||||
io[i] = 0L;
|
||||
for (j = 0; j < 32; j++)
|
||||
if (*p++ & 1)
|
||||
io[i] |= _des_bits32[j];
|
||||
}
|
||||
retval = _des_do_des(io[0], io[1], io, io + 1, flag ? -1 : 1);
|
||||
for (i = 0; i < 2; i++)
|
||||
for (j = 0; j < 32; j++)
|
||||
block[(i << 5) | j] = (io[i] & _des_bits32[j]) ? 1 : 0;
|
||||
return(retval);
|
||||
}
|
40
src/netif/ppp/des.h
Normal file
40
src/netif/ppp/des.h
Normal file
@ -0,0 +1,40 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* DES header
|
||||
*/
|
||||
|
||||
/*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef DES_H_
|
||||
#define DES_H_
|
||||
|
||||
int setkey(const char *key);
|
||||
int encrypt(char *block, int flag);
|
||||
|
||||
#endif /* DES_H_ */
|
175
src/netif/ppp/ecp.c
Normal file
175
src/netif/ppp/ecp.c
Normal file
@ -0,0 +1,175 @@
|
||||
/*
|
||||
* ecp.c - PPP Encryption Control Protocol.
|
||||
*
|
||||
* Copyright (c) 2002 Google, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. The name(s) of the authors of this software must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission.
|
||||
*
|
||||
* THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
|
||||
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Derived from ccp.c, which is:
|
||||
*
|
||||
* Copyright (c) 1994-2002 Paul Mackerras. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. The name(s) of the authors of this software must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission.
|
||||
*
|
||||
* 3. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by Paul Mackerras
|
||||
* <paulus@samba.org>".
|
||||
*
|
||||
* THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
|
||||
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "lwip/opt.h"
|
||||
|
||||
#define RCSID "$Id: ecp.c,v 1.4 2004/11/04 10:02:26 paulus Exp $"
|
||||
|
||||
static const char rcsid[] = RCSID;
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "pppd.h"
|
||||
#include "fsm.h"
|
||||
#include "ecp.h"
|
||||
|
||||
static option_t ecp_option_list[] = {
|
||||
{ "noecp", o_bool, &ecp_protent.enabled_flag,
|
||||
"Disable ECP negotiation" },
|
||||
{ "-ecp", o_bool, &ecp_protent.enabled_flag,
|
||||
"Disable ECP negotiation", OPT_ALIAS },
|
||||
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
/*
|
||||
* Protocol entry points from main code.
|
||||
*/
|
||||
static void ecp_init __P((int unit));
|
||||
/*
|
||||
static void ecp_open __P((int unit));
|
||||
static void ecp_close __P((int unit, char *));
|
||||
static void ecp_lowerup __P((int unit));
|
||||
static void ecp_lowerdown __P((int));
|
||||
static void ecp_input __P((int unit, u_char *pkt, int len));
|
||||
static void ecp_protrej __P((int unit));
|
||||
*/
|
||||
static int ecp_printpkt __P((u_char *pkt, int len,
|
||||
void (*printer) __P((void *, char *, ...)),
|
||||
void *arg));
|
||||
/*
|
||||
static void ecp_datainput __P((int unit, u_char *pkt, int len));
|
||||
*/
|
||||
|
||||
struct protent ecp_protent = {
|
||||
PPP_ECP,
|
||||
ecp_init,
|
||||
NULL, /* ecp_input, */
|
||||
NULL, /* ecp_protrej, */
|
||||
NULL, /* ecp_lowerup, */
|
||||
NULL, /* ecp_lowerdown, */
|
||||
NULL, /* ecp_open, */
|
||||
NULL, /* ecp_close, */
|
||||
ecp_printpkt,
|
||||
NULL, /* ecp_datainput, */
|
||||
0,
|
||||
"ECP",
|
||||
"Encrypted",
|
||||
ecp_option_list,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
fsm ecp_fsm[NUM_PPP];
|
||||
ecp_options ecp_wantoptions[NUM_PPP]; /* what to request the peer to use */
|
||||
ecp_options ecp_gotoptions[NUM_PPP]; /* what the peer agreed to do */
|
||||
ecp_options ecp_allowoptions[NUM_PPP]; /* what we'll agree to do */
|
||||
ecp_options ecp_hisoptions[NUM_PPP]; /* what we agreed to do */
|
||||
|
||||
static fsm_callbacks ecp_callbacks = {
|
||||
NULL, /* ecp_resetci, */
|
||||
NULL, /* ecp_cilen, */
|
||||
NULL, /* ecp_addci, */
|
||||
NULL, /* ecp_ackci, */
|
||||
NULL, /* ecp_nakci, */
|
||||
NULL, /* ecp_rejci, */
|
||||
NULL, /* ecp_reqci, */
|
||||
NULL, /* ecp_up, */
|
||||
NULL, /* ecp_down, */
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL, /* ecp_extcode, */
|
||||
"ECP"
|
||||
};
|
||||
|
||||
/*
|
||||
* ecp_init - initialize ECP.
|
||||
*/
|
||||
static void
|
||||
ecp_init(unit)
|
||||
int unit;
|
||||
{
|
||||
fsm *f = &ecp_fsm[unit];
|
||||
|
||||
f->unit = unit;
|
||||
f->protocol = PPP_ECP;
|
||||
f->callbacks = &ecp_callbacks;
|
||||
fsm_init(f);
|
||||
|
||||
memset(&ecp_wantoptions[unit], 0, sizeof(ecp_options));
|
||||
memset(&ecp_gotoptions[unit], 0, sizeof(ecp_options));
|
||||
memset(&ecp_allowoptions[unit], 0, sizeof(ecp_options));
|
||||
memset(&ecp_hisoptions[unit], 0, sizeof(ecp_options));
|
||||
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
ecp_printpkt(p, plen, printer, arg)
|
||||
u_char *p;
|
||||
int plen;
|
||||
void (*printer) __P((void *, char *, ...));
|
||||
void *arg;
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
45
src/netif/ppp/ecp.h
Normal file
45
src/netif/ppp/ecp.h
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* ecp.h - Definitions for PPP Encryption Control Protocol.
|
||||
*
|
||||
* Copyright (c) 2002 Google, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. The name(s) of the authors of this software must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission.
|
||||
*
|
||||
* THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
|
||||
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* $Id: ecp.h,v 1.2 2003/01/10 07:12:36 fcusack Exp $
|
||||
*/
|
||||
|
||||
typedef struct ecp_options {
|
||||
bool required; /* Is ECP required? */
|
||||
unsigned enctype; /* Encryption type */
|
||||
} ecp_options;
|
||||
|
||||
extern fsm ecp_fsm[];
|
||||
extern ecp_options ecp_wantoptions[];
|
||||
extern ecp_options ecp_gotoptions[];
|
||||
extern ecp_options ecp_allowoptions[];
|
||||
extern ecp_options ecp_hisoptions[];
|
||||
|
||||
extern struct protent ecp_protent;
|
301
src/netif/ppp/md4.c
Normal file
301
src/netif/ppp/md4.c
Normal file
@ -0,0 +1,301 @@
|
||||
/*
|
||||
** ********************************************************************
|
||||
** md4.c -- Implementation of MD4 Message Digest Algorithm **
|
||||
** Updated: 2/16/90 by Ronald L. Rivest **
|
||||
** (C) 1990 RSA Data Security, Inc. **
|
||||
** ********************************************************************
|
||||
*/
|
||||
|
||||
#include "lwip/opt.h"
|
||||
|
||||
/*
|
||||
** To use MD4:
|
||||
** -- Include md4.h in your program
|
||||
** -- Declare an MDstruct MD to hold the state of the digest
|
||||
** computation.
|
||||
** -- Initialize MD using MDbegin(&MD)
|
||||
** -- For each full block (64 bytes) X you wish to process, call
|
||||
** MD4Update(&MD,X,512)
|
||||
** (512 is the number of bits in a full block.)
|
||||
** -- For the last block (less than 64 bytes) you wish to process,
|
||||
** MD4Update(&MD,X,n)
|
||||
** where n is the number of bits in the partial block. A partial
|
||||
** block terminates the computation, so every MD computation
|
||||
** should terminate by processing a partial block, even if it
|
||||
** has n = 0.
|
||||
** -- The message digest is available in MD.buffer[0] ...
|
||||
** MD.buffer[3]. (Least-significant byte of each word
|
||||
** should be output first.)
|
||||
** -- You can print out the digest using MDprint(&MD)
|
||||
*/
|
||||
|
||||
/* Implementation notes:
|
||||
** This implementation assumes that ints are 32-bit quantities.
|
||||
*/
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
/* Compile-time includes
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include "md4.h"
|
||||
#include "pppd.h"
|
||||
|
||||
/* Compile-time declarations of MD4 "magic constants".
|
||||
*/
|
||||
#define I0 0x67452301 /* Initial values for MD buffer */
|
||||
#define I1 0xefcdab89
|
||||
#define I2 0x98badcfe
|
||||
#define I3 0x10325476
|
||||
#define C2 013240474631 /* round 2 constant = sqrt(2) in octal */
|
||||
#define C3 015666365641 /* round 3 constant = sqrt(3) in octal */
|
||||
/* C2 and C3 are from Knuth, The Art of Programming, Volume 2
|
||||
** (Seminumerical Algorithms), Second Edition (1981), Addison-Wesley.
|
||||
** Table 2, page 660.
|
||||
*/
|
||||
|
||||
#define fs1 3 /* round 1 shift amounts */
|
||||
#define fs2 7
|
||||
#define fs3 11
|
||||
#define fs4 19
|
||||
#define gs1 3 /* round 2 shift amounts */
|
||||
#define gs2 5
|
||||
#define gs3 9
|
||||
#define gs4 13
|
||||
#define hs1 3 /* round 3 shift amounts */
|
||||
#define hs2 9
|
||||
#define hs3 11
|
||||
#define hs4 15
|
||||
|
||||
/* Compile-time macro declarations for MD4.
|
||||
** Note: The "rot" operator uses the variable "tmp".
|
||||
** It assumes tmp is declared as unsigned int, so that the >>
|
||||
** operator will shift in zeros rather than extending the sign bit.
|
||||
*/
|
||||
#define f(X,Y,Z) ((X&Y) | ((~X)&Z))
|
||||
#define g(X,Y,Z) ((X&Y) | (X&Z) | (Y&Z))
|
||||
#define h(X,Y,Z) (X^Y^Z)
|
||||
#define rot(X,S) (tmp=X,(tmp<<S) | (tmp>>(32-S)))
|
||||
#define ff(A,B,C,D,i,s) A = rot((A + f(B,C,D) + X[i]),s)
|
||||
#define gg(A,B,C,D,i,s) A = rot((A + g(B,C,D) + X[i] + C2),s)
|
||||
#define hh(A,B,C,D,i,s) A = rot((A + h(B,C,D) + X[i] + C3),s)
|
||||
|
||||
/* MD4print(MDp)
|
||||
** Print message digest buffer MDp as 32 hexadecimal digits.
|
||||
** Order is from low-order byte of buffer[0] to high-order byte of
|
||||
** buffer[3].
|
||||
** Each byte is printed with high-order hexadecimal digit first.
|
||||
** This is a user-callable routine.
|
||||
*/
|
||||
void
|
||||
MD4Print(MDp)
|
||||
MD4_CTX *MDp;
|
||||
{
|
||||
int i,j;
|
||||
for (i=0;i<4;i++)
|
||||
for (j=0;j<32;j=j+8)
|
||||
printf("%02x",(MDp->buffer[i]>>j) & 0xFF);
|
||||
}
|
||||
|
||||
/* MD4Init(MDp)
|
||||
** Initialize message digest buffer MDp.
|
||||
** This is a user-callable routine.
|
||||
*/
|
||||
void
|
||||
MD4Init(MDp)
|
||||
MD4_CTX *MDp;
|
||||
{
|
||||
int i;
|
||||
MDp->buffer[0] = I0;
|
||||
MDp->buffer[1] = I1;
|
||||
MDp->buffer[2] = I2;
|
||||
MDp->buffer[3] = I3;
|
||||
for (i=0;i<8;i++) MDp->count[i] = 0;
|
||||
MDp->done = 0;
|
||||
}
|
||||
|
||||
/* MDblock(MDp,X)
|
||||
** Update message digest buffer MDp->buffer using 16-word data block X.
|
||||
** Assumes all 16 words of X are full of data.
|
||||
** Does not update MDp->count.
|
||||
** This routine is not user-callable.
|
||||
*/
|
||||
static void
|
||||
MDblock(MDp,Xb)
|
||||
MD4_CTX *MDp;
|
||||
unsigned char *Xb;
|
||||
{
|
||||
register unsigned int tmp, A, B, C, D;
|
||||
unsigned int X[16];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 16; ++i) {
|
||||
X[i] = Xb[0] + (Xb[1] << 8) + (Xb[2] << 16) + (Xb[3] << 24);
|
||||
Xb += 4;
|
||||
}
|
||||
|
||||
A = MDp->buffer[0];
|
||||
B = MDp->buffer[1];
|
||||
C = MDp->buffer[2];
|
||||
D = MDp->buffer[3];
|
||||
/* Update the message digest buffer */
|
||||
ff(A , B , C , D , 0 , fs1); /* Round 1 */
|
||||
ff(D , A , B , C , 1 , fs2);
|
||||
ff(C , D , A , B , 2 , fs3);
|
||||
ff(B , C , D , A , 3 , fs4);
|
||||
ff(A , B , C , D , 4 , fs1);
|
||||
ff(D , A , B , C , 5 , fs2);
|
||||
ff(C , D , A , B , 6 , fs3);
|
||||
ff(B , C , D , A , 7 , fs4);
|
||||
ff(A , B , C , D , 8 , fs1);
|
||||
ff(D , A , B , C , 9 , fs2);
|
||||
ff(C , D , A , B , 10 , fs3);
|
||||
ff(B , C , D , A , 11 , fs4);
|
||||
ff(A , B , C , D , 12 , fs1);
|
||||
ff(D , A , B , C , 13 , fs2);
|
||||
ff(C , D , A , B , 14 , fs3);
|
||||
ff(B , C , D , A , 15 , fs4);
|
||||
gg(A , B , C , D , 0 , gs1); /* Round 2 */
|
||||
gg(D , A , B , C , 4 , gs2);
|
||||
gg(C , D , A , B , 8 , gs3);
|
||||
gg(B , C , D , A , 12 , gs4);
|
||||
gg(A , B , C , D , 1 , gs1);
|
||||
gg(D , A , B , C , 5 , gs2);
|
||||
gg(C , D , A , B , 9 , gs3);
|
||||
gg(B , C , D , A , 13 , gs4);
|
||||
gg(A , B , C , D , 2 , gs1);
|
||||
gg(D , A , B , C , 6 , gs2);
|
||||
gg(C , D , A , B , 10 , gs3);
|
||||
gg(B , C , D , A , 14 , gs4);
|
||||
gg(A , B , C , D , 3 , gs1);
|
||||
gg(D , A , B , C , 7 , gs2);
|
||||
gg(C , D , A , B , 11 , gs3);
|
||||
gg(B , C , D , A , 15 , gs4);
|
||||
hh(A , B , C , D , 0 , hs1); /* Round 3 */
|
||||
hh(D , A , B , C , 8 , hs2);
|
||||
hh(C , D , A , B , 4 , hs3);
|
||||
hh(B , C , D , A , 12 , hs4);
|
||||
hh(A , B , C , D , 2 , hs1);
|
||||
hh(D , A , B , C , 10 , hs2);
|
||||
hh(C , D , A , B , 6 , hs3);
|
||||
hh(B , C , D , A , 14 , hs4);
|
||||
hh(A , B , C , D , 1 , hs1);
|
||||
hh(D , A , B , C , 9 , hs2);
|
||||
hh(C , D , A , B , 5 , hs3);
|
||||
hh(B , C , D , A , 13 , hs4);
|
||||
hh(A , B , C , D , 3 , hs1);
|
||||
hh(D , A , B , C , 11 , hs2);
|
||||
hh(C , D , A , B , 7 , hs3);
|
||||
hh(B , C , D , A , 15 , hs4);
|
||||
MDp->buffer[0] += A;
|
||||
MDp->buffer[1] += B;
|
||||
MDp->buffer[2] += C;
|
||||
MDp->buffer[3] += D;
|
||||
}
|
||||
|
||||
/* MD4Update(MDp,X,count)
|
||||
** Input: X -- a pointer to an array of unsigned characters.
|
||||
** count -- the number of bits of X to use.
|
||||
** (if not a multiple of 8, uses high bits of last byte.)
|
||||
** Update MDp using the number of bits of X given by count.
|
||||
** This is the basic input routine for an MD4 user.
|
||||
** The routine completes the MD computation when count < 512, so
|
||||
** every MD computation should end with one call to MD4Update with a
|
||||
** count less than 512. A call with count 0 will be ignored if the
|
||||
** MD has already been terminated (done != 0), so an extra call with
|
||||
** count 0 can be given as a "courtesy close" to force termination
|
||||
** if desired.
|
||||
*/
|
||||
void
|
||||
MD4Update(MDp,X,count)
|
||||
MD4_CTX *MDp;
|
||||
unsigned char *X;
|
||||
unsigned int count;
|
||||
{
|
||||
unsigned int i, tmp, bit, byte, mask;
|
||||
unsigned char XX[64];
|
||||
unsigned char *p;
|
||||
|
||||
/* return with no error if this is a courtesy close with count
|
||||
** zero and MDp->done is true.
|
||||
*/
|
||||
if (count == 0 && MDp->done) return;
|
||||
/* check to see if MD is already done and report error */
|
||||
if (MDp->done)
|
||||
{ printf("\nError: MD4Update MD already done."); return; }
|
||||
|
||||
/* Add count to MDp->count */
|
||||
tmp = count;
|
||||
p = MDp->count;
|
||||
while (tmp)
|
||||
{ tmp += *p;
|
||||
*p++ = tmp;
|
||||
tmp = tmp >> 8;
|
||||
}
|
||||
|
||||
/* Process data */
|
||||
if (count == 512)
|
||||
{ /* Full block of data to handle */
|
||||
MDblock(MDp,X);
|
||||
}
|
||||
else if (count > 512) /* Check for count too large */
|
||||
{
|
||||
printf("\nError: MD4Update called with illegal count value %d.",
|
||||
count);
|
||||
return;
|
||||
}
|
||||
else /* partial block -- must be last block so finish up */
|
||||
{
|
||||
/* Find out how many bytes and residual bits there are */
|
||||
byte = count >> 3;
|
||||
bit = count & 7;
|
||||
/* Copy X into XX since we need to modify it */
|
||||
if (count)
|
||||
for (i=0;i<=byte;i++) XX[i] = X[i];
|
||||
for (i=byte+1;i<64;i++) XX[i] = 0;
|
||||
/* Add padding '1' bit and low-order zeros in last byte */
|
||||
mask = 1 << (7 - bit);
|
||||
XX[byte] = (XX[byte] | mask) & ~( mask - 1);
|
||||
/* If room for bit count, finish up with this block */
|
||||
if (byte <= 55)
|
||||
{
|
||||
for (i=0;i<8;i++) XX[56+i] = MDp->count[i];
|
||||
MDblock(MDp,XX);
|
||||
}
|
||||
else /* need to do two blocks to finish up */
|
||||
{
|
||||
MDblock(MDp,XX);
|
||||
for (i=0;i<56;i++) XX[i] = 0;
|
||||
for (i=0;i<8;i++) XX[56+i] = MDp->count[i];
|
||||
MDblock(MDp,XX);
|
||||
}
|
||||
/* Set flag saying we're done with MD computation */
|
||||
MDp->done = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Finish up MD4 computation and return message digest.
|
||||
*/
|
||||
void
|
||||
MD4Final(buf, MD)
|
||||
unsigned char *buf;
|
||||
MD4_CTX *MD;
|
||||
{
|
||||
int i, j;
|
||||
unsigned int w;
|
||||
|
||||
MD4Update(MD, NULL, 0);
|
||||
for (i = 0; i < 4; ++i) {
|
||||
w = MD->buffer[i];
|
||||
for (j = 0; j < 4; ++j) {
|
||||
*buf++ = w;
|
||||
w >>= 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** End of md4.c
|
||||
****************************(cut)***********************************/
|
64
src/netif/ppp/md4.h
Normal file
64
src/netif/ppp/md4.h
Normal file
@ -0,0 +1,64 @@
|
||||
|
||||
/*
|
||||
** ********************************************************************
|
||||
** md4.h -- Header file for implementation of **
|
||||
** MD4 Message Digest Algorithm **
|
||||
** Updated: 2/13/90 by Ronald L. Rivest **
|
||||
** (C) 1990 RSA Data Security, Inc. **
|
||||
** ********************************************************************
|
||||
*/
|
||||
|
||||
#ifndef __P
|
||||
# if defined(__STDC__) || defined(__GNUC__)
|
||||
# define __P(x) x
|
||||
# else
|
||||
# define __P(x) ()
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/* MDstruct is the data structure for a message digest computation.
|
||||
*/
|
||||
typedef struct {
|
||||
unsigned int buffer[4]; /* Holds 4-word result of MD computation */
|
||||
unsigned char count[8]; /* Number of bits processed so far */
|
||||
unsigned int done; /* Nonzero means MD computation finished */
|
||||
} MD4_CTX;
|
||||
|
||||
/* MD4Init(MD4_CTX *)
|
||||
** Initialize the MD4_CTX prepatory to doing a message digest
|
||||
** computation.
|
||||
*/
|
||||
extern void MD4Init __P((MD4_CTX *MD));
|
||||
|
||||
/* MD4Update(MD,X,count)
|
||||
** Input: X -- a pointer to an array of unsigned characters.
|
||||
** count -- the number of bits of X to use (an unsigned int).
|
||||
** Updates MD using the first "count" bits of X.
|
||||
** The array pointed to by X is not modified.
|
||||
** If count is not a multiple of 8, MD4Update uses high bits of
|
||||
** last byte.
|
||||
** This is the basic input routine for a user.
|
||||
** The routine terminates the MD computation when count < 512, so
|
||||
** every MD computation should end with one call to MD4Update with a
|
||||
** count less than 512. Zero is OK for a count.
|
||||
*/
|
||||
extern void MD4Update __P((MD4_CTX *MD, unsigned char *X, unsigned int count));
|
||||
|
||||
/* MD4Print(MD)
|
||||
** Prints message digest buffer MD as 32 hexadecimal digits.
|
||||
** Order is from low-order byte of buffer[0] to high-order byte
|
||||
** of buffer[3].
|
||||
** Each byte is printed with high-order hexadecimal digit first.
|
||||
*/
|
||||
extern void MD4Print __P((MD4_CTX *));
|
||||
|
||||
/* MD4Final(buf, MD)
|
||||
** Returns message digest from MD and terminates the message
|
||||
** digest computation.
|
||||
*/
|
||||
extern void MD4Final __P((unsigned char *, MD4_CTX *));
|
||||
|
||||
/*
|
||||
** End of md4.h
|
||||
****************************(cut)***********************************/
|
@ -107,8 +107,14 @@
|
||||
#if EAP_SUPPORT
|
||||
#include "eap.h"
|
||||
#endif /* EAP_SUPPORT */
|
||||
#include "ccp.h"
|
||||
#include "ecp.h"
|
||||
#include "pathnames.h"
|
||||
|
||||
#if CBCP_SUPPORT
|
||||
#include "cbcp.h"
|
||||
#endif
|
||||
|
||||
#ifdef AT_CHANGE
|
||||
#include "atcp.h"
|
||||
#endif
|
||||
@ -161,6 +167,7 @@ int fd_ppp = -1; /* fd for talking PPP */
|
||||
int phase; /* where the link is at */
|
||||
int kill_link;
|
||||
int asked_to_quit;
|
||||
int open_ccp_flag;
|
||||
int listen_time;
|
||||
int got_sigusr2;
|
||||
int got_sigterm;
|
||||
@ -227,6 +234,7 @@ static void hup __P((int));
|
||||
static void term __P((int));
|
||||
static void chld __P((int));
|
||||
static void toggle_debug __P((int));
|
||||
static void open_ccp __P((int));
|
||||
static void bad_signal __P((int));
|
||||
static void holdoff_end __P((void *));
|
||||
static void forget_child __P((int pid, int status));
|
||||
@ -265,6 +273,8 @@ struct protent *protocols[] = {
|
||||
#ifdef INET6
|
||||
&ipv6cp_protent,
|
||||
#endif
|
||||
&ccp_protent,
|
||||
&ecp_protent,
|
||||
#ifdef AT_CHANGE
|
||||
&atcp_protent,
|
||||
#endif
|
||||
@ -507,6 +517,12 @@ int ppp_oldmain() {
|
||||
if (phase == PHASE_MASTER)
|
||||
mp_bundle_terminated();
|
||||
}
|
||||
if (open_ccp_flag) {
|
||||
if (phase == PHASE_NETWORK || phase == PHASE_RUNNING) {
|
||||
ccp_fsm[0].flags = OPT_RESTART; /* clears OPT_SILENT */
|
||||
(*ccp_protent.open)(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* restore FSMs to original state */
|
||||
lcp_close(0, "");
|
||||
@ -562,7 +578,7 @@ handle_events()
|
||||
{
|
||||
struct timeval timo;
|
||||
|
||||
kill_link = 0;
|
||||
kill_link = open_ccp_flag = 0;
|
||||
if (sigsetjmp(sigjmp, 1) == 0) {
|
||||
sigprocmask(SIG_BLOCK, &signals_handled, NULL);
|
||||
if (got_sighup || got_sigterm || got_sigusr2 || got_sigchld) {
|
||||
@ -594,6 +610,10 @@ handle_events()
|
||||
got_sigchld = 0;
|
||||
reap_kids(); /* Don't leave dead kids lying around */
|
||||
}
|
||||
if (got_sigusr2) {
|
||||
open_ccp_flag = 1;
|
||||
got_sigusr2 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -630,6 +650,7 @@ setup_signals()
|
||||
SIGNAL(SIGCHLD, chld);
|
||||
|
||||
SIGNAL(SIGUSR1, toggle_debug); /* Toggle debug flag */
|
||||
SIGNAL(SIGUSR2, open_ccp); /* Reopen CCP */
|
||||
|
||||
/*
|
||||
* Install a handler for other signals which would otherwise
|
||||
@ -1438,6 +1459,23 @@ toggle_debug(sig)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* open_ccp - Catch SIGUSR2 signal.
|
||||
*
|
||||
* Try to (re)negotiate compression.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
open_ccp(sig)
|
||||
int sig;
|
||||
{
|
||||
got_sigusr2 = 1;
|
||||
if (waiting)
|
||||
siglongjmp(sigjmp, 1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* bad_signal - We've caught a fatal signal. Clean up state and exit.
|
||||
*/
|
||||
|
146
src/netif/ppp/pppcrypt.c
Normal file
146
src/netif/ppp/pppcrypt.c
Normal file
@ -0,0 +1,146 @@
|
||||
/*
|
||||
* pppcrypt.c - PPP/DES linkage for MS-CHAP and EAP SRP-SHA1
|
||||
*
|
||||
* Extracted from chap_ms.c by James Carlson.
|
||||
*
|
||||
* Copyright (c) 1995 Eric Rosenquist. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. The name(s) of the authors of this software must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission.
|
||||
*
|
||||
* THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
|
||||
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "lwip/opt.h"
|
||||
|
||||
#include "pppd.h"
|
||||
#include "pppcrypt.h"
|
||||
#include "des.h"
|
||||
|
||||
static u_char
|
||||
Get7Bits(input, startBit)
|
||||
u_char *input;
|
||||
int startBit;
|
||||
{
|
||||
unsigned int word;
|
||||
|
||||
word = (unsigned)input[startBit / 8] << 8;
|
||||
word |= (unsigned)input[startBit / 8 + 1];
|
||||
|
||||
word >>= 15 - (startBit % 8 + 7);
|
||||
|
||||
return word & 0xFE;
|
||||
}
|
||||
|
||||
static void
|
||||
MakeKey(key, des_key)
|
||||
u_char *key; /* IN 56 bit DES key missing parity bits */
|
||||
u_char *des_key; /* OUT 64 bit DES key with parity bits added */
|
||||
{
|
||||
des_key[0] = Get7Bits(key, 0);
|
||||
des_key[1] = Get7Bits(key, 7);
|
||||
des_key[2] = Get7Bits(key, 14);
|
||||
des_key[3] = Get7Bits(key, 21);
|
||||
des_key[4] = Get7Bits(key, 28);
|
||||
des_key[5] = Get7Bits(key, 35);
|
||||
des_key[6] = Get7Bits(key, 42);
|
||||
des_key[7] = Get7Bits(key, 49);
|
||||
}
|
||||
|
||||
/*
|
||||
* in == 8-byte string (expanded version of the 56-bit key)
|
||||
* out == 64-byte string where each byte is either 1 or 0
|
||||
* Note that the low-order "bit" is always ignored by by setkey()
|
||||
*/
|
||||
static void
|
||||
Expand(in, out)
|
||||
u_char *in;
|
||||
u_char *out;
|
||||
{
|
||||
int j, c;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 64; in++){
|
||||
c = *in;
|
||||
for (j = 7; j >= 0; j--)
|
||||
*out++ = (c >> j) & 01;
|
||||
i += 8;
|
||||
}
|
||||
}
|
||||
|
||||
/* The inverse of Expand
|
||||
*/
|
||||
static void
|
||||
Collapse(in, out)
|
||||
u_char *in;
|
||||
u_char *out;
|
||||
{
|
||||
int j;
|
||||
int i;
|
||||
unsigned int c;
|
||||
|
||||
for (i = 0; i < 64; i += 8, out++) {
|
||||
c = 0;
|
||||
for (j = 7; j >= 0; j--, in++)
|
||||
c |= *in << j;
|
||||
*out = c & 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
DesSetkey(key)
|
||||
u_char *key;
|
||||
{
|
||||
u_char des_key[8];
|
||||
u_char crypt_key[66];
|
||||
|
||||
MakeKey(key, des_key);
|
||||
Expand(des_key, crypt_key);
|
||||
setkey((const char *)crypt_key);
|
||||
return (1);
|
||||
}
|
||||
|
||||
bool
|
||||
DesEncrypt(clear, cipher)
|
||||
u_char *clear; /* IN 8 octets */
|
||||
u_char *cipher; /* OUT 8 octets */
|
||||
{
|
||||
u_char des_input[66];
|
||||
|
||||
Expand(clear, des_input);
|
||||
encrypt((char *)des_input, 0);
|
||||
Collapse(des_input, cipher);
|
||||
return (1);
|
||||
}
|
||||
|
||||
bool
|
||||
DesDecrypt(cipher, clear)
|
||||
u_char *cipher; /* IN 8 octets */
|
||||
u_char *clear; /* OUT 8 octets */
|
||||
{
|
||||
u_char des_input[66];
|
||||
|
||||
Expand(cipher, des_input);
|
||||
encrypt((char *)des_input, 1);
|
||||
Collapse(des_input, clear);
|
||||
return (1);
|
||||
}
|
40
src/netif/ppp/pppcrypt.h
Normal file
40
src/netif/ppp/pppcrypt.h
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* pppcrypt.c - PPP/DES linkage for MS-CHAP and EAP SRP-SHA1
|
||||
*
|
||||
* Extracted from chap_ms.c by James Carlson.
|
||||
*
|
||||
* Copyright (c) 1995 Eric Rosenquist. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. The name(s) of the authors of this software must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission.
|
||||
*
|
||||
* THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
|
||||
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef PPPCRYPT_H
|
||||
#define PPPCRYPT_H
|
||||
|
||||
extern bool DesSetkey __P((u_char *));
|
||||
extern bool DesEncrypt __P((u_char *, u_char *));
|
||||
extern bool DesDecrypt __P((u_char *, u_char *));
|
||||
|
||||
#endif /* PPPCRYPT_H */
|
@ -529,6 +529,7 @@ void link_down __P((int)); /* the LCP layer has left the Opened state */
|
||||
void upper_layers_down __P((int));/* take all NCPs down */
|
||||
void link_established __P((int)); /* the link is up; authenticate now */
|
||||
void start_networks __P((int)); /* start all the network control protos */
|
||||
void continue_networks __P((int)); /* start network [ip, etc] control protos */
|
||||
void np_up __P((int, int)); /* a network protocol has come up */
|
||||
void np_down __P((int, int)); /* a network protocol has gone down */
|
||||
void np_finished __P((int, int)); /* a network protocol no longer needs link */
|
||||
|
@ -436,10 +436,14 @@ void
|
||||
pppSetAuth(enum pppAuthType authType, const char *user, const char *passwd)
|
||||
{
|
||||
ppp_settings.refuse_pap = 1;
|
||||
ppp_settings.refuse_chap = 0;
|
||||
ppp_settings.refuse_chap = 1;
|
||||
ppp_settings.refuse_mschap = 1;
|
||||
ppp_settings.refuse_mschap_v2 = 0;
|
||||
#if EAP_SUPPORT
|
||||
ppp_settings.refuse_pap = 1;
|
||||
ppp_settings.refuse_chap = 1;
|
||||
ppp_settings.refuse_mschap = 1;
|
||||
ppp_settings.refuse_mschap_v2 = 1;
|
||||
ppp_settings.refuse_eap = 0;
|
||||
#endif /* EAP_SUPPORT */
|
||||
|
||||
|
@ -46,6 +46,8 @@ struct ppp_settings {
|
||||
u_int explicit_remote : 1; /* remote_name specified with remotename opt */
|
||||
u_int refuse_pap : 1; /* Don't wanna auth. ourselves with PAP */
|
||||
u_int refuse_chap : 1; /* Don't wanna auth. ourselves with CHAP */
|
||||
u_int refuse_mschap : 1; /* Don't wanna auth. ourselves with MS-CHAP */
|
||||
u_int refuse_mschap_v2 : 1; /* Don't wanna auth. ourselves with MS-CHAPv2 */
|
||||
#if EAP_SUPPORT
|
||||
u_int refuse_eap : 1; /* Don't wanna auth. ourselves with EAP */
|
||||
#endif /* EAP_SUPPORT */
|
||||
|
172
src/netif/ppp/sha1.c
Normal file
172
src/netif/ppp/sha1.c
Normal file
@ -0,0 +1,172 @@
|
||||
/*
|
||||
* ftp://ftp.funet.fi/pub/crypt/hash/sha/sha1.c
|
||||
*
|
||||
* SHA-1 in C
|
||||
* By Steve Reid <steve@edmweb.com>
|
||||
* 100% Public Domain
|
||||
*
|
||||
* Test Vectors (from FIPS PUB 180-1)
|
||||
* "abc"
|
||||
* A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
|
||||
* "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
|
||||
* 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
|
||||
* A million repetitions of "a"
|
||||
* 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
|
||||
*/
|
||||
|
||||
#include "lwip/opt.h"
|
||||
|
||||
/* #define SHA1HANDSOFF * Copies data before messing with it. */
|
||||
|
||||
#include <string.h>
|
||||
#include <netinet/in.h> /* htonl() */
|
||||
#include <net/ppp_defs.h>
|
||||
#include "sha1.h"
|
||||
|
||||
static void
|
||||
SHA1_Transform(u_int32_t[5], const unsigned char[64]);
|
||||
|
||||
#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
|
||||
|
||||
/* blk0() and blk() perform the initial expand. */
|
||||
/* I got the idea of expanding during the round function from SSLeay */
|
||||
#define blk0(i) (block->l[i] = htonl(block->l[i]))
|
||||
#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
|
||||
^block->l[(i+2)&15]^block->l[i&15],1))
|
||||
|
||||
/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
|
||||
#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
|
||||
#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
|
||||
#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
|
||||
#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
|
||||
#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
|
||||
|
||||
|
||||
/* Hash a single 512-bit block. This is the core of the algorithm. */
|
||||
|
||||
static void
|
||||
SHA1_Transform(u_int32_t state[5], const unsigned char buffer[64])
|
||||
{
|
||||
u_int32_t a, b, c, d, e;
|
||||
typedef union {
|
||||
unsigned char c[64];
|
||||
u_int32_t l[16];
|
||||
} CHAR64LONG16;
|
||||
CHAR64LONG16 *block;
|
||||
|
||||
#ifdef SHA1HANDSOFF
|
||||
static unsigned char workspace[64];
|
||||
block = (CHAR64LONG16 *) workspace;
|
||||
memcpy(block, buffer, 64);
|
||||
#else
|
||||
block = (CHAR64LONG16 *) buffer;
|
||||
#endif
|
||||
/* Copy context->state[] to working vars */
|
||||
a = state[0];
|
||||
b = state[1];
|
||||
c = state[2];
|
||||
d = state[3];
|
||||
e = state[4];
|
||||
/* 4 rounds of 20 operations each. Loop unrolled. */
|
||||
R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
|
||||
R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
|
||||
R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
|
||||
R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
|
||||
R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
|
||||
R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
|
||||
R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
|
||||
R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
|
||||
R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
|
||||
R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
|
||||
R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
|
||||
R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
|
||||
R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
|
||||
R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
|
||||
R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
|
||||
R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
|
||||
R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
|
||||
R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
|
||||
R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
|
||||
R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
|
||||
/* Add the working vars back into context.state[] */
|
||||
state[0] += a;
|
||||
state[1] += b;
|
||||
state[2] += c;
|
||||
state[3] += d;
|
||||
state[4] += e;
|
||||
/* Wipe variables */
|
||||
a = b = c = d = e = 0;
|
||||
}
|
||||
|
||||
|
||||
/* SHA1Init - Initialize new context */
|
||||
|
||||
void
|
||||
SHA1_Init(SHA1_CTX *context)
|
||||
{
|
||||
/* SHA1 initialization constants */
|
||||
context->state[0] = 0x67452301;
|
||||
context->state[1] = 0xEFCDAB89;
|
||||
context->state[2] = 0x98BADCFE;
|
||||
context->state[3] = 0x10325476;
|
||||
context->state[4] = 0xC3D2E1F0;
|
||||
context->count[0] = context->count[1] = 0;
|
||||
}
|
||||
|
||||
|
||||
/* Run your data through this. */
|
||||
|
||||
void
|
||||
SHA1_Update(SHA1_CTX *context, const unsigned char *data, unsigned int len)
|
||||
{
|
||||
unsigned int i, j;
|
||||
|
||||
j = (context->count[0] >> 3) & 63;
|
||||
if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++;
|
||||
context->count[1] += (len >> 29);
|
||||
i = 64 - j;
|
||||
while (len >= i) {
|
||||
memcpy(&context->buffer[j], data, i);
|
||||
SHA1_Transform(context->state, context->buffer);
|
||||
data += i;
|
||||
len -= i;
|
||||
i = 64;
|
||||
j = 0;
|
||||
}
|
||||
|
||||
memcpy(&context->buffer[j], data, len);
|
||||
}
|
||||
|
||||
|
||||
/* Add padding and return the message digest. */
|
||||
|
||||
void
|
||||
SHA1_Final(unsigned char digest[20], SHA1_CTX *context)
|
||||
{
|
||||
u_int32_t i, j;
|
||||
unsigned char finalcount[8];
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
|
||||
>> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
|
||||
}
|
||||
SHA1_Update(context, (unsigned char *) "\200", 1);
|
||||
while ((context->count[0] & 504) != 448) {
|
||||
SHA1_Update(context, (unsigned char *) "\0", 1);
|
||||
}
|
||||
SHA1_Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
|
||||
for (i = 0; i < 20; i++) {
|
||||
digest[i] = (unsigned char)
|
||||
((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
|
||||
}
|
||||
/* Wipe variables */
|
||||
i = j = 0;
|
||||
memset(context->buffer, 0, 64);
|
||||
memset(context->state, 0, 20);
|
||||
memset(context->count, 0, 8);
|
||||
memset(&finalcount, 0, 8);
|
||||
#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite it's own static vars */
|
||||
SHA1Transform(context->state, context->buffer);
|
||||
#endif
|
||||
}
|
||||
|
31
src/netif/ppp/sha1.h
Normal file
31
src/netif/ppp/sha1.h
Normal file
@ -0,0 +1,31 @@
|
||||
/* sha1.h */
|
||||
|
||||
/* If OpenSSL is in use, then use that version of SHA-1 */
|
||||
#ifdef OPENSSL
|
||||
#include <t_sha.h>
|
||||
#define __SHA1_INCLUDE_
|
||||
#endif
|
||||
|
||||
#ifndef __SHA1_INCLUDE_
|
||||
|
||||
#ifndef SHA1_SIGNATURE_SIZE
|
||||
#ifdef SHA_DIGESTSIZE
|
||||
#define SHA1_SIGNATURE_SIZE SHA_DIGESTSIZE
|
||||
#else
|
||||
#define SHA1_SIGNATURE_SIZE 20
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
u_int32_t state[5];
|
||||
u_int32_t count[2];
|
||||
unsigned char buffer[64];
|
||||
} SHA1_CTX;
|
||||
|
||||
extern void SHA1_Init(SHA1_CTX *);
|
||||
extern void SHA1_Update(SHA1_CTX *, const unsigned char *, unsigned int);
|
||||
extern void SHA1_Final(unsigned char[SHA1_SIGNATURE_SIZE], SHA1_CTX *);
|
||||
|
||||
#define __SHA1_INCLUDE_
|
||||
#endif /* __SHA1_INCLUDE_ */
|
||||
|
Loading…
x
Reference in New Issue
Block a user