2017-05-24 03:52:24 -05:00
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License , v . 2.0 . If a copy of the MPL was not distributed with this
* file , You can obtain one at http : //mozilla.org/MPL/2.0/.
*/
2017-12-20 07:06:26 -06:00
# include <config.h>
2017-05-24 03:52:24 -05:00
# include <iostream>
# include <iomanip>
2023-07-06 14:51:58 -05:00
# include <pwd.h>
2017-08-30 06:49:50 -05:00
# include <sstream>
2023-07-06 14:51:58 -05:00
# include <sys/stat.h>
# include <sys/types.h>
2019-11-06 03:07:32 -06:00
# include <sysexits.h>
2017-05-24 03:52:24 -05:00
# include <termios.h>
2019-11-26 07:15:38 -06:00
# include <unistd.h>
2017-05-24 03:52:24 -05:00
# include <openssl/rand.h>
# include <openssl/evp.h>
2023-07-06 14:51:58 -05:00
# include <Poco/Crypto/RSAKey.h>
2017-05-24 03:52:24 -05:00
# include <Poco/Exception.h>
2022-01-08 10:38:21 -06:00
# include <Poco/File.h>
2017-05-24 03:52:24 -05:00
# include <Poco/Util/Application.h>
2017-08-30 22:54:05 -05:00
# include <Poco/Util/HelpFormatter.h>
2017-05-24 03:52:24 -05:00
# include <Poco/Util/Option.h>
# include <Poco/Util/OptionSet.h>
# include <Poco/Util/XMLConfiguration.h>
2017-12-20 07:06:26 -06:00
# include <Util.hpp>
# include <Crypto.hpp>
2017-05-24 03:52:24 -05:00
using Poco : : Util : : Application ;
2017-08-30 22:54:05 -05:00
using Poco : : Util : : HelpFormatter ;
2017-05-24 03:52:24 -05:00
using Poco : : Util : : Option ;
using Poco : : Util : : OptionSet ;
using Poco : : Util : : XMLConfiguration ;
# define MIN_PWD_SALT_LENGTH 20
# define MIN_PWD_ITERATIONS 1000
# define MIN_PWD_HASH_LENGTH 20
2021-11-15 07:47:53 -06:00
class CoolConfig final : public XMLConfiguration
2017-05-24 03:52:24 -05:00
{
public :
2021-11-15 07:47:53 -06:00
CoolConfig ( )
2017-05-24 03:52:24 -05:00
{ }
} ;
struct AdminConfig
{
2019-01-17 01:46:01 -06:00
private :
2019-01-16 01:59:45 -06:00
unsigned _pwdSaltLength = 128 ;
unsigned _pwdIterations = 10000 ;
unsigned _pwdHashLength = 128 ;
public :
void setPwdSaltLength ( unsigned pwdSaltLength ) { _pwdSaltLength = pwdSaltLength ; }
unsigned getPwdSaltLength ( ) const { return _pwdSaltLength ; }
void setPwdIterations ( unsigned pwdIterations ) { _pwdIterations = pwdIterations ; }
unsigned getPwdIterations ( ) const { return _pwdIterations ; }
void setPwdHashLength ( unsigned pwdHashLength ) { _pwdHashLength = pwdHashLength ; }
unsigned getPwdHashLength ( ) const { return _pwdHashLength ; }
2017-05-24 03:52:24 -05:00
} ;
2021-11-18 06:08:14 -06:00
// Config tool to change coolwsd configuration (coolwsd.xml)
2017-05-24 03:52:24 -05:00
class Config : public Application
{
// Display help information on the console
void displayHelp ( ) ;
2021-11-15 07:47:53 -06:00
CoolConfig _coolConfig ;
2017-05-24 03:52:24 -05:00
AdminConfig _adminConfig ;
public :
static std : : string ConfigFile ;
2022-01-08 10:38:21 -06:00
static std : : string OldConfigFile ;
2017-10-03 14:48:28 -05:00
static std : : string SupportKeyString ;
static bool SupportKeyStringProvided ;
2019-03-31 23:13:03 -05:00
static std : : uint64_t AnonymizationSalt ;
static bool AnonymizationSaltProvided ;
2022-01-08 10:38:21 -06:00
static bool Write ;
2017-05-24 03:52:24 -05:00
protected :
void defineOptions ( OptionSet & ) override ;
void handleOption ( const std : : string & , const std : : string & ) override ;
int main ( const std : : vector < std : : string > & ) override ;
} ;
2018-01-26 06:59:12 -06:00
std : : string Config : : ConfigFile =
# if ENABLE_DEBUG
DEBUG_ABSSRCDIR
# else
2021-11-18 06:08:14 -06:00
COOLWSD_CONFIGDIR
2018-01-26 06:59:12 -06:00
# endif
2021-11-18 06:08:14 -06:00
" /coolwsd.xml " ;
2018-01-26 06:59:12 -06:00
2022-01-08 10:38:21 -06:00
std : : string Config : : OldConfigFile = " /etc/loolwsd/loolwsd.xml " ;
bool Config : : Write = false ;
2017-10-17 02:04:04 -05:00
std : : string Config : : SupportKeyString ;
2017-10-03 14:48:28 -05:00
bool Config : : SupportKeyStringProvided = false ;
2019-03-31 23:13:03 -05:00
std : : uint64_t Config : : AnonymizationSalt = 0 ;
bool Config : : AnonymizationSaltProvided = false ;
2017-05-24 03:52:24 -05:00
2022-01-08 10:38:21 -06:00
int MigrateConfig ( std : : string , std : : string , bool ) ;
2017-05-24 03:52:24 -05:00
void Config : : displayHelp ( )
{
2017-08-30 22:54:05 -05:00
HelpFormatter helpFormatter ( options ( ) ) ;
helpFormatter . setCommand ( commandName ( ) ) ;
2018-01-26 06:59:12 -06:00
helpFormatter . setUsage ( " COMMAND [OPTIONS] " ) ;
2021-11-15 07:47:53 -06:00
helpFormatter . setHeader ( " coolconfig - Configuration tool for Collabora Online. \n "
2017-10-03 14:48:28 -05:00
" \n "
2018-01-26 06:59:12 -06:00
" Some options make sense only with a specific command. \n \n "
" Options: " ) ;
2017-10-03 14:48:28 -05:00
helpFormatter . format ( std : : cout ) ;
2018-01-26 06:59:12 -06:00
// Command list
std : : cout < < std : : endl
< < " Commands: " < < std : : endl
2022-01-08 10:38:21 -06:00
< < " migrateconfig [--old-config-file=<path>] [--config-file=<path>] [--write] " < < std : : endl
2019-03-31 23:13:03 -05:00
< < " anonymize [string-1]...[string-n] " < < std : : endl
2018-03-15 04:39:09 -05:00
< < " set-admin-password " < < std : : endl
2018-01-26 06:59:12 -06:00
# if ENABLE_SUPPORT_KEY
2018-03-15 04:39:09 -05:00
< < " set-support-key " < < std : : endl
2018-01-26 06:59:12 -06:00
# endif
2018-03-15 04:39:09 -05:00
< < " set <key> <value> " < < std : : endl
2023-07-06 14:51:58 -05:00
< < " generate-proof-key " < < std : : endl
2018-03-15 04:39:09 -05:00
< < " update-system-template " < < std : : endl < < std : : endl ;
2017-05-24 03:52:24 -05:00
}
void Config : : defineOptions ( OptionSet & optionSet )
{
Application : : defineOptions ( optionSet ) ;
2017-10-03 14:48:28 -05:00
optionSet . addOption ( Option ( " help " , " h " , " Show this usage information. " )
2017-05-24 03:52:24 -05:00
. required ( false )
. repeatable ( false ) ) ;
2017-08-30 22:54:05 -05:00
optionSet . addOption ( Option ( " config-file " , " " , " Specify configuration file path manually. " )
. required ( false )
. repeatable ( false )
. argument ( " path " ) ) ;
2022-01-08 10:38:21 -06:00
optionSet . addOption ( Option ( " old-config-file " , " " , " Specify configuration file path to migrate manually. " )
. required ( false )
. repeatable ( false )
. argument ( " path " ) ) ;
2017-08-30 22:54:05 -05:00
2017-10-03 14:48:28 -05:00
optionSet . addOption ( Option ( " pwd-salt-length " , " " , " Length of the salt to use to hash password [set-admin-password]. " )
2017-05-24 03:52:24 -05:00
. required ( false )
2022-01-08 10:38:21 -06:00
. repeatable ( false )
. argument ( " number " ) ) ;
2017-10-03 14:48:28 -05:00
optionSet . addOption ( Option ( " pwd-iterations " , " " , " Number of iterations to do in PKDBF2 password hashing [set-admin-password]. " )
2017-05-24 03:52:24 -05:00
. required ( false )
. repeatable ( false )
. argument ( " number " ) ) ;
2017-10-03 14:48:28 -05:00
optionSet . addOption ( Option ( " pwd-hash-length " , " " , " Length of password hash to generate [set-admin-password]. " )
2017-05-24 03:52:24 -05:00
. required ( false )
. repeatable ( false )
. argument ( " number " ) ) ;
2017-08-30 22:54:05 -05:00
2017-10-12 14:40:55 -05:00
# if ENABLE_SUPPORT_KEY
2017-10-03 14:48:28 -05:00
optionSet . addOption ( Option ( " support-key " , " " , " Specify the support key [set-support-key]. " )
. required ( false )
. repeatable ( false )
. argument ( " key " ) ) ;
2017-10-12 14:40:55 -05:00
# endif
2019-03-31 23:13:03 -05:00
optionSet . addOption ( Option ( " anonymization-salt " , " " , " Anonymize strings with the given 64-bit salt instead of the one in the config file. " )
. required ( false )
. repeatable ( false )
. argument ( " salt " ) ) ;
2022-01-08 10:38:21 -06:00
optionSet . addOption ( Option ( " write " , " " , " Write migrated configuration. " )
. required ( false )
. repeatable ( false ) ) ;
2017-05-24 03:52:24 -05:00
}
void Config : : handleOption ( const std : : string & optionName , const std : : string & optionValue )
{
Application : : handleOption ( optionName , optionValue ) ;
if ( optionName = = " help " )
{
displayHelp ( ) ;
2022-07-15 22:18:48 -05:00
Util : : forcedExit ( EX_OK ) ;
2017-05-24 03:52:24 -05:00
}
else if ( optionName = = " config-file " )
{
ConfigFile = optionValue ;
}
2022-01-08 10:38:21 -06:00
else if ( optionName = = " old-config-file " )
{
OldConfigFile = optionValue ;
}
2017-05-24 03:52:24 -05:00
else if ( optionName = = " pwd-salt-length " )
{
unsigned len = std : : stoi ( optionValue ) ;
if ( len < MIN_PWD_SALT_LENGTH )
{
len = MIN_PWD_SALT_LENGTH ;
std : : cout < < " Password salt length adjusted to minimum " < < len < < std : : endl ;
}
2019-01-16 01:59:45 -06:00
_adminConfig . setPwdSaltLength ( len ) ;
2017-05-24 03:52:24 -05:00
}
else if ( optionName = = " pwd-iterations " )
{
unsigned len = std : : stoi ( optionValue ) ;
if ( len < MIN_PWD_ITERATIONS )
{
len = MIN_PWD_ITERATIONS ;
std : : cout < < " Password iteration adjusted to minimum " < < len < < std : : endl ;
}
2019-01-16 01:59:45 -06:00
_adminConfig . setPwdIterations ( len ) ;
2017-05-24 03:52:24 -05:00
}
else if ( optionName = = " pwd-hash-length " )
{
unsigned len = std : : stoi ( optionValue ) ;
if ( len < MIN_PWD_HASH_LENGTH )
{
len = MIN_PWD_HASH_LENGTH ;
std : : cout < < " Password hash length adjusted to minimum " < < len < < std : : endl ;
}
2019-01-16 01:59:45 -06:00
_adminConfig . setPwdHashLength ( len ) ;
2017-05-24 03:52:24 -05:00
}
2017-10-03 14:48:28 -05:00
else if ( optionName = = " support-key " )
{
SupportKeyString = optionValue ;
SupportKeyStringProvided = true ;
}
2019-03-31 23:13:03 -05:00
else if ( optionName = = " anonymization-salt " )
{
AnonymizationSalt = std : : stoull ( optionValue ) ;
AnonymizationSaltProvided = true ;
std : : cout < < " Anonymization Salt: [ " < < AnonymizationSalt < < " ]. " < < std : : endl ;
}
2022-01-08 10:38:21 -06:00
else if ( optionName = = " write " )
{
Write = true ;
}
2017-05-24 03:52:24 -05:00
}
2023-08-23 06:35:46 -05:00
// coverity[root_function] : don't warn about uncaught exceptions
2017-05-24 03:52:24 -05:00
int Config : : main ( const std : : vector < std : : string > & args )
{
if ( args . empty ( ) )
{
std : : cerr < < " Nothing to do. " < < std : : endl ;
displayHelp ( ) ;
2019-11-06 03:07:32 -06:00
return EX_NOINPUT ;
2017-05-24 03:52:24 -05:00
}
2019-11-06 03:07:32 -06:00
int retval = EX_OK ;
2017-07-21 09:33:19 -05:00
bool changed = false ;
2021-11-15 07:47:53 -06:00
_coolConfig . load ( ConfigFile ) ;
2017-05-24 03:52:24 -05:00
2018-01-26 06:59:12 -06:00
if ( args [ 0 ] = = " set-admin-password " )
2017-07-21 09:33:19 -05:00
{
# if HAVE_PKCS5_PBKDF2_HMAC
2022-07-09 22:49:15 -05:00
std : : vector < unsigned char > pwdhash ( _adminConfig . getPwdHashLength ( ) ) ;
std : : vector < unsigned char > salt ( _adminConfig . getPwdSaltLength ( ) ) ;
RAND_bytes ( salt . data ( ) , _adminConfig . getPwdSaltLength ( ) ) ;
2018-01-26 06:59:12 -06:00
std : : stringstream stream ;
2018-11-13 07:32:37 -06:00
// Ask for admin username
std : : string adminUser ;
std : : cout < < " Enter admin username [admin]: " ;
std : : getline ( std : : cin , adminUser ) ;
if ( adminUser . empty ( ) )
{
adminUser = " admin " ;
}
2018-01-26 06:59:12 -06:00
// Ask for user password
termios oldTermios ;
tcgetattr ( STDIN_FILENO , & oldTermios ) ;
termios newTermios = oldTermios ;
// Disable user input mirroring on console for password input
newTermios . c_lflag & = ~ ECHO ;
tcsetattr ( STDIN_FILENO , TCSANOW , & newTermios ) ;
std : : string adminPwd ;
std : : cout < < " Enter admin password: " ;
std : : getline ( std : : cin , adminPwd ) ;
std : : string reAdminPwd ;
std : : cout < < std : : endl < < " Confirm admin password: " ;
std : : getline ( std : : cin , reAdminPwd ) ;
std : : cout < < std : : endl ;
// Set the termios to old state
tcsetattr ( STDIN_FILENO , TCSANOW , & oldTermios ) ;
if ( adminPwd ! = reAdminPwd )
{
std : : cout < < " Password mismatch. " < < std : : endl ;
2019-11-06 03:07:32 -06:00
return EX_DATAERR ;
2018-01-26 06:59:12 -06:00
}
2017-05-24 03:52:24 -05:00
2018-01-26 06:59:12 -06:00
// Do the magic !
PKCS5_PBKDF2_HMAC ( adminPwd . c_str ( ) , - 1 ,
2022-07-09 22:49:15 -05:00
salt . data ( ) , _adminConfig . getPwdSaltLength ( ) ,
2019-01-16 01:59:45 -06:00
_adminConfig . getPwdIterations ( ) ,
2018-01-26 06:59:12 -06:00
EVP_sha512 ( ) ,
2022-07-09 22:49:15 -05:00
_adminConfig . getPwdHashLength ( ) , pwdhash . data ( ) ) ;
2018-01-26 06:59:12 -06:00
// Make salt randomness readable
2019-01-16 01:59:45 -06:00
for ( unsigned j = 0 ; j < _adminConfig . getPwdSaltLength ( ) ; + + j )
2018-01-26 06:59:12 -06:00
stream < < std : : hex < < std : : setw ( 2 ) < < std : : setfill ( ' 0 ' ) < < static_cast < int > ( salt [ j ] ) ;
const std : : string saltHash = stream . str ( ) ;
// Clear our used hex stream to make space for password hash
stream . str ( " " ) ;
stream . clear ( ) ;
// Make the hashed password readable
2019-01-16 01:59:45 -06:00
for ( unsigned j = 0 ; j < _adminConfig . getPwdHashLength ( ) ; + + j )
2018-01-26 06:59:12 -06:00
stream < < std : : hex < < std : : setw ( 2 ) < < std : : setfill ( ' 0 ' ) < < static_cast < int > ( pwdhash [ j ] ) ;
const std : : string passwordHash = stream . str ( ) ;
std : : stringstream pwdConfigValue ( " pbkdf2.sha512. " , std : : ios_base : : in | std : : ios_base : : out | std : : ios_base : : ate ) ;
2020-05-24 08:10:18 -05:00
pwdConfigValue < < std : : to_string ( _adminConfig . getPwdIterations ( ) ) < < ' . ' ;
pwdConfigValue < < saltHash < < ' . ' < < passwordHash ;
2021-11-15 07:47:53 -06:00
_coolConfig . setString ( " admin_console.username " , adminUser ) ;
_coolConfig . setString ( " admin_console.secure_password[@desc] " ,
2018-01-26 06:59:12 -06:00
" Salt and password hash combination generated using PBKDF2 with SHA512 digest. " ) ;
2021-11-15 07:47:53 -06:00
_coolConfig . setString ( " admin_console.secure_password " , pwdConfigValue . str ( ) ) ;
2018-01-26 06:59:12 -06:00
changed = true ;
2017-07-21 09:33:19 -05:00
# else
2021-11-18 06:08:14 -06:00
std : : cerr < < " This application was compiled with old OpenSSL. Operation not supported. You can use plain text password in /etc/coolwsd/coolwsd.xml. " < < std : : endl ;
2019-11-06 03:07:32 -06:00
return EX_UNAVAILABLE ;
2017-07-21 09:33:19 -05:00
# endif
2018-01-26 06:59:12 -06:00
}
2017-07-21 09:33:19 -05:00
# if ENABLE_SUPPORT_KEY
2018-01-26 06:59:12 -06:00
else if ( args [ 0 ] = = " set-support-key " )
{
std : : string supportKeyString ;
if ( SupportKeyStringProvided )
supportKeyString = SupportKeyString ;
else
2017-07-21 09:33:19 -05:00
{
2018-01-26 06:59:12 -06:00
std : : cout < < " Enter support key: " ;
std : : getline ( std : : cin , supportKeyString ) ;
}
2017-10-03 14:48:28 -05:00
2018-01-26 06:59:12 -06:00
if ( ! supportKeyString . empty ( ) )
{
SupportKey key ( supportKeyString ) ;
if ( ! key . verify ( ) )
std : : cerr < < " Invalid key \n " ;
else {
int validDays = key . validDaysRemaining ( ) ;
if ( validDays < = 0 )
std : : cerr < < " Valid but expired key \n " ;
else
{
std : : cerr < < " Valid for " < < validDays < < " days - setting to config \n " ;
2021-11-15 07:47:53 -06:00
_coolConfig . setString ( " support_key " , supportKeyString ) ;
2019-01-09 03:28:25 -06:00
changed = true ;
2017-07-21 09:33:19 -05:00
}
}
2018-01-26 06:59:12 -06:00
}
else
{
std : : cerr < < " Removing empty support key \n " ;
2021-11-15 07:47:53 -06:00
_coolConfig . remove ( " support_key " ) ;
2019-01-09 03:28:25 -06:00
changed = true ;
2018-01-26 06:59:12 -06:00
}
}
# endif
2018-02-13 01:03:01 -06:00
else if ( args [ 0 ] = = " set " )
2018-01-26 06:59:12 -06:00
{
if ( args . size ( ) = = 3 )
{
// args[1] = key
// args[2] = value
2021-11-15 07:47:53 -06:00
if ( _coolConfig . has ( args [ 1 ] ) )
2017-07-21 09:33:19 -05:00
{
2021-11-15 07:47:53 -06:00
const std : : string val = _coolConfig . getString ( args [ 1 ] ) ;
2020-05-24 08:10:18 -05:00
std : : cout < < " Previous value found in config file: \" " < < val < < ' " ' < < std : : endl ;
std : : cout < < " Changing value to: \" " < < args [ 2 ] < < ' " ' < < std : : endl ;
2017-07-21 09:33:19 -05:00
}
2018-01-26 06:59:12 -06:00
else
2022-01-14 12:24:40 -06:00
{
std : : cout < < " No property, \" " < < args [ 1 ] < < " \" , " < < " found in config file. " < < std : : endl ;
std : : cout < < " Adding it as new with value: \" " < < args [ 2 ] < < ' " ' < < std : : endl ;
}
_coolConfig . setString ( args [ 1 ] , args [ 2 ] ) ;
changed = true ;
2017-07-21 09:33:19 -05:00
}
2018-01-26 06:59:12 -06:00
else
2018-02-13 01:03:01 -06:00
std : : cerr < < " set expects a key and value as arguments " < < std : : endl
2018-01-26 06:59:12 -06:00
< < " Eg: " < < std : : endl
2018-02-13 01:03:01 -06:00
< < " set logging.level trace " < < std : : endl ;
2018-01-26 06:59:12 -06:00
2017-07-21 09:33:19 -05:00
}
2018-03-15 04:39:09 -05:00
else if ( args [ 0 ] = = " update-system-template " )
{
2021-11-17 15:09:50 -06:00
const char command [ ] = " coolwsd-systemplate-setup /opt/cool/systemplate " LO_PATH " >/dev/null 2>&1 " ;
2018-03-15 04:39:09 -05:00
std : : cout < < " Running the following command: " < < std : : endl
< < command < < std : : endl ;
2018-03-27 07:35:19 -05:00
2018-03-28 02:26:56 -05:00
retval = system ( command ) ;
2018-03-27 07:35:19 -05:00
if ( retval ! = 0 )
std : : cerr < < " Error when executing command. " < < std : : endl ;
2018-03-15 04:39:09 -05:00
}
2019-03-31 23:13:03 -05:00
else if ( args [ 0 ] = = " anonymize " )
{
if ( ! AnonymizationSaltProvided )
{
2021-11-15 07:47:53 -06:00
const std : : string val = _coolConfig . getString ( " logging.anonymize.anonymization_salt " ) ;
2019-03-31 23:13:03 -05:00
AnonymizationSalt = std : : stoull ( val ) ;
std : : cout < < " Anonymization Salt: [ " < < AnonymizationSalt < < " ]. " < < std : : endl ;
}
for ( std : : size_t i = 1 ; i < args . size ( ) ; + + i )
{
2020-12-06 22:01:18 -06:00
std : : cout < < ' [ ' < < args [ i ] < < " ]: " < < Util : : anonymizeUrl ( args [ i ] , AnonymizationSalt ) < < std : : endl ;
2019-03-31 23:13:03 -05:00
}
}
2022-01-08 10:38:21 -06:00
else if ( args [ 0 ] = = " migrateconfig " )
{
std : : cout < < " Migrating old configuration from " < < OldConfigFile < < " to " < < ConfigFile < < " . " < < std : : endl ;
if ( ! Write )
std : : cout < < " This is a dry run, no changes are written to file. " < < std : : endl ;
std : : cout < < std : : endl ;
const std : : string OldConfigMigrated = OldConfigFile + " .migrated " ;
Poco : : File AlreadyMigrated ( OldConfigMigrated ) ;
if ( AlreadyMigrated . exists ( ) )
{
std : : cout < < " Migration already performed, file " + OldConfigMigrated + " exists. Aborting. " < < std : : endl ;
}
else
{
const int Result = MigrateConfig ( OldConfigFile , ConfigFile , Write ) ;
if ( Result = = 0 )
{
std : : cout < < " Successful migration. " < < std : : endl ;
if ( Write )
{
Poco : : File ConfigToRename ( OldConfigFile ) ;
ConfigToRename . renameTo ( OldConfigMigrated ) ;
}
}
else
std : : cout < < " Migration of old configuration failed. " < < std : : endl ;
}
}
2023-07-06 14:51:58 -05:00
else if ( args [ 0 ] = = " generate-proof-key " )
{
std : : string proofKeyPath =
# if ENABLE_DEBUG
DEBUG_ABSSRCDIR
# else
COOLWSD_CONFIGDIR
# endif
" /proof_key " ;
# if !ENABLE_DEBUG
struct passwd * pwd ;
pwd = getpwnam ( COOL_USER_ID ) ;
if ( pwd = = NULL )
{
std : : cerr < < " User ' " COOL_USER_ID
" ' does not exist. Please reinstall coolwsd package, or in case of manual "
" installation from source, create the ' " COOL_USER_ID " ' user manually. "
< < std : : endl ;
return EX_NOUSER ;
}
# endif
Poco : : File proofKeyFile ( proofKeyPath ) ;
if ( ! proofKeyFile . exists ( ) )
{
Poco : : Crypto : : RSAKey proofKey =
Poco : : Crypto : : RSAKey ( Poco : : Crypto : : RSAKey : : KeyLength : : KL_2048 ,
Poco : : Crypto : : RSAKey : : Exponent : : EXP_LARGE ) ;
proofKey . save ( proofKeyPath + " .pub " , proofKeyPath , " " /*no password*/ ) ;
# if !ENABLE_DEBUG
chmod ( proofKeyPath . c_str ( ) , S_IRUSR | S_IWUSR ) ;
2023-07-22 22:20:58 -05:00
const int ChResult = chown ( proofKeyPath . c_str ( ) , pwd - > pw_uid , - 1 ) ;
if ( ChResult ! = 0 )
std : : cerr < < " Changing owner of " + proofKeyPath + " failed. " < < std : : endl ;
2023-07-06 14:51:58 -05:00
# endif
}
else
{
std : : cerr < < proofKeyPath < < " exists already. New proof key was not generated. "
< < std : : endl ;
}
}
2018-01-26 06:59:12 -06:00
else
{
2020-05-24 08:10:18 -05:00
std : : cerr < < " No such command, \" " < < args [ 0 ] < < ' " ' < < std : : endl ;
2018-01-26 06:59:12 -06:00
displayHelp ( ) ;
}
2017-07-21 09:33:19 -05:00
if ( changed )
{
std : : cout < < " Saving configuration to : " < < ConfigFile < < " ... " < < std : : endl ;
2021-11-15 07:47:53 -06:00
_coolConfig . save ( ConfigFile ) ;
2017-07-21 09:33:19 -05:00
std : : cout < < " Saved " < < std : : endl ;
2017-05-24 03:52:24 -05:00
}
2018-03-28 02:26:56 -05:00
return retval ;
2017-05-24 03:52:24 -05:00
}
2023-08-23 06:35:46 -05:00
// coverity[root_function] : don't warn about uncaught exceptions
2017-05-24 03:52:24 -05:00
POCO_APP_MAIN ( Config ) ;
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */