示例#1
0
    /*
     * Uses the currently set locale to read a pre-defined file and then compares
     * the output with a reference file that is read with the UTF-8 functions.
     * These should of course be the same for this test to be successful.
     *
     * What encoded file should be read for a certain locale, and which reference file
     * should be used to test against is handled with a configurations file
     * that has the name "scxfile_test-locale-map.txt" that consists of multiple 
     * lines like this:
     * <name of locale> <name of encoded file> <name of reference file>
     * 
     * The "encoded file" is read with named locale active into an array.
     * The reference file is read with our own UTF-8 decoding routines, into 
     * another array. These two should result in exactly the same result for this
     * test to be successful.
     * 
     * If you're writing a new encoded or reference file, you'll at some point need
     * to see exactly what it contains byte-for-byte. The this command will be 
     * useful: "od -t x1 <filename>".
     *
     * If the current locale is not found in the configuration file, this results
     * in a warning.
     */
    void TestReadFilesWithPresetCharacterConversion()
    {
        bool found = false;

        std::wifstream locmap("./testfiles/scxfile_test-locale-map.txt");
        wstring locName, encodedFileName, referenceFileName;

        // This is the name of the currently selected locale for the Ctype facet
        wstring presetLocaleName(SCXLocaleContext::GetCtypeName());

        if (presetLocaleName == L"C" || presetLocaleName == L"POSIX") {
            SCXUNIT_WARNING(L"Testing with C/POSIX locale is meaningless.");
        }

        wcout << "\nTesting preset locale " << presetLocaleName << endl;

        while (locmap) {
            locmap >> locName >> encodedFileName >> referenceFileName;

            // Diagnostic output
            // wcout << "Name " << locName << endl;
            // wcout << "File " << encodedFileName << endl;
            // wcout << "File " << referenceFileName << endl;

            if (locName == presetLocaleName) {
                // wcout << L"found " << locName << endl;
                found = true;
                break;
            }
        }

        if (!found) {
            SCXUNIT_WARNING(L"Can't find preset locale " + presetLocaleName + L" in locale-map.txt. Please add it and test again.");
            return;
        }

        SCXFilePath encodedFileFP;
        encodedFileFP.SetDirectory(L"./testfiles/");
        encodedFileFP.SetFilename(encodedFileName);

        SCXFilePath referenceFileFP;
        referenceFileFP.SetDirectory(L"./testfiles/");
        referenceFileFP.SetFilename(referenceFileName);

        SCXStream::NLFs nlfs;
        vector<wstring> localLines;
        vector<wstring> utf8Lines;
        SCXFile::ReadAllLines(encodedFileFP, localLines, nlfs);
        SCXFile::ReadAllLinesAsUTF8(referenceFileFP, utf8Lines, nlfs);
        CPPUNIT_ASSERT_MESSAGE("Failure for preset locale " + locale().name(),
                               localLines == utf8Lines);

    }
    /**
        Constructor

       \param[in]  id            Identifier for the appserver (= install path for the appserver configuration)
       \param[in]  homePath      Root install path for the application server
       \param[in]  deps          Dependency instance to use
    */
    TomcatAppServerInstance::TomcatAppServerInstance(
        wstring id, wstring homePath, SCXHandle<TomcatAppServerInstancePALDependencies> deps) : 
        AppServerInstance(id, APP_SERVER_TYPE_TOMCAT), m_deps(deps)
    {
        SCXFilePath installPath;
        SCXFilePath homeFilePath;

        installPath.SetDirectory(id);
        SetId(installPath.Get());
        m_diskPath = GetId();
        homeFilePath.SetDirectory(homePath);
        m_homePath = homeFilePath.Get();

        SCX_LOGTRACE(m_log, wstring(L"TomcatAppServerInstance default constructor - ").append(GetId()));
    }
    /**
        Read the nodemanager.domains file to get a list of the
        WebLogic 10g domains associated with the installation.
           
        Note: this file is located up the tree in a 'well-known' location.
              i.e. /opt/Oracle/Middleware/wlserver_10.3/common/nodemanager/nodemanager.domains
       
       Example:
       #Domains and directories created by Configuration Wizard
       #Tue Apr 12 15:23:12 PDT 2011
       base_domain=/opt/Oracle/Middleware/user_projects/domains/base_domain 
       
       \param[in]  nodemanagerDomains File object of the text file
                                      to open.
                                            
       \param[out] domains           vector that will be populated with
                                     list of discovered domains.
       
     */
    void WebLogicFileReader::ReadNodemanagerDomains(
            const SCXFilePath& nodemanagerDomains,
            vector<SCXFilePath>& domains)
    {
        string content;

        try {
            
            /*
             * Parse the INI file. 
             * 
             * After a '#', assume the rest of the line is a comment.
             * The file should consist of name/value pairs seperated
             * by an '='. 
             */
            SCXHandle<istream> reader = 
                    OpenNodemanagerDomains(nodemanagerDomains.Get());
            
            while (SCXStream::IsGood(*reader))
            {
                string buffer;
                getline(*reader, buffer);
                
                size_t effectiveEnd = buffer.size();
                size_t commentLocation = buffer.find(INI_COMMENT);
                if (string::npos != commentLocation)
                {
                    effectiveEnd = commentLocation; 
                }
                
                size_t delimiterLocation = buffer.find(INI_DELIMITER);
                if (string::npos != delimiterLocation)
                {
                    string narrowPath = buffer.substr(delimiterLocation + 1);
                    wstring widePath = StrFromUTF8(narrowPath);
                    SCXFilePath domainPath;
                    domainPath.SetDirectory(widePath);
                    domains.push_back(domainPath);
                }
            }
        }
        catch (SCXFilePathNotFoundException&)
        {
            SCX_LOGERROR(m_log, 
                    wstring(L"WebLogicFileReader::ReadNodemanagerDomains() - ").
                    append(m_installationPath).append(L" - Could not find file: ").
                    append(nodemanagerDomains.Get()));
        }
        catch (SCXUnauthorizedFileSystemAccessException&)
        {
            SCX_LOGERROR(m_log, 
                    wstring(L"WebLogicFileReader::ReadNodemanagerDomains() - ").
                    append(m_installationPath).append(L" - not authorized to open file: ").
                    append(nodemanagerDomains.Get()));
        }
    }
    /**
     From the necessary file, read the domains and return a unique list
     of potential domains.
     
     */
    vector<SCXFilePath> WebLogicFileReader::GetDomains()
    {
        SCX_LOGTRACE(m_log, L"WebLogicFileReader::GetDomains");

        vector<SCXFilePath> domains;

        // Logic necessary for reading WebLogic 11g domains
        SCXFilePath domainRegistryXml;
        domainRegistryXml.SetDirectory(m_installationPath);
        domainRegistryXml.SetFilename(
                WEBLOGIC_DOMAIN_REGISTRY_XML_FILENAME);
        
        if (DoesDomainRegistryXmlExist(domainRegistryXml))
        {
            ReadDomainRegistryXml(domainRegistryXml, domains);
        }

        // Logic necessary for reading WebLogic 10g domains
        SCXFilePath nodemanagerDomains;
        nodemanagerDomains.SetDirectory(m_installationPath);
        nodemanagerDomains.AppendDirectory(WEBLOGIC_NODEMANAGER_DOMAINS_DIRECTORY);
        nodemanagerDomains.SetFilename(WEBLOGIC_NODEMANAGER_DOMAINS_FILENAME);

        if (DoesNodemanagerDomainsExist(nodemanagerDomains))
        {
            ReadNodemanagerDomains(nodemanagerDomains, domains);
        }
        
        // There may be duplicates in the list, it is necessary to
        // sort the list of domains and return only the unique instances.
        sort(domains.begin(), domains.end(), SortPath());
        vector<SCXFilePath>::iterator tmp = 
                unique(domains.begin(), domains.end());
        domains.resize(tmp-domains.begin());
                
        SCX_LOGTRACE(m_log, 
                wstring(L"WebLogicFileReader::GetDomains() - ").
                append(L"Found ").append(StrFrom(domains.size())).append(L" domain(s)"));

        return domains;
    }
    /**
       Read a simple XML file to find the locations of the domains for
       this WebLogic 11g R1 installation.
       
       Example:
       <?xml version="1.0" encoding="UTF-8"?>
       <domain-registry xmlns="http://xmlns.oracle.com/weblogic/domain-registry">
         <domain location="/opt/Oracle/Middleware/user_projects/domains/base_domain"/>
       </domain-registry> 
       
              \param[in]  domainRegistryXml File object of the XML file
                                            to open.
                                            
              \param[out] domains           vector that will contain the
                                            list of discovered domains.
     */
    void WebLogicFileReader::ReadDomainRegistryXml(
            const SCXFilePath& domainRegistryXml,
            vector<SCXFilePath>& domains)
    {
        string xml;

        try {
            SCXHandle<istream> reader = 
                    OpenDomainRegistryXml(domainRegistryXml.Get());
            GetStringFromStream(reader, xml);

            XElementPtr domainRegistryNode;
            XElement::Load(xml, domainRegistryNode);
            if (domainRegistryNode->GetName() == WEBLOGIC_DOMAIN_REGISTRY_XML_NODE)
            {
                XElementList domainNodes;
                domainRegistryNode->GetChildren(domainNodes);
                for (size_t index = 0; index < domainNodes.size(); ++index)
                {
                    string location;
                    if (domainNodes[index]->GetName() == WEBLOGIC_DOMAIN_XML_NODE && 
                        domainNodes[index]->GetAttributeValue(WEBLOGIC_LOCATION_XML_ATTRIBUTE, location))
                    {
                        wstring wideLocation = StrFromUTF8(location);
                        SCXFilePath domainPath;
                        domainPath.SetDirectory(wideLocation);                                
                        domains.push_back(domainPath);
                    }
                }
            }
        }
        catch (SCXFilePathNotFoundException&)
        {
            SCX_LOGERROR(m_log, 
                    wstring(L"WebLogicFileReader::ReadDomainRegistryXml() - ").
                    append(m_installationPath).append(L" - Could not find file: ").
                    append(domainRegistryXml.Get()));
        }
        catch (SCXUnauthorizedFileSystemAccessException&)
        {
            SCX_LOGERROR(m_log, 
                    wstring(L"WebLogicFileReader::ReadDomainRegistryXml() - ").
                    append(m_installationPath).append(L" - not authorized to open file: ").
                    append(domainRegistryXml.Get()));
        }
        catch (XmlException&)
        {
            SCX_LOGERROR(m_log, 
                    wstring(L"WebLogicFileReader::ReadDomainRegistryXml() - ").
                    append(m_installationPath).append(L" - Could not load XML from file: ").
                    append(domainRegistryXml.Get()));
        }
    }
