Finished authenticator support.

libkernelppp.a should be feature-complete now. As it is completely untested we could call it _very_ early alpha stage.
The next task will be to add an interface module for our netstack. Some ioctls will be handled by PPPInterface, so libkernelppp.a will be modified in the next few days/weeks to support these ioctls.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@4767 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Waldemar Kornewald 2003-09-19 17:53:09 +00:00
parent f3d6a89559
commit 06c8940fcf
21 changed files with 497 additions and 100 deletions

View File

@ -20,12 +20,11 @@ typedef uint32 interface_id;
// module key types (used when loading a module)
enum ppp_module_key_type {
PPP_UNDEFINED_KEY_TYPE = -1,
PPP_LOAD_MODULE_TYPE = 0,
PPP_DEVICE_TYPE,
PPP_PROTOCOL_TYPE,
PPP_AUTHENTICATOR_TYPE,
PPP_PEER_AUTHENTICATOR_TYPE,
PPP_MULTILINK_TYPE
PPP_LOAD_MODULE_KEY_TYPE = 0,
PPP_DEVICE_KEY_TYPE,
PPP_PROTOCOL_KEY_TYPE,
PPP_AUTHENTICATOR_KEY_TYPE,
PPP_MULTILINK_KEY_TYPE
};
// PPP events as defined in RFC 1661 (with one exception: PPP_UP_FAILED_EVENT)

View File

@ -80,11 +80,10 @@ class PPPDevice {
uint32 fMTU;
// always hold this value up-to-date!
bool fIsUp;
status_t fInitStatus;
private:
char fName[PPP_HANDLER_NAME_LENGTH_LIMIT + 1];
char *fName;
PPPInterface& fInterface;
driver_parameter *fSettings;
};

View File

