/* Copyright 2015-2016 Amebis Copyright 2016 GÉANT This file is part of GÉANTLink. GÉANTLink is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. GÉANTLink is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GÉANTLink. If not, see . */ #include "StdAfx.h" using namespace std; using namespace winstd; ////////////////////////////////////////////////////////////////////// // eap::config_method_eaphost ////////////////////////////////////////////////////////////////////// eap::config_method_eaphost::config_method_eaphost(_In_ module &mod, _In_ unsigned int level) : config_method(mod, level), m_type_str(L"EapHost") { memset(&m_type, 0, sizeof(EAP_METHOD_TYPE)); } eap::config_method_eaphost::config_method_eaphost(_In_ const config_method_eaphost &other) : m_type (other.m_type ), m_type_str (other.m_type_str), m_cfg_blob (other.m_cfg_blob), config_method(other ) { } eap::config_method_eaphost::config_method_eaphost(_Inout_ config_method_eaphost &&other) : m_type (std::move(other.m_type )), m_type_str (std::move(other.m_type_str)), m_cfg_blob (std::move(other.m_cfg_blob)), config_method(std::move(other )) { } eap::config_method_eaphost& eap::config_method_eaphost::operator=(_In_ const config_method_eaphost &other) { if (this != &other) { (config_method&)*this = other; m_type = other.m_type; m_type_str = other.m_type_str; m_cfg_blob = other.m_cfg_blob; } return *this; } eap::config_method_eaphost& eap::config_method_eaphost::operator=(_Inout_ config_method_eaphost &&other) { if (this != &other) { (config_method&&)*this = std::move(other ); m_type = std::move(other.m_type ); m_type_str = std::move(other.m_type_str); m_cfg_blob = std::move(other.m_cfg_blob); } return *this; } eap::config* eap::config_method_eaphost::clone() const { return new config_method_eaphost(*this); } void eap::config_method_eaphost::save(_In_ IXMLDOMDocument *pDoc, _In_ IXMLDOMNode *pConfigRoot) const { assert(pDoc); assert(pConfigRoot); config_method::save(pDoc, pConfigRoot); // Convert configuration BLOB to XML using EapHost (and ultimately method peer's EapPeerConfigBlob2Xml). com_obj pConfigDoc; eap_error error; DWORD dwResult = EapHostPeerConfigBlob2Xml(0, m_type, (DWORD)m_cfg_blob.size(), const_cast(m_cfg_blob.data()), &pConfigDoc, &error._Myptr); if (dwResult == ERROR_SUCCESS) { HRESULT hr; com_obj pXmlElConfigDoc; if (FAILED(hr = pConfigDoc->get_documentElement(&pXmlElConfigDoc))) throw com_runtime_error(hr, __FUNCTION__ " Error getting XML document element."); // Insert method configuration into our XML configuration. if (FAILED(hr = pConfigRoot->appendChild(pXmlElConfigDoc, NULL))) throw com_runtime_error(hr, __FUNCTION__ " Error appending configuration document element."); } else if (error) throw eap_runtime_error(*error , __FUNCTION__ " EapHostPeerConfigBlob2Xml failed."); else throw win_runtime_error(dwResult, __FUNCTION__ " EapHostPeerConfigBlob2Xml failed."); } void eap::config_method_eaphost::load(_In_ IXMLDOMNode *pConfigRoot) { assert(pConfigRoot); config_method::load(pConfigRoot); // winstd::com_obj pXmlElEapHostConfig; if (SUCCEEDED(eapxml::select_element(pConfigRoot, winstd::bstr(L"eaphostconfig:EapHostConfig"), pXmlElEapHostConfig))) { // Convert configuration XML to BLOB using EapHost (and ultimately method peer's EapPeerConfigXml2Blob). DWORD cfg_data_size = 0; eap_blob cfg_data; eap_error error; DWORD dwResult = EapHostPeerConfigXml2Blob(0, pXmlElEapHostConfig, &cfg_data_size, &cfg_data._Myptr, &m_type, &error._Myptr); if (dwResult == ERROR_SUCCESS) { update_type(); const BYTE *_cfg_data = cfg_data.get(); m_cfg_blob.assign(_cfg_data, _cfg_data + cfg_data_size); } else if (error) throw eap_runtime_error(*error , __FUNCTION__ " EapHostPeerConfigXml2Blob failed."); else throw win_runtime_error(dwResult, __FUNCTION__ " EapHostPeerConfigXml2Blob failed."); } } void eap::config_method_eaphost::operator<<(_Inout_ cursor_out &cursor) const { config_method::operator<<(cursor); cursor << m_type ; cursor << m_cfg_blob; } size_t eap::config_method_eaphost::get_pk_size() const { return config_method::get_pk_size() + pksizeof(m_type ) + pksizeof(m_cfg_blob); } void eap::config_method_eaphost::operator>>(_Inout_ cursor_in &cursor) { config_method::operator>>(cursor); cursor >> m_type ; update_type(); cursor >> m_cfg_blob; } eap_type_t eap::config_method_eaphost::get_method_id() const { return (eap_type_t)m_type.eapType.type; } const wchar_t* eap::config_method_eaphost::get_method_str() const { return m_type_str.c_str(); } eap::credentials* eap::config_method_eaphost::make_credentials() const { return new credentials_eaphost(m_module); } /// \cond internal void eap::config_method_eaphost::update_type() { // Query registry for EAP method name and save it to m_type_str. // get_method_str() can return pointer to static string only, therefore we need to have the method name ready in advance. reg_key key; if (key.open(HKEY_LOCAL_MACHINE, m_type.dwAuthorId == 0 ? tstring_printf(_T("SYSTEM\\CurrentControlSet\\services\\RasMan\\PPP\\EAP\\%u" ), m_type.eapType.type ).c_str() : // Legacy EAP method (RasMan) m_type.eapType.type == 254 ? tstring_printf(_T("SYSTEM\\CurrentControlSet\\services\\EapHost\\Methods\\%u\\%u\\%u\\%u"), m_type.dwAuthorId, m_type.eapType.type, m_type.eapType.dwVendorId, m_type.eapType.dwVendorType).c_str() : // EapHost Expanded Type Peer tstring_printf(_T("SYSTEM\\CurrentControlSet\\services\\EapHost\\Methods\\%u\\%u" ), m_type.dwAuthorId, m_type.eapType.type ).c_str(), // EapHost Peer 0, KEY_READ) && RegLoadMUIStringW(key, m_type.dwAuthorId == 0 ? L"FriendlyName" : L"PeerFriendlyName", m_type_str, 0, NULL) == ERROR_SUCCESS) return; // Query failed. Provide generic name. if (m_type.dwAuthorId == 0 ) sprintf(m_type_str, L"RasMan-%u" , m_type.eapType.type ); else if (m_type.eapType.type == 254) sprintf(m_type_str, L"EapHost-%u-%u-%u-%u", m_type.dwAuthorId, m_type.eapType.type, m_type.eapType.dwVendorId, m_type.eapType.dwVendorType); else sprintf(m_type_str, L"EapHost-%u-%u" , m_type.dwAuthorId, m_type.eapType.type ); } /// \endcond