📄 auth.c
字号:
//--------------------------------------------------------------------------
// Ip Stack
//--------------------------------------------------------------------------
// AUTH.C
//
// Authentication functions for PPP/LCP
//
// Author: Michael A. Denio
// Copyright 2000 by Texas Instruments Inc.
//-------------------------------------------------------------------------
#include <stkmain.h>
#include <netmain.h>
#include "ppp.h"
#include "md5.h"
#ifdef _INCLUDE_PPP_CODE
#define AUTH_TIMER_TIMEOUT 8
#define AUTH_TIMER_CFGRETRY 3
// PAP Codes
#define PAPCODE_REQ 1
#define PAPCODE_ACK 2
#define PAPCODE_NAK 3
// CHAP Codes
#define CHAPCODE_CHALLENGE 1
#define CHAPCODE_RESPONSE 2
#define CHAPCODE_SUCCESS 3
#define CHAPCODE_FAILURE 4
static uint authGetPassword( PPP_SESSION *p );
static void papSendCfg( PPP_SESSION *p );
static void chapSendMsg( PPP_SESSION *p, UINT8 Message, UINT8 Id );
//--------------------------------------------------------------------
// authInit()
//
// Initialize AUTH and set it to CLOSED state
//--------------------------------------------------------------------
void authInit( PPP_SESSION *p )
{
p->auth.State = PROT_STATE_CLOSED;
// Set options
if( p->Flags & PPPFLG_OPT_AUTH_PAP )
p->auth.Protocol = PPPPROT_PAP;
else if( p->Flags & PPPFLG_OPT_AUTH_CHAP )
p->auth.Protocol = PPPPROT_CHAP;
else
p->auth.Protocol = 0;
}
//--------------------------------------------------------------------
// authStart()
//
// Start AUTH layer
//--------------------------------------------------------------------
void authStart( PPP_SESSION *p )
{
// Set our new state
p->auth.State = PROT_STATE_OPEN;
// Set some defaults
p->auth.LastId = 0; // Default Id
// If PAP, send CFG request
if( p->auth.Protocol == PPPPROT_PAP && p->Flags & PPPFLG_CLIENT )
{
// Set our new state
p->auth.Count = 5;
papSendCfg( p );
}
// Else if CHAP server, send challenge
else if( p->auth.Protocol == PPPPROT_CHAP && p->Flags & PPPFLG_SERVER )
{
// Set our new state
p->auth.Count = 5;
chapSendMsg( p, CHAPCODE_CHALLENGE, ++p->auth.LastId );
}
// Else set an idle timeout
else
{
// Set a timeout for the peer
p->auth.Timer = AUTH_TIMER_TIMEOUT;
p->auth.Count = 0;
}
}
//--------------------------------------------------------------------
// authTimer()
//
// Called every second for AUTH timeout
//--------------------------------------------------------------------
void authTimer( PPP_SESSION *p )
{
// What we do depends on our state
if( p->auth.Timer && !--p->auth.Timer )
switch( p->auth.State )
{
case PROT_STATE_OPEN:
// See if we need a CFG message retry
if( p->auth.Count )
{
p->auth.Count--;
if( p->auth.Protocol == PPPPROT_PAP )
papSendCfg( p );
else if( p->auth.Protocol == PPPPROT_CHAP )
{
// Resend challenge or response
// If we're a server, we must be resending the challenge
if( p->Flags & PPPFLG_SERVER )
chapSendMsg( p, CHAPCODE_CHALLENGE, ++p->auth.LastId );
// Else resend response
else
chapSendMsg( p, CHAPCODE_RESPONSE, p->auth.LastId );
}
}
else
{
p->auth.State = PROT_STATE_STOPPED;
pppEvent( (HANDLE)p, PPP_EVENT_AUTH_STOPPED );
}
break;
}
}
//--------------------------------------------------------------------
// authGetPassword()
//
// Gets the password for the supplied UserId
//--------------------------------------------------------------------
static uint authGetPassword( PPP_SESSION *p )
{
CI_ACCT CA;
uint index;
uint retval = 0;
int rc;
llExit();
index = 1;
for(;;)
{
rc = CfgGetImmediate( 0, CFGTAG_ACCT, CFGITEM_ACCT_PPP,
index, sizeof(CA), (UINT8 *)&CA );
if( !rc )
break;
if( !strcmp( CA.Username, p->UserId ) &&
(CA.Flags&p->Flags&PPPFLG_CHMASK) )
{
strcpy( p->Password, CA.Password );
retval = 1;
break;
}
index++;
}
llEnter();
return( retval );
}
//--------------------------------------------------------------------
// papSendCfg()
//
// Send a AUTH Configuration Request
//--------------------------------------------------------------------
static void papSendCfg( PPP_SESSION *p )
{
HANDLE hPkt,hFrag;
uint Offset;
UINT8 *pb;
LCPHDR *pHdr;
UINT16 Len,wTmp;
UINT8 *pTagData;
// Create the packet (use size of 100 for now)
if( !(hPkt = IFCreatePacket( 100, 0, 0 )) )
return;
// Get the frag
hFrag = PktGetFrag( hPkt );
// Get a pointer to the new header
pb = FragGetBufParams( hFrag, 0, 0, 0 );
Offset = PktGetSizeLLC( hPkt );
pHdr = (LCPHDR *)(pb + Offset);
// Reset the timeout
p->auth.Timer = AUTH_TIMER_CFGRETRY;
// Bump the Id
p->auth.LastId++;
//
// RIGHT NOW, PAP ONLY
//
// Build the CFG packet
pHdr->Code = PAPCODE_REQ;
pHdr->Id = p->auth.LastId;
// Add options
pTagData = pHdr->TagData;
Len = SIZE_LCPHDR;
// User Id
wTmp = strlen( p->UserId );
*pTagData++ = (UINT8)wTmp;
mmCopy( pTagData, p->UserId, wTmp );
pTagData += wTmp;
Len += wTmp + 1;
// Password
wTmp = strlen( p->Password );
*pTagData++ = (UINT8)wTmp;
mmCopy( pTagData, p->Password, wTmp );
pTagData += wTmp;
Len += wTmp + 1;
pHdr->Length = HNC16(Len);
// Send the packet
FragSetBufParams( hFrag, Len, Offset );
p->SICtrl(p->hSI, SI_MSG_SENDPACKET, PPPPROT_PAP, hPkt );
}
//--------------------------------------------------------------------
// papInput()
//
// Packet input function for PAP
//--------------------------------------------------------------------
void papInput( PPP_SESSION *p, HANDLE hPkt )
{
LCPHDR *pHdr;
HANDLE hFrag;
UINT8 *pb;
uint Size,Offset;
UINT16 Len;
UINT8 *pTagData;
UINT8 c;
char Password[PPPNAMELEN];
// If we're anything but open, discard the packet
if( p->auth.State != PROT_STATE_OPEN )
goto PAPExit;
// We know we have a Frag...
hFrag = PktGetFrag( hPkt );
// Get the buffer parameters
pb = FragGetBufParams( hFrag, 0, &Size, &Offset );
pb += Offset;
// Get the LCPHDR
pHdr = (LCPHDR *)pb;
// Get packet length
Len = HNC16( pHdr->Length );
// Verify that we have the entire packet
if( Len > (UINT16)Size )
goto PAPExit;
switch( pHdr->Code )
{
case PAPCODE_REQ:
//---------------------
// Authentication-Request
//---------------------
if( !(p->Flags & PPPFLG_SERVER) )
goto AUTH_REJECT;
pTagData = pHdr->TagData;
// Get UserId and write into instance structure
c = *pTagData++;
if( c >= PPPNAMELEN )
goto AUTH_REJECT;
mmCopy( p->UserId, pTagData, c );
p->UserId[c] = 0;
pTagData += c;
// Get Password and write into temp string
c = *pTagData++;
if( c >= PPPNAMELEN )
goto AUTH_REJECT;
mmCopy( Password, pTagData, c );
Password[c] = 0;
pTagData += c;
// The the real password in tht user structure and compare to supplied
if( authGetPassword(p) && !strcmp( Password, p->Password ) )
{
// Ack this authentication
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -