diff --git a/src/tests/kits/net/ppp/headers/KPPPDefs.h b/src/tests/kits/net/ppp/headers/KPPPDefs.h index b2a42a92e6..e1845c9209 100644 --- a/src/tests/kits/net/ppp/headers/KPPPDefs.h +++ b/src/tests/kits/net/ppp/headers/KPPPDefs.h @@ -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) diff --git a/src/tests/kits/net/ppp/headers/KPPPDevice.h b/src/tests/kits/net/ppp/headers/KPPPDevice.h index 88d2c69df0..bd7525c3f4 100644 --- a/src/tests/kits/net/ppp/headers/KPPPDevice.h +++ b/src/tests/kits/net/ppp/headers/KPPPDevice.h @@ -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; }; diff --git a/src/tests/kits/net/ppp/headers/KPPPEncapsulator.h b/src/tests/kits/net/ppp/headers/KPPPEncapsulator.h index 7e8f26f1d8..f007328635 100644 --- a/src/tests/kits/net/ppp/headers/KPPPEncapsulator.h +++ b/src/tests/kits/net/ppp/headers/KPPPEncapsulator.h @@ -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; diff --git a/src/tests/kits/net/ppp/headers/KPPPLCPExtension.h b/src/tests/kits/net/ppp/headers/KPPPLCPExtension.h index da58774286..0400e1dafa 100644 --- a/src/tests/kits/net/ppp/headers/KPPPLCPExtension.h +++ b/src/tests/kits/net/ppp/headers/KPPPLCPExtension.h @@ -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; diff --git a/src/tests/kits/net/ppp/headers/KPPPOptionHandler.h b/src/tests/kits/net/ppp/headers/KPPPOptionHandler.h index 1c3ec8e784..fb00c998fe 100644 --- a/src/tests/kits/net/ppp/headers/KPPPOptionHandler.h +++ b/src/tests/kits/net/ppp/headers/KPPPOptionHandler.h @@ -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; diff --git a/src/tests/kits/net/ppp/headers/KPPPProtocol.h b/src/tests/kits/net/ppp/headers/KPPPProtocol.h index 1a805aebd1..ca7efb0bbe 100644 --- a/src/tests/kits/net/ppp/headers/KPPPProtocol.h +++ b/src/tests/kits/net/ppp/headers/KPPPProtocol.h @@ -8,11 +8,10 @@ #ifndef _K_PPP_PROTOCOL__H #define _K_PPP_PROTOCOL__H -#include - #include 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; diff --git a/src/tests/kits/net/ppp/headers/KPPPUtils.h b/src/tests/kits/net/ppp/headers/KPPPUtils.h index 403d186669..87289cd21d 100644 --- a/src/tests/kits/net/ppp/headers/KPPPUtils.h +++ b/src/tests/kits/net/ppp/headers/KPPPUtils.h @@ -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. diff --git a/src/tests/kits/net/ppp/headers/PPPControl.h b/src/tests/kits/net/ppp/headers/PPPControl.h index de9b3382dd..b92821dad5 100644 --- a/src/tests/kits/net/ppp/headers/PPPControl.h +++ b/src/tests/kits/net/ppp/headers/PPPControl.h @@ -12,6 +12,10 @@ #include +// 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; diff --git a/src/tests/kits/net/ppp/headers/PPPDefs.h b/src/tests/kits/net/ppp/headers/PPPDefs.h index 7921575238..95a42a3a6b 100644 --- a/src/tests/kits/net/ppp/headers/PPPDefs.h +++ b/src/tests/kits/net/ppp/headers/PPPDefs.h @@ -11,10 +11,6 @@ #include -// 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 diff --git a/src/tests/kits/net/ppp/src/Jamfile b/src/tests/kits/net/ppp/src/Jamfile index e07d6f1d43..27b3c1950a 100644 --- a/src/tests/kits/net/ppp/src/Jamfile +++ b/src/tests/kits/net/ppp/src/Jamfile @@ -26,5 +26,6 @@ R5KernelStaticLibrary kernelppp : # integrated modules _KPPPMRUHandler.cpp + _KPPPAuthenticationHandler.cpp _KPPPPFCHandler.cpp ; diff --git a/src/tests/kits/net/ppp/src/KPPPDevice.cpp b/src/tests/kits/net/ppp/src/KPPPDevice.cpp index d55a692824..c2a0de388e 100644 --- a/src/tests/kits/net/ppp/src/KPPPDevice.cpp +++ b/src/tests/kits/net/ppp/src/KPPPDevice.cpp @@ -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(); diff --git a/src/tests/kits/net/ppp/src/KPPPEncapsulator.cpp b/src/tests/kits/net/ppp/src/KPPPEncapsulator.cpp index a8fe58e470..540129e9a9 100644 --- a/src/tests/kits/net/ppp/src/KPPPEncapsulator.cpp +++ b/src/tests/kits/net/ppp/src/KPPPEncapsulator.cpp @@ -7,6 +7,7 @@ #include #include +#include "settings_tools.h" #include @@ -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 diff --git a/src/tests/kits/net/ppp/src/KPPPInterface.cpp b/src/tests/kits/net/ppp/src/KPPPInterface.cpp index 0b02f481b8..e6b212b5f3 100644 --- a/src/tests/kits/net/ppp/src/KPPPInterface.cpp +++ b/src/tests/kits/net/ppp/src/KPPPInterface.cpp @@ -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; diff --git a/src/tests/kits/net/ppp/src/KPPPLCPExtension.cpp b/src/tests/kits/net/ppp/src/KPPPLCPExtension.cpp index dde5449d06..65ba15d444 100644 --- a/src/tests/kits/net/ppp/src/KPPPLCPExtension.cpp +++ b/src/tests/kits/net/ppp/src/KPPPLCPExtension.cpp @@ -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; diff --git a/src/tests/kits/net/ppp/src/KPPPOptionHandler.cpp b/src/tests/kits/net/ppp/src/KPPPOptionHandler.cpp index 394ebf5780..f1f0d7cbb6 100644 --- a/src/tests/kits/net/ppp/src/KPPPOptionHandler.cpp +++ b/src/tests/kits/net/ppp/src/KPPPOptionHandler.cpp @@ -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; diff --git a/src/tests/kits/net/ppp/src/KPPPProtocol.cpp b/src/tests/kits/net/ppp/src/KPPPProtocol.cpp index 65653f9be8..37b4020d45 100644 --- a/src/tests/kits/net/ppp/src/KPPPProtocol.cpp +++ b/src/tests/kits/net/ppp/src/KPPPProtocol.cpp @@ -6,8 +6,10 @@ //--------------------------------------------------------------------- #include +#include #include +#include "settings_tools.h" #include @@ -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: diff --git a/src/tests/kits/net/ppp/src/KPPPStateMachine.cpp b/src/tests/kits/net/ppp/src/KPPPStateMachine.cpp index a46980391e..937eda7fce 100644 --- a/src/tests/kits/net/ppp/src/KPPPStateMachine.cpp +++ b/src/tests/kits/net/ppp/src/KPPPStateMachine.cpp @@ -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); diff --git a/src/tests/kits/net/ppp/src/_KPPPAuthenticationHandler.cpp b/src/tests/kits/net/ppp/src/_KPPPAuthenticationHandler.cpp new file mode 100644 index 0000000000..bf6517aef4 --- /dev/null +++ b/src/tests/kits/net/ppp/src/_KPPPAuthenticationHandler.cpp @@ -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 +#include + +#include + +#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; +} diff --git a/src/tests/kits/net/ppp/src/_KPPPAuthenticationHandler.h b/src/tests/kits/net/ppp/src/_KPPPAuthenticationHandler.h new file mode 100644 index 0000000000..c9264f307e --- /dev/null +++ b/src/tests/kits/net/ppp/src/_KPPPAuthenticationHandler.h @@ -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 + + +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 diff --git a/src/tests/kits/net/ppp/src/settings_tools.cpp b/src/tests/kits/net/ppp/src/settings_tools.cpp index f7712936ff..c88e526412 100644 --- a/src/tests/kits/net/ppp/src/settings_tools.cpp +++ b/src/tests/kits/net/ppp/src/settings_tools.cpp @@ -5,6 +5,7 @@ // Copyright (c) 2003 Waldemar Kornewald, Waldemar.Kornewald@web.de //--------------------------------------------------------------------- +#include #include #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; diff --git a/src/tests/kits/net/ppp/src/settings_tools.h b/src/tests/kits/net/ppp/src/settings_tools.h index b25c084cd7..f45ac91c60 100644 --- a/src/tests/kits/net/ppp/src/settings_tools.h +++ b/src/tests/kits/net/ppp/src/settings_tools.h @@ -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*) ¶meters->parameter_count); } - #endif