summaryrefslogtreecommitdiff
path: root/cpp/src/IceSSL/ConfigParser.cpp
diff options
context:
space:
mode:
authorMark Spruiell <mes@zeroc.com>2002-04-24 21:13:00 +0000
committerMark Spruiell <mes@zeroc.com>2002-04-24 21:13:00 +0000
commit5409c1ecef0f226dedc77721c0d2fc8dfe9e85de (patch)
tree97ba75bc47a143726d6d8382be3a462e51716700 /cpp/src/IceSSL/ConfigParser.cpp
parentcleaning up sample impls (diff)
downloadice-5409c1ecef0f226dedc77721c0d2fc8dfe9e85de.tar.bz2
ice-5409c1ecef0f226dedc77721c0d2fc8dfe9e85de.tar.xz
ice-5409c1ecef0f226dedc77721c0d2fc8dfe9e85de.zip
merging from plugins branch
Diffstat (limited to 'cpp/src/IceSSL/ConfigParser.cpp')
-rw-r--r--cpp/src/IceSSL/ConfigParser.cpp657
1 files changed, 657 insertions, 0 deletions
diff --git a/cpp/src/IceSSL/ConfigParser.cpp b/cpp/src/IceSSL/ConfigParser.cpp
new file mode 100644
index 00000000000..48557ac2ada
--- /dev/null
+++ b/cpp/src/IceSSL/ConfigParser.cpp
@@ -0,0 +1,657 @@
+// **********************************************************************
+//
+// Copyright (c) 2001
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+// Note: This pragma is used to disable spurious warning messages having
+// to do with the length of debug symbols exceeding 255 characters.
+// This is due to STL template identifiers expansion.
+// The MSDN Library recommends that you put this pragma directive
+// in place to avoid the warnings.
+#ifdef _WIN32
+#pragma warning(disable:4786)
+#endif
+
+#include <sstream>
+#include <iostream>
+
+#include <util/PlatformUtils.hpp>
+#include <parsers/DOMParser.hpp>
+#include <framework/LocalFileInputSource.hpp>
+#include <util/Janitor.hpp>
+
+#include <IceSSL/OpenSSL.h>
+#include <IceSSL/Exception.h>
+#include <IceSSL/ConfigParserErrorReporter.h>
+#include <IceSSL/ConfigParser.h>
+
+#include <algorithm>
+
+using namespace std;
+using namespace IceSSL;
+
+//
+// Public Methods
+//
+
+IceSSL::ConfigParser::ConfigParser(const string& configFile) :
+ _configFile(configFile)
+{
+ assert(!configFile.empty());
+ _configPath = "./";
+ _traceLevels = 0;
+ _logger = 0;
+}
+
+IceSSL::ConfigParser::ConfigParser(const string& configFile, const string& configPath) :
+ _configFile(configFile),
+ _configPath(configPath)
+{
+ assert(!configFile.empty());
+ assert(!configPath.empty());
+ _traceLevels = 0;
+ _logger = 0;
+}
+
+IceSSL::ConfigParser::~ConfigParser()
+{
+}
+
+void
+IceSSL::ConfigParser::process()
+{
+ try
+ {
+ XMLPlatformUtils::Initialize();
+ }
+ catch(const XMLException& toCatch)
+ {
+ ConfigParseException configEx(__FILE__, __LINE__);
+
+ ostringstream s;
+ s << "while parsing " << _configFile << ": " << endl;
+ s << "xerces-c init exception: " << DOMString(toCatch.getMessage());
+
+ configEx._message = s.str();
+
+ throw configEx;
+ }
+
+ int errorCount = 0;
+
+ ConfigParserErrorReporterPtr errReporter = new ConfigParserErrorReporter(_traceLevels, _logger);
+ assert(errReporter != 0);
+
+ // Create our parser, then attach an error handler to the parser.
+ // The parser will call back to methods of the ConfigParserErrorHandler
+ // if it discovers errors during the course of parsing the XML document.
+ DOMParser parser;
+ parser.setValidationScheme(DOMParser::Val_Auto);
+ parser.setDoNamespaces(false);
+ parser.setDoSchema(false);
+ parser.setCreateEntityReferenceNodes(false);
+ parser.setToCreateXMLDeclTypeNode(true);
+ parser.setErrorHandler(errReporter.get());
+
+ try
+ {
+ if (*(_configFile.begin()) != '/')
+ {
+ if (*(_configPath.rbegin()) != '/')
+ {
+ _configPath += "/";
+ }
+
+ XMLCh* xmlConfigPath = XMLString::transcode(_configPath.c_str());
+ XMLCh* xmlConfigFile = XMLString::transcode(_configFile.c_str());
+ ArrayJanitor<XMLCh> janPath(xmlConfigPath);
+ ArrayJanitor<XMLCh> janFile(xmlConfigFile);
+ LocalFileInputSource configSource(xmlConfigPath, xmlConfigFile);
+
+ parser.parse(configSource);
+ }
+ else
+ {
+ XMLCh* xmlConfigFile = XMLString::transcode(_configFile.c_str());
+ ArrayJanitor<XMLCh> janFile(xmlConfigFile);
+ LocalFileInputSource configSource(xmlConfigFile);
+
+ parser.parse(configSource);
+ }
+
+ errorCount = parser.getErrorCount();
+
+ if (errorCount == 0)
+ {
+ // Get the root of the parse tree.
+ _root = parser.getDocument();
+ }
+ }
+ catch (const XMLException& e)
+ {
+ ConfigParseException configEx(__FILE__, __LINE__);
+
+ ostringstream s;
+ s << "while parsing " << _configFile << ": " << endl;
+ s << "xerces-c parsing error: " << DOMString(e.getMessage());
+
+ configEx._message = s.str();
+
+ throw configEx;
+ }
+ catch (const DOM_DOMException& e)
+ {
+ ConfigParseException configEx(__FILE__, __LINE__);
+
+ ostringstream s;
+ s << "while parsing " << _configFile << ": " << endl;
+ s << "xerces-c DOM parsing error, DOMException code: " << e.code;
+ s << ", message: " << e.msg;
+
+ configEx._message = s.str();
+
+ throw configEx;
+ }
+ catch (...)
+ {
+ ConfigParseException configEx(__FILE__, __LINE__);
+
+ configEx._message = "while parsing " + _configFile + "\n" + "unknown error occured during parsing";
+
+ throw configEx;
+ }
+
+ if (errorCount)
+ {
+ ConfigParseException configEx(__FILE__, __LINE__);
+
+ ostringstream errStr;
+
+ errStr << dec << errorCount << " errors occured during parsing";
+
+ configEx._message = errStr.str();
+
+ string reporterErrors = errReporter->getErrors();
+
+ if (!reporterErrors.empty())
+ {
+ configEx._message += "\n";
+ configEx._message += reporterErrors;
+ }
+
+ throw configEx;
+ }
+}
+
+bool
+IceSSL::ConfigParser::loadClientConfig(GeneralConfig& general,
+ CertificateAuthority& certAuth,
+ BaseCertificates& baseCerts)
+{
+ string clientSectionString("SSLConfig:client");
+ DOM_Node clientSection = find(clientSectionString);
+
+ try
+ {
+ // If we actually have a client section.
+ if (clientSection != 0)
+ {
+ getGeneral(clientSection, general);
+ getCertAuth(clientSection, certAuth);
+ getBaseCerts(clientSection, baseCerts);
+ return true;
+ }
+ }
+ catch (const DOM_DOMException& e)
+ {
+ ConfigParseException configEx(__FILE__, __LINE__);
+
+ ostringstream s;
+ s << "while loading client configuration: " << endl;
+ s << "xerces-c DOM parsing error, DOMException code: " << e.code;
+ s << ", message: " << e.msg;
+
+ configEx._message = s.str();
+
+ throw configEx;
+ }
+
+ return false;
+}
+
+bool
+IceSSL::ConfigParser::loadServerConfig(GeneralConfig& general,
+ CertificateAuthority& certAuth,
+ BaseCertificates& baseCerts,
+ TempCertificates& tempCerts)
+{
+ string serverSectionString("SSLConfig:server");
+ DOM_Node serverSection = find(serverSectionString);
+
+ try
+ {
+ // If we actually have a client section.
+ if (serverSection != 0)
+ {
+ getGeneral(serverSection, general);
+ getCertAuth(serverSection, certAuth);
+ getBaseCerts(serverSection, baseCerts);
+ getTempCerts(serverSection, tempCerts);
+ return true;
+ }
+ }
+ catch (const DOM_DOMException& e)
+ {
+ ConfigParseException configEx(__FILE__, __LINE__);
+
+ ostringstream s;
+ s << "while loading server configuration " << endl;
+ s << "xerces-c DOM parsing error, DOMException code: " << e.code;
+ s << ", message: " << e.msg;
+
+ configEx._message = s.str();
+
+ throw configEx;
+ }
+
+ return false;
+}
+
+void
+IceSSL::ConfigParser::setTrace(const IceInternal::TraceLevelsPtr& traceLevels)
+{
+ _traceLevels = traceLevels;
+}
+
+bool
+IceSSL::ConfigParser::isTraceSet() const
+{
+ return _traceLevels;
+}
+
+void
+IceSSL::ConfigParser::setLogger(const Ice::LoggerPtr& logger)
+{
+ _logger = logger;
+}
+
+bool
+IceSSL::ConfigParser::isLoggerSet() const
+{
+ return _logger;
+}
+
+//
+// Private Methods
+//
+
+// path is of the form "sslconfig:client:general"
+void
+IceSSL::ConfigParser::popRoot(string& path, string& root, string& tail)
+{
+ string::size_type pos = path.find_first_of(':');
+
+ if (pos != string::npos)
+ {
+ root = path.substr(0,pos);
+ tail = path.substr(pos+1);
+ }
+ else
+ {
+ root = path;
+ tail = "";
+ }
+}
+
+DOM_Node
+IceSSL::ConfigParser::find(string& nodePath)
+{
+ return find(_root, nodePath);
+}
+
+DOM_Node
+IceSSL::ConfigParser::find(DOM_Node rootNode, string& nodePath)
+{
+ // The target node that we're looking for.
+ DOM_Node tNode;
+
+ if (rootNode == 0)
+ {
+ return tNode;
+ }
+
+ string rootNodeName;
+ string tailNodes;
+
+ // Pop the root off the path.
+ popRoot(nodePath, rootNodeName, tailNodes);
+
+ DOM_Node child = rootNode.getFirstChild();
+
+ while (child != 0)
+ {
+ // Ignore any other node types - we're only interested in ELEMENT_NODEs.
+ if (child.getNodeType() == DOM_Node::ELEMENT_NODE)
+ {
+ string nodeName = toString(child.getNodeName());
+
+ if (nodeName.compare(rootNodeName) == 0)
+ {
+ // No further to recurse, this must be it.
+ if (tailNodes.empty())
+ {
+ tNode = child;
+ }
+ else
+ {
+ // Recursive call.
+ tNode = find(child, tailNodes);
+ }
+ }
+ }
+
+ child = child.getNextSibling();
+ }
+
+ return tNode;
+}
+
+void
+IceSSL::ConfigParser::getGeneral(DOM_Node rootNode, GeneralConfig& generalConfig)
+{
+ if (rootNode == 0)
+ {
+ return;
+ }
+
+ string generalString("general");
+ DOM_Node general = find(rootNode, generalString);
+
+ DOM_NamedNodeMap attributes = general.getAttributes();
+
+ int attrCount = attributes.getLength();
+
+ for (int i = 0; i < attrCount; i++)
+ {
+ DOM_Node attribute = attributes.item(i);
+ string nodeName = toString(attribute.getNodeName());
+ string nodeValue = toString(attribute.getNodeValue());
+
+ // Set the property.
+ generalConfig.set(nodeName, nodeValue);
+ }
+}
+
+void
+IceSSL::ConfigParser::getCertAuth(DOM_Node rootNode, CertificateAuthority& certAuth)
+{
+ if (rootNode == 0)
+ {
+ return;
+ }
+
+ string nodeName = "certauthority";
+ DOM_Node certAuthNode = find(rootNode, nodeName);
+
+ if (certAuthNode == 0)
+ {
+ return;
+ }
+
+ DOM_NamedNodeMap attributes = certAuthNode.getAttributes();
+
+ int attrCount = attributes.getLength();
+
+ for (int i = 0; i < attrCount; i++)
+ {
+ DOM_Node attribute = attributes.item(i);
+ string nodeName = toString(attribute.getNodeName());
+ string nodeValue = toString(attribute.getNodeValue());
+
+ if (nodeName.compare("file") == 0)
+ {
+ string filename = nodeValue;
+
+ // Just a filename, no path component, append path.
+ if ((filename.find("/") == string::npos) && (filename.find("\\") == string::npos))
+ {
+ filename = _configPath + filename;
+ }
+
+ certAuth.setCAFileName(filename);
+ }
+ else if (nodeName.compare("path") == 0)
+ {
+ certAuth.setCAPath(nodeValue);
+ }
+ }
+}
+
+void
+IceSSL::ConfigParser::getBaseCerts(DOM_Node rootNode, BaseCertificates& baseCerts)
+{
+ if (rootNode == 0)
+ {
+ return;
+ }
+
+ string nodeName = "basecerts";
+ DOM_Node baseCertsRoot = find(rootNode, nodeName);
+
+ if (baseCertsRoot == 0)
+ {
+ return;
+ }
+
+ CertificateDesc rsaCert;
+ CertificateDesc dsaCert;
+ DiffieHellmanParamsFile dhParams;
+
+ string rsaCertString("rsacert");
+ string dsaCertString("dsacert");
+ string dhParamsString("dhparams");
+
+ getCert(find(baseCertsRoot, rsaCertString), rsaCert);
+ getCert(find(baseCertsRoot, dsaCertString), dsaCert);
+
+ getDHParams(find(baseCertsRoot, dhParamsString), dhParams);
+
+ baseCerts = BaseCertificates(rsaCert, dsaCert, dhParams);
+}
+
+void
+IceSSL::ConfigParser::getTempCerts(DOM_Node rootNode, TempCertificates& tempCerts)
+{
+ if (rootNode == 0)
+ {
+ return;
+ }
+
+ string nodeName = "tempcerts";
+ DOM_Node tempCertsRoot = find(rootNode, nodeName);
+
+ if (tempCertsRoot == 0)
+ {
+ return;
+ }
+
+ DOM_Node child = tempCertsRoot.getFirstChild();
+
+ while (child != 0)
+ {
+ DOMString nodeName = child.getNodeName();
+ string name = toString(nodeName);
+
+ if (name.compare("dhparams") == 0)
+ {
+ loadDHParams(child, tempCerts);
+ }
+ else if (name.compare("rsacert") == 0)
+ {
+ loadRSACert(child, tempCerts);
+ }
+
+ child = child.getNextSibling();
+ }
+}
+
+void
+IceSSL::ConfigParser::loadDHParams(DOM_Node rootNode, TempCertificates& tempCerts)
+{
+ DiffieHellmanParamsFile dhParams;
+
+ getDHParams(rootNode, dhParams);
+
+ tempCerts.addDHParams(dhParams);
+}
+
+void
+IceSSL::ConfigParser::loadRSACert(DOM_Node rootNode, TempCertificates& tempCerts)
+{
+ CertificateDesc rsaCert;
+
+ getCert(rootNode, rsaCert);
+
+ tempCerts.addRSACert(rsaCert);
+}
+
+void
+IceSSL::ConfigParser::getCert(DOM_Node rootNode, CertificateDesc& certDesc)
+{
+ if (rootNode == 0)
+ {
+ return;
+ }
+
+ CertificateFile publicFile;
+ CertificateFile privateFile;
+ int keySize = 0;
+
+ DOM_NamedNodeMap attributes = rootNode.getAttributes();
+ int attrCount = attributes.getLength();
+
+ for (int i = 0; i < attrCount; i++)
+ {
+ DOM_Node attribute = attributes.item(i);
+ string nodeName = toString(attribute.getNodeName());
+ string nodeValue = toString(attribute.getNodeValue());
+
+ if (nodeName.compare("keysize") == 0)
+ {
+ keySize = atoi(nodeValue.c_str());
+ }
+ }
+
+ string publicString("public");
+ string privateString("private");
+
+ loadCertificateFile(find(rootNode, publicString), publicFile);
+ loadCertificateFile(find(rootNode, privateString), privateFile);
+
+ // Initialize the certificate description.
+ certDesc = CertificateDesc(keySize, publicFile, privateFile);
+}
+
+void
+IceSSL::ConfigParser::getDHParams(DOM_Node rootNode, DiffieHellmanParamsFile& dhParams)
+{
+ if (rootNode == 0)
+ {
+ return;
+ }
+
+ CertificateFile certFile;
+ loadCertificateFile(rootNode, certFile);
+
+ DOM_NamedNodeMap attributes = rootNode.getAttributes();
+ int keySize = 0;
+ int attrCount = attributes.getLength();
+
+ for (int i = 0; i < attrCount; i++)
+ {
+ DOM_Node attribute = attributes.item(i);
+ string nodeName = toString(attribute.getNodeName());
+ string nodeValue = toString(attribute.getNodeValue());
+
+ if (nodeName.compare("keysize") == 0)
+ {
+ keySize = atoi(nodeValue.c_str());
+ }
+ }
+
+ dhParams = DiffieHellmanParamsFile(keySize, certFile.getFileName(), certFile.getEncoding());
+}
+
+void
+IceSSL::ConfigParser::loadCertificateFile(DOM_Node rootNode, CertificateFile& certFile)
+{
+ if (rootNode == 0)
+ {
+ return;
+ }
+
+ string filename;
+ int encoding = 0; // Initialize, to keep the compiler from complaining.
+
+ DOM_NamedNodeMap attributes = rootNode.getAttributes();
+ int attrCount = attributes.getLength();
+
+ for (int i = 0; i < attrCount; i++)
+ {
+ DOM_Node attribute = attributes.item(i);
+ string nodeName = toString(attribute.getNodeName());
+ string nodeValue = toString(attribute.getNodeValue());
+
+ if (nodeName.compare("encoding") == 0)
+ {
+ encoding = parseEncoding(nodeValue);
+ }
+ else if (nodeName.compare("filename") == 0)
+ {
+ filename = nodeValue;
+
+ // Just a filename, no path component, append path.
+ if ((filename.find("/") == string::npos) && (filename.find("\\") == string::npos))
+ {
+ filename = _configPath + filename;
+ }
+ }
+ }
+
+ certFile = CertificateFile(filename, encoding);
+}
+
+int
+IceSSL::ConfigParser::parseEncoding(string& encodingString)
+{
+ int encoding = 0;
+
+ if (encodingString.compare("PEM") == 0)
+ {
+ encoding = SSL_FILETYPE_PEM;
+ }
+ else if (encodingString.compare("ASN1") == 0)
+ {
+ encoding = SSL_FILETYPE_ASN1;
+ }
+
+ return encoding;
+}
+
+string
+IceSSL::ConfigParser::toString(const DOMString& domString)
+{
+ char* cString = domString.transcode();
+
+ string stlString(cString);
+
+ delete []cString;
+
+ return stlString;
+}
+