From 06c8940fcf74643526009a25a50ec9cc523f1ba6 Mon Sep 17 00:00:00 2001 From: Waldemar Kornewald Date: Fri, 19 Sep 2003 17:53:09 +0000 Subject: [PATCH] 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 --- src/tests/kits/net/ppp/headers/KPPPDefs.h | 11 +- src/tests/kits/net/ppp/headers/KPPPDevice.h | 3 +- .../kits/net/ppp/headers/KPPPEncapsulator.h | 7 +- .../kits/net/ppp/headers/KPPPLCPExtension.h | 2 +- .../kits/net/ppp/headers/KPPPOptionHandler.h | 2 +- src/tests/kits/net/ppp/headers/KPPPProtocol.h | 21 +- src/tests/kits/net/ppp/headers/KPPPUtils.h | 1 + src/tests/kits/net/ppp/headers/PPPControl.h | 7 +- src/tests/kits/net/ppp/headers/PPPDefs.h | 16 +- src/tests/kits/net/ppp/src/Jamfile | 1 + src/tests/kits/net/ppp/src/KPPPDevice.cpp | 13 +- .../kits/net/ppp/src/KPPPEncapsulator.cpp | 31 +- src/tests/kits/net/ppp/src/KPPPInterface.cpp | 22 +- .../kits/net/ppp/src/KPPPLCPExtension.cpp | 13 +- .../kits/net/ppp/src/KPPPOptionHandler.cpp | 13 +- src/tests/kits/net/ppp/src/KPPPProtocol.cpp | 40 ++- .../kits/net/ppp/src/KPPPStateMachine.cpp | 8 +- .../ppp/src/_KPPPAuthenticationHandler.cpp | 283 ++++++++++++++++++ .../net/ppp/src/_KPPPAuthenticationHandler.h | 37 +++ src/tests/kits/net/ppp/src/settings_tools.cpp | 63 ++-- src/tests/kits/net/ppp/src/settings_tools.h | 3 +- 21 files changed, 497 insertions(+), 100 deletions(-) create mode 100644 src/tests/kits/net/ppp/src/_KPPPAuthenticationHandler.cpp create mode 100644 src/tests/kits/net/ppp/src/_KPPPAuthenticationHandler.h 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