示例#6
0
 //! Search for an existing filename using case insensitive comparision
 SCXFilePath SearchExistingFilename(const wstring &directory, const wstring &name) {
     vector<SCXCoreLib::SCXFilePath> files = SCXDirectory::GetFiles(directory);
     for (size_t nr = 0; nr < files.size(); nr++) {
         if (StrCompare(files[nr].GetFilename(), name, true) == 0) {
             return files[nr];
         }
     }
     // No existing name found, return the original path
     SCXFilePath original;
     original.SetDirectory(directory);
     original.SetFilename(name);
     return original;
 }
示例#7
0
    void TestFileSystemInfo_SetAttributes()
    {
        // Improve code coverage on SCXFileSystemInfo
#if defined(SCX_UNIX)
        SCXFileSystem::Attribute readable = SCXFileSystem::eUserRead;
        SCXFileSystem::Attribute writable = SCXFileSystem::eUserWrite;
#else
        SCXFileSystem::Attribute readable = SCXFileSystem::eReadable;
        SCXFileSystem::Attribute writable = SCXFileSystem::eWritable;
#endif

        SCXFileInfo fi(m_path1);

        SCXFileSystem::Attributes attrRO, attrRW;
        attrRO.insert(readable);
        attrRW.insert(readable);
        attrRW.insert(writable);

        // Test SCXFileSystemInfo::SetAttributes and SCXFileSystemInfo::isWritable (and make sure it's right!)
        fi.SetAttributes(attrRO);
        CPPUNIT_ASSERT(! fi.isWritable());
        CPPUNIT_ASSERT(fi.GetAttributes().count(writable) == 0);
        fi.SetAttributes(attrRW);
        fi.Refresh();
        CPPUNIT_ASSERT(fi.isWritable());
        CPPUNIT_ASSERT(fi.GetAttributes().count(writable) != 0);

        // Create a new "junk" object to test directory - test SCXFileSystemInfo::GetDirectoryPath
        // (Use operator += to add a filename to pick up an additional test of that operator)
        SCXFilePath fbad = fi.GetDirectoryPath();
        fbad += L"file";
        fbad += L".txt";
        fbad.SetDirectory(L"/bogus/directory/path");
#if defined(SCX_UNIX)
        CPPUNIT_ASSERT(fbad.GetDirectory() == L"/bogus/directory/path/");
        CPPUNIT_ASSERT(fbad.Get() == L"/bogus/directory/path/file.txt");
#else
        CPPUNIT_ASSERT(fbad.GetDirectory() == L"\\bogus\\directory\\path\\");
        CPPUNIT_ASSERT(fbad.Get() == L"\\bogus\\directory\\path\\file.txt");
#endif
        // Original path was created without directory - test SCXFileSystemInfo::GetOriginalPath
        CPPUNIT_ASSERT(fi.GetOriginalPath().GetDirectory() == L"");
        CPPUNIT_ASSERT(fi.GetFullPath().GetDirectory() != L"");
    }
    /**
        Constructor

       \param[in]  cell          The WebSphere Cell Name
       \param[in]  node          The WebSphere Node Name
       \param[in]  profile       The WebSphete Profile Name
       \param[in]  installDir    The folder where WebSphere is installed
       \param[in]  server        The WebSphere Server Name
       \param[in]  deps          Dependency instance to use
    */
    WebSphereAppServerInstance::WebSphereAppServerInstance(
        wstring installDir, wstring cell, wstring node, wstring profile, wstring server,
        SCXHandle<WebSphereAppServerInstancePALDependencies> deps) : 
        AppServerInstance(installDir, APP_SERVER_TYPE_WEBSPHERE), m_deps(deps)
    {
        SCXFilePath installPath;

        installPath.SetDirectory(installDir);

        m_diskPath = installPath.Get();
        
        m_cell = cell;
        m_node = node;
        m_profile = profile;
        m_server = server;

        wstring id = profile;
        SetId(id.append(L"-").append(cell).append(L"-").append(node).append(L"-").append(server));

        SCX_LOGTRACE(m_log, wstring(L"WebSphereAppServerInstance default constructor - ").append(GetId()));
    }
    /**
       From the necessary XML configuration file, read information about
       the known instances.
       
       The file should be:
           ${Install}/${Domain}/config/config.xml

       \param[in]  domains    List of domains to find instances for

       \param[out] instances  vector to add instances to
       
    */    
    void WebLogicFileReader::GetInstances(
            const SCXFilePath& domain,
            vector<SCXHandle<AppServerInstance> >& instances)
    {
        SCXFilePath configXml;
        configXml.SetDirectory(domain.Get());
        configXml.AppendDirectory(WEBLOGIC_CONFIG_DIRECTORY);
        configXml.Append(WEBLOGIC_CONFIG_FILENAME);
        
        if (DoesConfigXmlExist(configXml))        
           {
            SCX_LOGTRACE(m_log, 
                    wstring(L"WebLogicFileReader::GetInstances() - ").
                    append(L"Reading ").append(configXml.Get()));
            ReadConfigXml(domain, configXml, instances);
           }
        else
        {
            SCX_LOGTRACE(m_log, 
                    wstring(L"WebLogicFileReader::GetInstances() - ").
                    append(L"Expected configuration file '").
                    append(configXml.Get()).append(L"' does not exist."));
        }
    }
    /**
       Read a simple XML file to find the locations of the both 
       the Admin and Managed servers for a WebLogic 11g R1 installation.
       
       Example:
       <?xml version="1.0" encoding="UTF-8"?>
       <domain ...>
         <name>base_domain</name>
         <domain-version>10.3.2.0</domain-version>
         <security-configuration ...>
            ...
         </security-configuration>
         <server>
           <name>AdminServer</name>
           <ssl>
             <name>AdminServer</name>
             <enabled>true</enabled>
             <listen-port>7012</listen-port>
           </ssl>
           <machine>new_UnixMachine_1</machine>
           <listen-port>7011</listen-port>
           <listen-address/>
         </server>
         <server>
           <name>new_ManagedServer_1</name>
           <ssl>
             <name>new_ManagedServer_1</name>
             <enabled>true</enabled>
             <listen-port>7513</listen-port>
           </ssl>
           <machine>new_UnixMachine_1</machine>
           <listen-port>7013</listen-port>
           <listen-address/>
         </server>
         <embedded-ldap>
           <name>base_domain</name>
           <credential-encrypted>{AES}RVX+Cadq8XJ5EvV7/1Ta2qGZrJlxve6t5CEa2A9euGUkYOMDTAwAqytymqDBS00Q</credential-encrypted>
         </embedded-ldap>
         <configuration-version>10.3.2.0</configuration-version>
         <machine xsi:type="unix-machineType">
           <name>new_UnixMachine_1</name>
           <node-manager>
             <name>new_UnixMachine_1</name>
             <listen-address>localhost</listen-address>
             <listen-port>5566</listen-port>
           </node-manager>
         </machine>
         <admin-server-name>AdminServer</admin-server-name>
       </domain>

              \param[in]  domainDir         Directory of the domain (needed
                                            for build the path to the server
       
              \param[in]  configXml         File object of the XML file
                                            to open.
                                            
              \param[out] instances         vector that will contain the
                                            list of server instances for the
                                            given domain.
       
     */
    void WebLogicFileReader::ReadConfigXml(
            const SCXFilePath& domainDir,
            const SCXFilePath& configXml,
            vector<SCXHandle<AppServerInstance> >& instances)
    {
        SCX_LOGTRACE(m_log, L"WebLogicFileReader::ReadConfigXml");
        SCX_LOGTRACE(m_log, 
                wstring(L"WebLogicFileReader::ReadConfigXml() - ").
                append(L"Reading the file: ").append(configXml.Get()));
        string xml;

        try {
            SCXHandle<istream> reader = 
                    OpenConfigXml(configXml.Get());
            GetStringFromStream(reader, xml);

            XElementPtr domainNode;
            XElement::Load(xml, domainNode);
            
            if (domainNode->GetName() == WEBLOGIC_DOMAIN_XML_NODE)
            {
                string version;
                ReadConfigXmlForVersion(domainNode, version);
                
                string adminServerName;
                ReadConfigXmlForAdminServerName(domainNode, adminServerName);
                
                XElementList serverNodes;
                domainNode->GetChildren(serverNodes);
                for (size_t index = 0; index < serverNodes.size(); ++index)
                {
                    if (serverNodes[index]->GetName() == WEBLOGIC_SERVER_XML_NODE)
                    {
                        bool isAdminServer = false;
                        bool isSslEnabled = false;
                        string name = "";
                        string httpPort = "";
                        string httpsPort = "";

                        XElementList childNodes;
                        serverNodes[index]->GetChildren(childNodes);
                        for (size_t j = 0; j < childNodes.size(); ++j)
                        {
                            /*
                             *   <server>
                             *     <name>new_ManagedServer_1</name>
                             *     <ssl>
                             *       <name>new_ManagedServer_1</name>
                             *       <enabled>true</enabled>
                             *       <listen-port>7513</listen-port>
                             *     </ssl>
                             *     <machine>new_UnixMachine_1</machine>
                             *     <listen-port>7013</listen-port>
                             *     <listen-address/>
                             *   </server>
                             * 
                             */
                            if (childNodes[j]->GetName() == WEBLOGIC_NAME_XML_NODE)
                            {
                                name = childNodes[j]->GetContent();
                                isAdminServer = adminServerName == name;                                       
                            } 
                            else if (childNodes[j]->GetName() == WEBLOGIC_SSL_XML_NODE)
                            {
                                ReadConfigXmlForSslInformation(
                                        childNodes[j],
                                        isSslEnabled,
                                        httpsPort);                            } 
                            else if (childNodes[j]->GetName() == WEBLOGIC_LISTEN_PORT_XML_NODE)
                            {
                                httpPort = childNodes[j]->GetContent();
                            }                            
                        }
                        /*
                         * Having found the server node, 
                         * read the children
                         */
                        wstring wideName = StrFromUTF8(name);
                        SCXFilePath pathOnDisk;
                        pathOnDisk.SetDirectory(domainDir.Get());
                        pathOnDisk.AppendDirectory(WEBLOGIC_SERVERS_DIRECTORY);
                        pathOnDisk.AppendDirectory(wideName);

                        if (DoesServerDirectoryExist(pathOnDisk))
                        {
                            SCX_LOGTRACE(m_log, 
                                    wstring(L"WebLogicFileReader::ReadConfigXml() - ").
                                    append(L"Adding instance for ID='").append(pathOnDisk.Get()).
                                    append(L"'"));
                            // when the HTTP port is not set for the AdminServer,
                            // default to the default weblogic HTTP port (i.e. 7001)
                            wstring wideHttpPort = StrFromUTF8(httpPort);
                            if(isAdminServer && L"" == wideHttpPort)
                            {
                                wideHttpPort = DEFAULT_WEBLOGIC_HTTP_PORT;
                            }

                            // when the HTTPS port is not set, default to
                            // the default HTTPS port (i.e. 7002)
                            wstring wideHttpsPort = StrFromUTF8(httpsPort);
                            if(L"" == wideHttpsPort)
                            {
                                wideHttpsPort = DEFAULT_WEBLOGIC_HTTPS_PORT;
                            }
                        
                            wstring wideVersion = StrFromUTF8(version);
                        
                            SCXHandle<AppServerInstance> instance(
                                 new WebLogicAppServerInstance (
                                        pathOnDisk.GetDirectory()));
                        
                            instance->SetHttpPort(wideHttpPort);
                            instance->SetHttpsPort(wideHttpsPort);
                            instance->SetIsDeepMonitored(false, PROTOCOL_HTTPS);
                            instance->SetIsRunning(false);
                            instance->SetVersion(wideVersion);
                        
                            instance->SetServer(
                                    isAdminServer ?
                                            WEBLOGIC_SERVER_TYPE_ADMIN :
                                            WEBLOGIC_SERVER_TYPE_MANAGED);
                           
                            instances.push_back(instance);
                        }
                        else
                        {
                            SCX_LOGTRACE(m_log, 
                                    wstring(L"WebLogicFileReader::ReadConfigXml() - ").
                                    append(L"The directory (").append(pathOnDisk.Get()).
                                    append(L") does not exist on disk, ignoring this instance"));
                        }
                    }
                }
            }
        }
        catch (SCXFilePathNotFoundException&)
        {
            SCX_LOGERROR(m_log, 
                    wstring(L"WebLogicFileReader::ReadConfigXml() - ").
                    append(m_installationPath).append(L" - Could not find file: ").
                    append(configXml.Get()));
        }
        catch (SCXUnauthorizedFileSystemAccessException&)
        {
            SCX_LOGERROR(m_log, 
                    wstring(L"WebLogicFileReader::ReadConfigXml() - ").
                    append(m_installationPath).append(L" - not authorized to open file: ").
                    append(configXml.Get()));
        }
        catch (XmlException& x)
        {
            SCX_LOGERROR(m_log, 
                    wstring(L"WebLogicFileReader::ReadConfigXml() - ").
                    append(m_installationPath).append(L" - Could not load XML from file: ").
                    append(configXml.Get()));
        }
    }