@ -49,6 +49,9 @@ class PPPEncapsulator {
// negative values and values > 0xFF are ignored
int32 Flags() const
{ return fFlags; }
ppp_side Side() const
{ return fSide; }
// which side this encapsulator works for
void SetEnabled(bool enabled = true);
bool IsEnabled() const
@ -101,11 +104,11 @@ class PPPEncapsulator {
protected:
uint32 fOverhead;
ppp_side fSide;
status_t fInitStatus;
private:
char fName[PPP_HANDLER_NAME_LENGTH_LIMIT + 1];
char *fName;
ppp_phase fPhase;
ppp_encapsulation_level fLevel;
uint16 fProtocol;

View File

@ -52,7 +52,7 @@ class PPPLCPExtension {
status_t fInitStatus;
private:
char fName[PPP_HANDLER_NAME_LENGTH_LIMIT + 1];
char *fName;
PPPInterface& fInterface;
driver_parameter *fSettings;
uint8 fCode;

View File

@ -69,7 +69,7 @@ class PPPOptionHandler {
status_t fInitStatus;
private:
char fName[PPP_HANDLER_NAME_LENGTH_LIMIT + 1];
char *fName;
uint8 fType;
PPPInterface& fInterface;
driver_parameter *fSettings;

View File

@ -8,11 +8,10 @@
#ifndef _K_PPP_PROTOCOL__H
#define _K_PPP_PROTOCOL__H
#include <driver_settings.h>
#include <KPPPDefs.h>
class PPPInterface;
class PPPOptionHandler;
class PPPProtocol {
@ -20,7 +19,7 @@ class PPPProtocol {
PPPProtocol(const char *name, ppp_phase phase, uint16 protocol,
int32 addressFamily, PPPInterface& interface,
driver_parameter *settings, int32 flags = PPP_NO_FLAGS,
ppp_authenticator_type authenticatorType = PPP_NO_AUTHENTICATOR);
const char *type = NULL, PPPOptionHandler *optionHandler = NULL);
virtual ~PPPProtocol();
virtual status_t InitCheck() const;
@ -43,9 +42,15 @@ class PPPProtocol {
// negative values and values > 0xFF are ignored
int32 Flags() const
{ return fFlags; }
ppp_side Side() const
{ return fSide; }
// which side this protocol works for
ppp_authenticator_type AuthenticatorType() const
{ return fAuthenticatorType; }
// extensions
const char *Type() const
{ return fType; }
PPPOptionHandler *OptionHandler() const
{ return fOptionHandler; }
void SetEnabled(bool enabled = true);
bool IsEnabled() const
@ -88,17 +93,19 @@ class PPPProtocol {
// report up/down events
protected:
ppp_side fSide;
status_t fInitStatus;
private:
char fName[PPP_HANDLER_NAME_LENGTH_LIMIT + 1];
char *fName;
ppp_phase fPhase;
uint16 fProtocol;
int32 fAddressFamily;
PPPInterface& fInterface;
driver_parameter *fSettings;
int32 fFlags;
ppp_authenticator_type fAuthenticatorType;
char *fType;
PPPOptionHandler *fOptionHandler;
bool fEnabled;
bool fUpRequested;

View File

@ -42,6 +42,7 @@ ForEachItem(_LIST& list, _FUNCTION function)
function(list.ItemAt(index));
}
// These are very simple send/receive_data functions with a timeout
// and there is a race condition beween has_data() and send/receive_data().
// Timeouts in ms.

View File

@ -12,6 +12,10 @@
#include <PPPDefs.h>
// various constants
#define PPP_HANDLER_NAME_LENGTH_LIMIT 63
// if the name is longer than this value it will be truncated to fit the structure
// starting values and other values for control ops
#define PPP_RESERVE_OPS_COUNT 0xFFFF
#define PPP_OPS_START B_DEVICE_OP_CODES_END + 1
@ -132,6 +136,7 @@ typedef struct ppp_handler_info {
ppp_phase phase;
int32 addressFamily, flags;
ppp_side side;
uint16 protocol;
bool isEnabled;
@ -146,7 +151,7 @@ typedef struct ppp_handler_info {
// PPP_TERMINATION_PHASE - IsGoingDown() == true
// only protocol
ppp_authenticator_type authenticatorType;
char type[PPP_HANDLER_NAME_LENGTH_LIMIT + 1];
// only encapsulator
ppp_encapsulation_level level;

View File

@ -11,10 +11,6 @@
#include <SupportDefs.h>
// various constants
#define PPP_HANDLER_NAME_LENGTH_LIMIT 63
// if the name is longer than this value it will be truncated
// settings keys
#define PPP_DISONNECT_AFTER_IDLE_SINCE_KEY "DisonnectAfterIdleSince"
#define PPP_MODE_KEY "Mode"
@ -24,7 +20,6 @@
#define PPP_PROTOCOL_KEY "Protocol"
#define PPP_DEVICE_KEY "Device"
#define PPP_AUTHENTICATOR_KEY "Authenticator"
#define PPP_PEER_AUTHENTICATOR_KEY "Peer-Authenticator"
#define PPP_MULTILINK_KEY "Multilink-Protocol"
// settings values
@ -130,11 +125,12 @@ enum ppp_mode {
PPP_SERVER_MODE
};
// PPPProtocol serves as authenticator
enum ppp_authenticator_type {
PPP_NO_AUTHENTICATOR = 0,
PPP_LOCAL_AUTHENTICATOR,
PPP_PEER_AUTHENTICATOR
// which side the protocol/encapsulator works for
enum ppp_side {
PPP_NO_SIDE,
PPP_LOCAL_SIDE,
PPP_PEER_SIDE,
PPP_BOTH_SIDES
};
// authentication status

View File

@ -26,5 +26,6 @@ R5KernelStaticLibrary kernelppp :
# integrated modules
_KPPPMRUHandler.cpp
_KPPPAuthenticationHandler.cpp
_KPPPPFCHandler.cpp
;

View File

@ -20,11 +20,10 @@ PPPDevice::PPPDevice(const char *name, PPPInterface& interface,
fInterface(interface),
fSettings(settings)
{
if(name) {
strncpy(fName, name, PPP_HANDLER_NAME_LENGTH_LIMIT);
fName[PPP_HANDLER_NAME_LENGTH_LIMIT] = 0;
} else
strcpy(fName, "???");
if(name)
fName = strdup(name);
else
fName = strdup("Unknown");
fInitStatus = interface.SetDevice(this) ? B_OK : B_ERROR;
}
@ -32,6 +31,8 @@ PPPDevice::PPPDevice(const char *name, PPPInterface& interface,
PPPDevice::~PPPDevice()
{
free(fName);
Interface().SetDevice(NULL);
}
@ -53,7 +54,7 @@ PPPDevice::Control(uint32 op, void *data, size_t length)
ppp_device_info *info = (ppp_device_info*) data;
memset(info, 0, sizeof(ppp_device_info_t));
strcpy(info->name, Name());
strncpy(info->name, Name(), PPP_HANDLER_NAME_LENGTH_LIMIT);
info->settings = Settings();
info->MTU = MTU();
info->inputTransferRate = InputTransferRate();

View File

@ -7,6 +7,7 @@
#include <KPPPEncapsulator.h>
#include <KPPPUtils.h>
#include "settings_tools.h"
#include <PPPControl.h>
@ -28,11 +29,20 @@ PPPEncapsulator::PPPEncapsulator(const char *name, ppp_phase phase,
fUpRequested(true),
fConnectionStatus(PPP_DOWN_PHASE)
{
if(name) {
strncpy(fName, name, PPP_HANDLER_NAME_LENGTH_LIMIT);
fName[PPP_HANDLER_NAME_LENGTH_LIMIT] = 0;
} else
strcpy(fName, "???");
if(name)
fName = strdup(name);
else
fName = strdup("Unknown");
const char *sideString = get_parameter_value("side", settings);
if(sideString)
fSide = get_side_string_value(sideString, PPP_LOCAL_SIDE);
else {
if(interface.Mode() == PPP_CLIENT_MODE)
fSide = PPP_LOCAL_SIDE;
else
fSide = PPP_PEER_SIDE;
}
fInitStatus = interface.AddEncapsulator(this) ? B_OK : B_ERROR;
}
@ -40,6 +50,8 @@ PPPEncapsulator::PPPEncapsulator(const char *name, ppp_phase phase,
PPPEncapsulator::~PPPEncapsulator()
{
free(fName);
Interface().RemoveEncapsulator(this);
}
@ -74,11 +86,12 @@ PPPEncapsulator::Control(uint32 op, void *data, size_t length)
ppp_handler_info *info = (ppp_handler_info*) data;
memset(info, 0, sizeof(ppp_handler_info_t));
strcpy(info->name, Name());
strncpy(info->name, Name(), PPP_HANDLER_NAME_LENGTH_LIMIT);
info->settings = Settings();
info->phase = Phase();
info->addressFamily = AddressFamily();
info->flags = Flags();
info->side = Side();
info->protocol = Protocol();
info->isEnabled = IsEnabled();
info->isUpRequested = IsUpRequested();
@ -118,11 +131,9 @@ status_t
PPPEncapsulator::SendToNext(struct mbuf *packet, uint16 protocol) const
{
// Find the next possible handler for this packet.
// This handler should be:
// - enabled
// - allowed to send
// This handler should be enabled, up, and allowed to send
if(Next()) {
if(Next()->IsEnabled()
if(Next()->IsEnabled() && Next()->IsUp()
&& is_handler_allowed(*Next(), Interface().State(), Interface().Phase()))
return Next()->Send(packet, protocol);
else

View File

@ -33,6 +33,7 @@
// internal modules
#include "_KPPPMRUHandler.h"
#include "_KPPPAuthenticationHandler.h"
#include "_KPPPPFCHandler.h"
@ -87,6 +88,11 @@ PPPInterface::PPPInterface(uint32 ID, driver_settings *settings,
new _PPPMRUHandler(*this);
if(mruHandler->InitCheck() != B_OK)
delete mruHandler;
// authentication
_PPPAuthenticationHandler *authenticationHandler =
new _PPPAuthenticationHandler(*this);
if(authenticationHandler->InitCheck() != B_OK)
delete authenticationHandler;
// PFC
_PPPPFCHandler *pfcHandler =
new _PPPPFCHandler(fLocalPFCState, fPeerPFCState, *this);
@ -478,9 +484,7 @@ PPPInterface::AddProtocol(PPPProtocol *protocol)
LockerHelper locker(fLock);
if(Phase() != PPP_DOWN_PHASE
|| (protocol->AuthenticatorType() != PPP_NO_AUTHENTICATOR
&& ProtocolFor(protocol->Protocol())))
if(Phase() != PPP_DOWN_PHASE)
return false;
// a running connection may not change and there may only be
// one authenticator protocol for each protocol number
@ -1050,7 +1054,7 @@ PPPInterface::LoadModules(driver_settings *settings, int32 start, int32 count)
if(!strcasecmp(settings->parameters[index].name, PPP_MULTILINK_KEY)
&& settings->parameters[index].value_count > 0) {
if(!LoadModule(settings->parameters[index].values[0],
settings->parameters[index].parameters, PPP_MULTILINK_TYPE))
settings->parameters[index].parameters, PPP_MULTILINK_KEY_TYPE))
return false;
break;
}
@ -1072,15 +1076,13 @@ PPPInterface::LoadModules(driver_settings *settings, int32 start, int32 count)
name = settings->parameters[index].name;
if(!strcasecmp(name, PPP_LOAD_MODULE_KEY))
type = PPP_LOAD_MODULE_TYPE;
type = PPP_LOAD_MODULE_KEY_TYPE;
else if(!strcasecmp(name, PPP_DEVICE_KEY))
type = PPP_DEVICE_TYPE;
type = PPP_DEVICE_KEY_TYPE;
else if(!strcasecmp(name, PPP_PROTOCOL_KEY))
type = PPP_PROTOCOL_TYPE;
type = PPP_PROTOCOL_KEY_TYPE;
else if(!strcasecmp(name, PPP_AUTHENTICATOR_KEY))
type = PPP_AUTHENTICATOR_TYPE;
else if(!strcasecmp(name, PPP_PEER_AUTHENTICATOR_KEY))
type = PPP_PEER_AUTHENTICATOR_TYPE;
type = PPP_AUTHENTICATOR_KEY_TYPE;
if(type >= 0)
for(int32 value_id = 0; value_id < settings->parameters[index].value_count;

View File

@ -17,11 +17,10 @@ PPPLCPExtension::PPPLCPExtension(const char *name, uint8 code, PPPInterface& int
fCode(code),
fEnabled(true)
{
if(name) {
strncpy(fName, name, PPP_HANDLER_NAME_LENGTH_LIMIT);
fName[PPP_HANDLER_NAME_LENGTH_LIMIT] = 0;
} else
strcpy(fName, "???");
if(name)
fName = strdup(name);
else
fName = strdup("Unknown");
fInitStatus = interface.LCP().AddLCPExtension(this) ? B_OK : B_ERROR;
}
@ -29,6 +28,8 @@ PPPLCPExtension::PPPLCPExtension(const char *name, uint8 code, PPPInterface& int
PPPLCPExtension::~PPPLCPExtension()
{
free(fName);
Interface().LCP().RemoveLCPExtension(this);
}
@ -50,7 +51,7 @@ PPPLCPExtension::Control(uint32 op, void *data, size_t length)
ppp_simple_handler_info *info = (ppp_simple_handler_info*) data;
memset(info, 0, sizeof(ppp_simple_handler_info_t));
strcpy(info->name, Name());
strncpy(info->name, Name(), PPP_HANDLER_NAME_LENGTH_LIMIT);
info->settings = Settings();
info->isEnabled = IsEnabled();
} break;

View File

@ -17,11 +17,10 @@ PPPOptionHandler::PPPOptionHandler(const char *name, uint8 type,
fSettings(settings),
fEnabled(true)
{
if(name) {
strncpy(fName, name, PPP_HANDLER_NAME_LENGTH_LIMIT);
fName[PPP_HANDLER_NAME_LENGTH_LIMIT] = 0;
} else
strcpy(fName, "???");
if(name)
fName = strdup(name);
else
fName = strdup("Unknown");
fInitStatus = interface.LCP().AddOptionHandler(this) ? B_OK : B_ERROR;
}
@ -29,6 +28,8 @@ PPPOptionHandler::PPPOptionHandler(const char *name, uint8 type,
PPPOptionHandler::~PPPOptionHandler()
{
free(fName);
Interface().LCP().RemoveOptionHandler(this);
}
@ -50,7 +51,7 @@ PPPOptionHandler::Control(uint32 op, void *data, size_t length)
ppp_simple_handler_info *info = (ppp_simple_handler_info*) data;
memset(info, 0, sizeof(ppp_simple_handler_info_t));
strcpy(info->name, Name());
strncpy(info->name, Name(), PPP_HANDLER_NAME_LENGTH_LIMIT);
info->settings = Settings();
info->isEnabled = IsEnabled();
} break;

View File

@ -6,8 +6,10 @@
//---------------------------------------------------------------------
#include <KPPPInterface.h>
#include <KPPPOptionHandler.h>
#include <PPPControl.h>
#include "settings_tools.h"
#include <cstring>
@ -15,27 +17,37 @@
PPPProtocol::PPPProtocol(const char *name, ppp_phase phase, uint16 protocol,
int32 addressFamily, PPPInterface& interface,
driver_parameter *settings, int32 flags = PPP_NO_FLAGS,
ppp_authenticator_type authenticatorType = PPP_NO_AUTHENTICATOR)
const char *type = NULL, PPPOptionHandler *optionHandler = NULL)
: fPhase(phase),
fProtocol(protocol),
fAddressFamily(addressFamily),
fInterface(interface),
fSettings(settings),
fFlags(flags),
fAuthenticatorType(authenticatorType),
fOptionHandler(optionHandler),
fEnabled(true),
fUpRequested(true),
fConnectionStatus(PPP_DOWN_PHASE)
{
if(name) {
strncpy(fName, name, PPP_HANDLER_NAME_LENGTH_LIMIT);
fName[PPP_HANDLER_NAME_LENGTH_LIMIT] = 0;
} else
strcpy(fName, "???");
if(name)
fName = strdup(name);
else
fName = strdup("Unknown");
if(authenticatorType != PPP_NO_AUTHENTICATOR)
SetEnabled(false);
// only the active authenticator should be enabled
if(type)
fType = strdup(type);
else
fType = strdup("Unknown");
const char *sideString = get_parameter_value("side", settings);
if(sideString)
fSide = get_side_string_value(sideString, PPP_LOCAL_SIDE);
else {
if(interface.Mode() == PPP_CLIENT_MODE)
fSide = PPP_LOCAL_SIDE;
else
fSide = PPP_PEER_SIDE;
}
fInitStatus = interface.AddProtocol(this) ? B_OK : B_ERROR;
}
@ -43,6 +55,9 @@ PPPProtocol::PPPProtocol(const char *name, ppp_phase phase, uint16 protocol,
PPPProtocol::~PPPProtocol()
{
free(fName);
free(fType);
Interface().RemoveProtocol(this);
}
@ -77,16 +92,17 @@ PPPProtocol::Control(uint32 op, void *data, size_t length)
ppp_handler_info *info = (ppp_handler_info*) data;
memset(info, 0, sizeof(ppp_handler_info_t));
strcpy(info->name, Name());
strncpy(info->name, Name(), PPP_HANDLER_NAME_LENGTH_LIMIT);
info->settings = Settings();
info->phase = Phase();
info->addressFamily = AddressFamily();
info->flags = Flags();
info->side = Side();
info->protocol = Protocol();
info->isEnabled = IsEnabled();
info->isUpRequested = IsUpRequested();
info->connectionStatus = fConnectionStatus;
info->authenticatorType = AuthenticatorType();
strncpy(info->type, Type(), PPP_HANDLER_NAME_LENGTH_LIMIT);
} break;
case PPPC_SET_ENABLED:

View File

@ -1337,14 +1337,18 @@ PPPStateMachine::RCREvent(struct mbuf *packet)
handler = LCP().OptionHandlerFor(request.ItemAt(index)->type);
if(!handler || !handler->IsEnabled()) {
// unhandled items should be added to reject
// unhandled items should be added to the reject
reject.AddItem(request.ItemAt(index));
continue;
}
result = handler->ParseRequest(request, index, nak, reject);
if(result != B_OK) {
if(result == PPP_UNHANDLED) {
// unhandled items should be added to the reject
reject.AddItem(request.ItemAt(index));
continue;
} else if(result != B_OK) {
// the request contains a value that has been sent more than
// once or the value is corrupted
m_freem(packet);

View File

@ -0,0 +1,283 @@
//----------------------------------------------------------------------
// This software is part of the OpenBeOS distribution and is covered
// by the OpenBeOS license.
//
// Copyright (c) 2003 Waldemar Kornewald, Waldemar.Kornewald@web.de
//---------------------------------------------------------------------
#include "_KPPPAuthenticationHandler.h"
#include <KPPPConfigurePacket.h>
#include <KPPPDevice.h>
#include <netinet/in.h>
#define AUTHENTICATION_TYPE 0x3
#define AUTHENTICATOR_TYPE_STRING "Authenticator"
typedef struct authentication_item {
uint8 type;
uint8 length;
uint16 protocol;
} authentication_item;
_PPPAuthenticationHandler::_PPPAuthenticationHandler(PPPInterface& interface)
: PPPOptionHandler("Authentication Handler", AUTHENTICATION_TYPE, interface, NULL),
fLocalIndex(-1),
fPeerIndex(-1),
fSuggestedLocalIndex(-1),
fSuggestedPeerIndex(-1),
fPeerAuthenticatorRejected(false)
{
}
int32
_PPPAuthenticationHandler::NextAuthenticator(int32 start, ppp_side side)
{
// find the next authenticator for side, beginning at start
PPPProtocol *protocol;
for(int32 index = start; index < Interface().CountProtocols(); index++) {
protocol = Interface().ProtocolAt(index);
if(protocol && !strcasecmp(protocol->Type(), AUTHENTICATOR_TYPE_STRING)
&& protocol->OptionHandler()
&& protocol->Side() == side)
return index;
}
return -1;
}
status_t
_PPPAuthenticationHandler::AddToRequest(PPPConfigurePacket& request)
{
// AddToRequest(): Check if peer must authenticate itself and
// add an authentication request if needed. This request is added
// by the authenticator's OptionHandler.
int32 index;
PPPProtocol *protocol;
if(fPeerIndex != -1 && (protocol = Interface().ProtocolAt(fPeerIndex)))
protocol->SetEnabled(false);
if(fSuggestedPeerIndex != -1
&& (protocol = Interface().ProtocolAt(fSuggestedPeerIndex)))
protocol->SetEnabled(false);
if(fPeerAuthenticatorRejected) {
if(fSuggestedPeerIndex == -1) {
// This happens when the protocol is rejected, but no alternative
// protocol is supplied to us or the suggested protocol is not supported.
// We can use this chance to increase fPeerIndex to the next authenticator.
index = NextAuthenticator(fPeerIndex + 1, PPP_PEER_SIDE);
} else
index = fSuggestedPeerIndex;
fPeerAuthenticatorRejected = false;
} else {
if(fPeerIndex == -1) {
// there is no authenticator selected, so find one for us
index = NextAuthenticator(fPeerIndex + 1, PPP_PEER_SIDE);
} else
index = fPeerIndex;
}
// check if all authenticators were rejected or if no authentication needed
if(index == -1) {
if(fPeerIndex == -1)
return B_OK;
// no peer authentication needed
else
return B_ERROR;
// all authenticators were denied
}
protocol = Interface().ProtocolAt(index);
if(!protocol || !protocol->OptionHandler())
return B_ERROR;
fPeerIndex = index;
// this could omit some authenticators when we get a suggestion, but that is
// no problem because the suggested authenticator will be accepted (hopefully)
protocol->SetEnabled(true);
return protocol->OptionHandler()->AddToRequest(request);
// let protocol add its request
}
status_t
_PPPAuthenticationHandler::ParseNak(const PPPConfigurePacket& nak)
{
// The authenticator's OptionHandler is not notified.
authentication_item *item =
(authentication_item*) nak.ItemWithType(AUTHENTICATION_TYPE);
if(!item)
return B_OK;
// the request was not rejected
if(item->length < 4)
return B_ERROR;
PPPProtocol *protocol;
if(fSuggestedPeerIndex != -1
&& (protocol = Interface().ProtocolAt(fSuggestedPeerIndex))) {
protocol->SetEnabled(false);
// if no alternative protocol is supplied we will choose a new one in
// AddToRequest()
if(ntohs(item->protocol) == protocol->Protocol()) {
fSuggestedPeerIndex = -1;
return B_OK;
}
}
fPeerAuthenticatorRejected = true;
int32 index = 0;
if((protocol = Interface().ProtocolFor(ntohs(item->protocol), &index))
&& !strcasecmp(protocol->Type(), AUTHENTICATOR_TYPE_STRING)
&& protocol->OptionHandler())
fSuggestedPeerIndex = index;
else
fSuggestedPeerIndex = -1;
return B_OK;
}
status_t
_PPPAuthenticationHandler::ParseReject(const PPPConfigurePacket& reject)
{
// an authentication request must not be rejected!
if(reject.ItemWithType(AUTHENTICATION_TYPE))
return B_ERROR;
return B_OK;
}
status_t
_PPPAuthenticationHandler::ParseAck(const PPPConfigurePacket& ack)
{
authentication_item *item =
(authentication_item*) ack.ItemWithType(AUTHENTICATION_TYPE);
PPPProtocol *protocol = Interface().ProtocolAt(fPeerIndex);
if(fPeerIndex != -1 && !protocol)
return B_ERROR;
// could not find the protocol
if(!item) {
if(fPeerIndex != -1)
return B_ERROR;
// the ack does not contain our request
} else if(fPeerIndex == -1 || ntohs(item->protocol) != protocol->Protocol())
return B_ERROR;
// this item was never requested
return protocol->OptionHandler()->ParseAck(ack);
// this should enable the authenticator
}
status_t
_PPPAuthenticationHandler::ParseRequest(const PPPConfigurePacket& request,
int32 index, PPPConfigurePacket& nak, PPPConfigurePacket& reject)
{
PPPProtocol *protocol;
if(fLocalIndex != -1 && (protocol = Interface().ProtocolAt(fLocalIndex)))
protocol->SetEnabled(false);
authentication_item *item = (authentication_item*) request.ItemAt(index);
if(!item)
return B_OK;
// no authentication requested by peer
// try to find the requested protocol and select it by saving it in fLocalIndex
fLocalIndex = 0;
protocol = Interface().ProtocolFor(ntohs(item->protocol), &fLocalIndex);
if(protocol && !strcasecmp(protocol->Type(), AUTHENTICATOR_TYPE_STRING)
&& protocol->OptionHandler())
return protocol->OptionHandler()->ParseRequest(request, index, nak, reject);
// suggest another authentication protocol
int32 nextIndex = NextAuthenticator(fSuggestedLocalIndex + 1, PPP_LOCAL_SIDE);
if(nextIndex == -1) {
if(fSuggestedLocalIndex == -1) {
// reject the complete authentication option
reject.AddItem((ppp_configure_item*) item);
return B_OK;
} else
nextIndex = fSuggestedLocalIndex;
// try the old one again as it was not rejected until now
}
protocol = Interface().ProtocolAt(nextIndex);
if(!protocol)
return B_ERROR;
fSuggestedLocalIndex = nextIndex;
fLocalIndex = -1;
// no authenticator selected
// nak this authenticator and suggest an alternative
authentication_item suggestion;
suggestion.type = AUTHENTICATION_TYPE;
suggestion.length = 4;
suggestion.protocol = htons(protocol->Protocol());
return nak.AddItem((ppp_configure_item*) &suggestion) ? B_OK : B_ERROR;
}
status_t
_PPPAuthenticationHandler::SendingAck(const PPPConfigurePacket& ack)
{
// do not insist on authenticating our side of the link ;)
authentication_item *item =
(authentication_item*) ack.ItemWithType(AUTHENTICATION_TYPE);
if(!item)
return B_OK;
// no authentication needed
fSuggestedLocalIndex = -1;
if(fLocalIndex == -1)
return B_ERROR;
// no authenticator selected (our suggestions must be requested, too)
PPPProtocol *protocol = Interface().ProtocolAt(fLocalIndex);
if(!protocol)
return B_ERROR;
protocol->SetEnabled(true);
return protocol->OptionHandler()->SendingAck(ack);
// this should enable the authenticator
}
void
_PPPAuthenticationHandler::Reset()
{
PPPProtocol *protocol = NULL;
if(fLocalIndex != -1 && (protocol = Interface().ProtocolAt(fLocalIndex))) {
protocol->SetEnabled(false);
protocol->OptionHandler()->Reset();
}
if(fPeerIndex != -1 && (protocol = Interface().ProtocolAt(fPeerIndex))) {
protocol->SetEnabled(false);
protocol->OptionHandler()->Reset();
}
if(fSuggestedPeerIndex != -1
&& (protocol = Interface().ProtocolAt(fSuggestedPeerIndex))) {
protocol->SetEnabled(false);
protocol->OptionHandler()->Reset();
}
fLocalIndex = fPeerIndex = fSuggestedLocalIndex = fSuggestedPeerIndex = -1;
fPeerAuthenticatorRejected = false;
}

View File

@ -0,0 +1,37 @@
//----------------------------------------------------------------------
// This software is part of the OpenBeOS distribution and is covered
// by the OpenBeOS license.
//
// Copyright (c) 2003 Waldemar Kornewald, Waldemar.Kornewald@web.de
//---------------------------------------------------------------------
#ifndef __K_PPP_AUTHENTICATION_HANDLER__H
#define __K_PPP_AUTHENTICATION_HANDLER__H
#include <KPPPOptionHandler.h>
class _PPPAuthenticationHandler : public PPPOptionHandler {
public:
_PPPAuthenticationHandler(PPPInterface& interface);
int32 NextAuthenticator(int32 start, ppp_side side);
virtual status_t AddToRequest(PPPConfigurePacket& request);
virtual status_t ParseNak(const PPPConfigurePacket& nak);
virtual status_t ParseReject(const PPPConfigurePacket& reject);
virtual status_t ParseAck(const PPPConfigurePacket& ack);
virtual status_t ParseRequest(const PPPConfigurePacket& request,
int32 index, PPPConfigurePacket& nak, PPPConfigurePacket& reject);
virtual status_t SendingAck(const PPPConfigurePacket& ack);
virtual void Reset();
private:
int32 fLocalIndex, fPeerIndex, fSuggestedLocalIndex, fSuggestedPeerIndex;
bool fPeerAuthenticatorRejected;
};
#endif

View File

@ -5,6 +5,7 @@
// Copyright (c) 2003 Waldemar Kornewald, Waldemar.Kornewald@web.de
//---------------------------------------------------------------------
#include <KPPPDefs.h>
#include <driver_settings.h>
#include "settings_tools.h"
@ -17,7 +18,8 @@ static void copy_parameter(const driver_parameter *from, driver_parameter *to);
static void free_driver_parameter(driver_parameter *p);
driver_settings *dup_driver_settings(const driver_settings *dup)
driver_settings*
dup_driver_settings(const driver_settings *dup)
{
if(!dup)
return NULL; // we got a NULL pointer, so return nothing
@ -34,7 +36,9 @@ driver_settings *dup_driver_settings(const driver_settings *dup)
}
static void copy_parameter(const driver_parameter *from, driver_parameter *to)
static
void
copy_parameter(const driver_parameter *from, driver_parameter *to)
{
to->name = strdup(from->name);
to->value_count = from->value_count;
@ -53,7 +57,8 @@ static void copy_parameter(const driver_parameter *from, driver_parameter *to)
}
void free_driver_settings(driver_settings *settings)
void
free_driver_settings(driver_settings *settings)
{
for(int32 i=0; i < settings->parameter_count; i++)
free_driver_parameter(&settings->parameters[i]);
@ -63,7 +68,8 @@ void free_driver_settings(driver_settings *settings)
}
void free_driver_parameter(driver_parameter *p)
void
free_driver_parameter(driver_parameter *p)
{
free(p->name);
@ -79,25 +85,47 @@ void free_driver_parameter(driver_parameter *p)
}
bool get_string_value(const char *string, bool unknownValue)
ppp_side
get_side_string_value(const char *sideString, ppp_side unknownValue)
{
if(!sideString)
return unknownValue;
if(!strcasecmp(sideString, "local"))
return PPP_LOCAL_SIDE;
if(!strcasecmp(sideString, "peer"))
return PPP_PEER_SIDE;
if(!strcasecmp(sideString, "none")
|| !strcasecmp(sideString, "no"))
return PPP_NO_SIDE;
if(!strcasecmp(sideString, "both"))
return PPP_BOTH_SIDES;
// no correct value has been found => return default value
return unknownValue;
}
bool
get_string_value(const char *string, bool unknownValue)
{
if(!string)
return unknownValue;
if (!strcmp(string, "1")
|| !strcasecmp(string, "true")
|| !strcasecmp(string, "yes")
|| !strcasecmp(string, "on")
|| !strcasecmp(string, "enable")
|| !strcasecmp(string, "enabled"))
|| !strcasecmp(string, "true")
|| !strcasecmp(string, "yes")
|| !strcasecmp(string, "on")
|| !strcasecmp(string, "enable")
|| !strcasecmp(string, "enabled"))
return true;
if (!strcmp(string, "0")
|| !strcasecmp(string, "false")
|| !strcasecmp(string, "no")
|| !strcasecmp(string, "off")
|| !strcasecmp(string, "disable")
|| !strcasecmp(string, "disabled"))
|| !strcasecmp(string, "false")
|| !strcasecmp(string, "no")
|| !strcasecmp(string, "off")
|| !strcasecmp(string, "disable")
|| !strcasecmp(string, "disabled"))
return false;
// no correct value has been found => return default value
@ -105,7 +133,8 @@ bool get_string_value(const char *string, bool unknownValue)
}
const char *get_settings_value(const char *name, const driver_settings *settings)
const char*
get_settings_value(const char *name, const driver_settings *settings)
{
if(!name || !settings)
return NULL;

View File

@ -17,10 +17,11 @@ struct driver_parameter;
driver_settings *dup_driver_settings(const driver_settings *settings);
void free_driver_settings(driver_settings *settings);
ppp_side get_side_string_value(const char *sideString, ppp_side unknownValue);
bool get_boolean_value(const char *string, bool unknownValue);
const char *get_settings_value(const char *name, const driver_settings *settings);
const char *get_parameter_value(const char *name, const driver_parameter *parameters)
{ return get_settings_value(name, (driver_settings*) &parameters->parameter_count); }
#endif