示例#11
0
/**
   main function.

   \param argc size of \a argv[]
   \param argv array of string pointers from the command line.
   \returns 0 on success, otherwise, 1 on error.

   Usage: scxgencert [-d domain]  [-h hostname] [-g targetpath] [-e days] [-s days]
   \n -v             toggle the debug flag.
   \n -?             print the help message and exit.
   \n -g targetpath  target path where certificates should be written
   \n -s days        days to offset valid start date with
   \n -e days        days to offset valid end date with
   \n -d domain      domain name
   \n -h host        hostname
   \n -b bits        number of key bits (defaults to 2048)

   Result Code
   \n -1  an exception has occured
   \n  0  success
   \n >1  an error occured while executing the command.

*/
int main(int argc, char *argv[])
{
    // commandline switches
    const string helpFlag       ("-?");
    const string bitsFlag       ("-b");
    const string domainFlag     ("-d");
    const string enddaysFlag    ("-e");
    const string forceFlag      ("-f");
    const string generateFlag   ("-g");
    const string hostFlag       ("-h");
    const string startdaysFlag  ("-s");
    const string debugFlag      ("-v");
    const string testFlag       ("-t"); // Undocummented, for testing only

    // Control variables built from command line arguments (defaulted as needed by SCX)
    bool debugMode = false;
    bool testMode = false;
    bool doGenerateCert = false;
    wstring targetPath = L"/etc/opt/omi/ssl";
    int startDays = -365;
    int endDays = 7300;
#if defined(hpux) && defined(hppa)
    int bits = 1024;
#else
    int bits = 2048;
#endif

    SCXCoreLib::NameResolver mi;
    wstring hostname;
    wstring domainname;

    wstring specified_hostname;
    wstring specified_domainname;

    int i = 1;
    for (; i < argc; ++i)
    {
        if (debugFlag == argv[i])
        {
            debugMode = ! debugMode;
            wcout << L"Setting debugMode=" << (debugMode ? L"true" :L"false") << endl;
        }
        else if (helpFlag == argv[i])
        {
            usage(argv[0], 0);
        }
        else if (forceFlag == argv[i])
        {
            doGenerateCert = true;
        }
        else if(bitsFlag == argv[i])
        {
            if (++i >= argc)
            {
                wcout << L"Enter number of bits." << endl;
                usage(argv[0], 1);
            }
            bits = (int) SCXCoreLib::StrToLong(SCXCoreLib::StrFromUTF8(argv[i]));
            if (0 == bits || 0 != bits%512)
            {
                wcout << L"Bits must be non-zero dividable by 512." << endl;
                usage(argv[0], 1);
            }
        }
        else if(domainFlag == argv[i])
        {
            if (++i >= argc)
            {
                wcout << L"Enter a domain name." << endl;
                usage(argv[0], 1);
            }

            // Some platforms fail to convert if locale is not right (SLES 11 for instance).
            // Note we do not print domain name  because wcout will also fail to
            // properly convert, displaying a mangled string and further confusing
            // the user. Using cout is not an option because it will not print a
            // non-convertible string at all....
            try
            {
                specified_domainname = SCXCoreLib::StrFromMultibyte(argv[i], true);
            }
            catch(const SCXCoreLib::SCXStringConversionException &ex)
            {
                wcout << L"Not able to convert domain name. Consider adjusting your locale setting. Exiting." << endl;
                exit(3);
            }
        }
        else if(hostFlag == argv[i])
        {
            if (++i >= argc)
            {
                wcout << "Enter a hostname." << endl;
                usage(argv[0], 1);
            }

            // Host name is expected to be 7 bit so conversion is in most cases a no-op
            // If it fails prompt user and quit
            try
            {
                specified_hostname = SCXCoreLib::StrFromMultibyte(argv[i], true);
            }
            catch(const SCXCoreLib::SCXStringConversionException &e)
            {
                wcout << L"Not able to convert host name, \'" << argv[i] << "\'." << endl;
                wcout << L"Please specify a host name that uses only 7-bit ASCII characters." << endl;
                exit(4);
            }
        }
        else if (generateFlag == argv[i])
        {
            // Ensure the path argument exists.
            if (++i >= argc)
            {
                wcout << "Enter a target path to generate certificates." << endl;
                usage(argv[0], 1);
            }

            try
            {
                targetPath = SCXCoreLib::StrFromMultibyte(argv[i], true);
            }
            catch(SCXCoreLib::SCXStringConversionException)
            {
                wcout << L"Not able to convert target path, \'" << argv[i] << "\'." << endl;
                wcout << L"Consider adjusting your locale by changing the LC_CTYPE environment variable." << endl;
                exit(4);
            }
        }
        else if (startdaysFlag == argv[i])
        {
            // Ensure the value argument exists.
            if (++i >= argc)
            {
                wcout << "Enter a value for start days." << endl;
                usage(argv[0], 1);
            }
            startDays = (int) SCXCoreLib::StrToLong(SCXCoreLib::StrFromUTF8(argv[i]));
        }
        else if (enddaysFlag == argv[i])
        {
            // Ensure the value argument exists.
            if (++i >= argc || SCXCoreLib::StrToLong(SCXCoreLib::StrFromUTF8(argv[i])) == 0)
            {
                wcout << "Enter a non-zero value for end days." << endl;
                usage(argv[0], 1);
            }
            endDays = (int) SCXCoreLib::StrToLong(SCXCoreLib::StrFromUTF8(argv[i]));
        }
        else if (testFlag == argv[i])
        {
            testMode = true;
        }
        else
        {
            break;
        }
    }

    // Fail if all arguments are not used.
    if (i < argc) {
        wcout << L"Unused arguments:" << endl;
        for (; i < argc; ++i)
        {
            wcout << L"\t" << argv[i] << endl;
        }
        wcout << endl;
        usage(argv[0], 1);
    }

    hostname = specified_hostname;
    domainname = specified_domainname;

    if(hostname.empty())
    {
        std::string hostname_raw = "";
        try
        {
            // This can fail because there are string conversions done in GetHostname()
            hostname = mi.GetHostname(&hostname_raw);
        }
        catch(SCXCoreLib::SCXStringConversionException)
        {
            // Note: We should never see this because host names are s'pose to be 7 bit ASCII
            // Can get away with conversion of stdout here because we are dying, and can do it exactly once ...
            fwide(stdout, -1);
            cout << "Unable to convert default host name \'" << hostname_raw << "\'." << endl;
            cout << "This might be caused by a host name that contains UTF-8 characters that are invalid given your current locale." << endl;
            // MUST exit here, due to fwide() call above ... cannot call fwide() more than once w/out closing/reopening handle
            exit(3);
        }
        catch(SCXCoreLib::SCXErrnoERANGE_Exception &e)
        {
            cout << SCXCoreLib::StrToUTF8(e.Where()) << endl
                 << SCXCoreLib::StrToUTF8(e.What()) << endl;
            exit(3);
        }
    }

    // If the user did not supply a domain name, use default.
    if(domainname.empty())
    {
        domainname = mi.GetDomainname();
    }

    if(debugMode)
    {
        // Show what we would have used - even if user specified specific host/domain
        wcout << L"Generated hostname:   \"" << mi.GetHostname()
              << L"\" (" << mi.DumpSourceString(mi.GetHostnameSource()) << L")" << endl;
        wcout << L"Generated domainname: \"" << mi.GetDomainname()
              << L"\" (" << mi.DumpSourceString(mi.GetDomainnameSource()) << L")" << endl << endl;

        wcout << L"Using Host Name:     " << hostname << endl;
        wcout << L"Using Domain Name:   " << domainname << endl;
        wcout << L"Start Days:          " << startDays << endl;
        wcout << L"End Days:            " << endDays << endl;
        wcout << L"Cert Length:         " << bits << endl;
        wcout << L"Target Path:         " << targetPath << endl << endl;
    }

    // We only generate the certificate if "-f" was specified, or if no certificate exists
    // (Note: If no certificate exists, we should still return a success error code!)
    if (!doGenerateCert)
    {
        SCXFilePath keyPath;
        keyPath.SetDirectory(targetPath);
        keyPath.SetFilename(L"omikey.pem");

        SCXCoreLib::SCXFileInfo keyInfo(keyPath);
        if ( ! keyInfo.Exists() )
        {
            doGenerateCert = true;
        }
        else
        {
            wcerr << L"Certificate not generated - '" << keyPath.Get() << "' exists" << endl;
        }
    }

    int rc = 0;
    if (doGenerateCert)
    {
        rc = DoGenerate(targetPath, startDays, endDays, hostname, domainname, bits, debugMode);

        // When the domain or host name is specified through the command line we do not allow recovery.
        // Add an exception to this rule for testing purposes.
        if  ( (specified_domainname.empty() && specified_hostname.empty()) || testMode )
        {
            // When the domain or hostname is not RFC compliant, openssl fails to generate a cerificate.
            // We will try to fallback.
            if ( rc == ERROR_CERT_GENERATE )
            {
                wcout << "Hostname or domain likely not RFC compliant, trying fallback: \"localhost.local\"" << endl;
                rc = DoGenerate(targetPath, startDays, endDays, L"localhost", L"local", bits, debugMode);
            }
        }
    }

    if (debugMode)
    {
        wcout << L"return code = " << rc << endl;
    }
    exit(rc);
}
示例#12
0
/**
    Generate Key and Certificate
    \param[in] targetPath Path where the certificates should be written.
    \param[in] startDays Days to offset valid start date.
    \param[in] endDays Days to offset valid end date.
    \param[in] hostname Hostname to put into the certificate.
    \param[in] domainname Domainname to put into the certificate.
    \param[in] bits Number of bits in key.
    \returns Zero on success.
*/
static int DoGenerate(const wstring & targetPath, int startDays, int endDays,
                      const wstring & hostname, const wstring & domainname,
                      int bits, bool bDebug)
{
    // Output what we'll be using for certificate generation
    wcout << L"Generating certificate with hostname=\"" << hostname << L"\"";
    if (domainname.length())
    {
        wcout << L", domainname=\"" << domainname << L"\"" ;
    }
    wcout << endl;

    std::wstring c_certFilename(L"omi-host-");  // Remainder must be generated
    const std::wstring c_keyFilename(L"omikey.pem");

    int rc = 0;
    // Do not allow an exception to slip out
    try
    {
        // The certificate filename must be something like omi-host-<hostname>.pem; generate it
        c_certFilename.append(hostname);
        c_certFilename.append(L".pem");

        SCXFilePath keyPath;
        keyPath.SetDirectory(targetPath);
        keyPath.SetFilename(c_keyFilename);
        SCXFilePath certPath;
        certPath.SetDirectory(targetPath);
        certPath.SetFilename(c_certFilename);
        SCXSSLCertificateLocalizedDomain cert(keyPath, certPath, startDays, endDays, hostname, domainname, bits);

        std::ostringstream debugChatter;
        debugChatter << endl;

        try
        {
            cert.Generate(debugChatter);
        }
        catch(const SCXCoreLib::SCXStringConversionException &ex)
        {
            if(bDebug)
                wcout << debugChatter.str().c_str();

            wcerr  << endl << "Generation of certificate raised an exception" << endl;
            wcerr << ex.Where() << endl;
            wcerr << ex.What() << endl;

            return 2;
        }
        catch(const SCXSSLException &e_ssl)
        {
            if(bDebug)
            {
                wcout << debugChatter.str().c_str();
                debugChatter.str("");
            }

            wcerr << e_ssl.What() << endl;
            return ERROR_CERT_GENERATE;
        }
        catch(const SCXCoreLib::SCXFilePathNotFoundException &ex)
        {
            wcerr  << endl << "Generation of certificate raised an exception" << endl;
            wcerr  << "Output path \"" << ex.GetPath().Get() << "\" does not exist" << endl;
            return 4;
        }

        if(bDebug)
        {
            wcout << debugChatter.str().c_str();
        }

        /*
        ** We actually have three certificate files in total:
        **
        ** Certificate File: omi-host-<hostname>.pem  (public)
        ** Key File:         omi-key.pem              (private)
        ** Soft link:        omi.pem  (soft link to certificate file, used by openwsman)
        **
        **
        ** Create the soft link to point to the certificate file.
        */

        SCXFilePath fpLinkFile;
        fpLinkFile.SetDirectory(targetPath);
        fpLinkFile.SetFilename(L"omi.pem");

        std::string sLinkFile = SCXCoreLib::StrToMultibyte(fpLinkFile.Get());
        std::string sCertFile = SCXCoreLib::StrToMultibyte(certPath.Get());

        rc = unlink(sLinkFile.c_str());
        if (0 != rc && ENOENT != errno) {
            throw SCXCoreLib::SCXErrnoFileException(L"unlink", fpLinkFile.Get(), errno, SCXSRCLOCATION);
        }

        rc = symlink(sCertFile.c_str(), sLinkFile.c_str());
        if (0 != rc) {
            throw SCXCoreLib::SCXErrnoFileException(L"unlink", fpLinkFile.Get(), errno, SCXSRCLOCATION);
        }

        /*
        ** Finally, make sure the permissions are right:
        ** The pub key gets 444, the priv key gets 400
        */

        rc = chmod(sCertFile.c_str(), 00444);
        if (0 != rc) {
            throw SCXCoreLib::SCXErrnoFileException(L"chmod", certPath.Get(), errno, SCXSRCLOCATION);
        }

        std::string sKeyFile = SCXCoreLib::StrToMultibyte(keyPath.Get());
        rc = chmod(sKeyFile.c_str(), 00400);
        if (0 != rc) {
            throw SCXCoreLib::SCXErrnoFileException(L"chmod", keyPath.Get(), errno, SCXSRCLOCATION);
        }
    }
    catch(const SCXCoreLib::SCXException & e)
    {
        wcout << e.Where() << endl
              << e.What() << endl;
        // use -1 to indicate an exception occured.
        rc = -1;
    }
    return rc;
}