2022-08-29 00:26:46 +03:00
< ? php
require 'vendor/autoload.php' ;
2023-03-31 19:43:21 +03:00
function checkDNS ( $domain , $withWww = false )
2022-08-29 00:26:46 +03:00
{
if ( ! preg_match ( '/(?=^.{4,253}$)(^((?!-)[a-zA-Z0-9-]{0,62}[a-zA-Z0-9]\.)+[a-zA-Z]{2,63}$)/' , strtolower ( $domain ))) {
throw new Exception ( 'not valid domain : "' . $domain . '".' );
}
$currentip = dns_get_record ( $domain , DNS_A + DNS_AAAA );
if ( empty ( $currentip )) {
throw new Exception ( 'the domain ' . $domain . ' was not found in DNS record.' );
}
if ( $currentip [ 0 ][ 'ip' ] !== $_SERVER [ 'ip4' ]) {
throw new Exception ( 'the current ip v4 address of ' . $domain . ' is ' . $currentip [ 0 ][ 'ip' ] . '. it should be ' . $_SERVER [ 'ip4' ]);
}
if ( $currentip [ 1 ][ 'ipv6' ] !== $_SERVER [ 'ip6' ]) {
throw new Exception ( 'the current ip v6 address of ' . $domain . ' is ' . $currentip [ 1 ][ 'ipv6' ] . '. it should be ' . $_SERVER [ 'ip6' ]);
}
2023-03-31 19:43:21 +03:00
if ( $withWww ) {
$dnsentries = dns_get_record ( 'www.' . $domain , DNS_A + DNS_AAAA + DNS_CNAME );
$foundCnameEntry = false ;
$foundIp4 = false ;
$foundIp6 = false ;
foreach ( $dnsentries as $key => $row ) {
if ( $row [ 'host' ] == 'www.' . $domain && $row [ 'type' ] == 'CNAME' && $row [ 'target' ] == $domain ) {
$foundCnameEntry = true ;
}
if ( $row [ 'host' ] == 'www.' . $domain && $row [ 'type' ] == 'A' && $row [ 'ip' ] == $_SERVER [ 'ip4' ]) {
$foundIp4 = true ;
}
if ( $row [ 'host' ] == 'www.' . $domain && $row [ 'type' ] == 'AAAA' && $row [ 'ipv6' ] == $_SERVER [ 'ip6' ]) {
$foundIp6 = true ;
}
}
if ( ! $foundCnameEntry ) {
if ( ! $foundIp4 && ! $foundIp6 ) {
throw new Exception ( 'the domain www.' . $domain . ' was not found in DNS record as a CNAME targeting ' . $domain . " \n " . ' or A entry to ' . $_SERVER [ 'ip4' ] . ' and a AAAA entry to ' . $_SERVER [ 'ip6' ] . '.' );
}
}
}
2022-08-29 00:26:46 +03:00
return true ;
}
function checkIfInstalled ( $domain )
{
exec ( 'find /home/* -maxdepth 1 -type d | grep ' . $domain , $output );
if ( ! empty ( $output )) {
throw new Exception ( 'the domain ' . $domain . ' was already found on the server.' );
}
}
function checkIfUserExist ( $user )
{
exec ( 'cut -d: -f1 /etc/passwd | grep ' . $user , $output );
return ! empty ( $output );
}
function generateUserFromDomain ( $domain , $recursive = null )
{
if ( $recursive == 100 ) {
throw new Exception ( 'Too much users found, 100 that is too much for ' . $domain );
}
2022-09-06 13:38:00 +03:00
$user = str_split ( str_replace ([ $_SERVER [ 'maindomain' ], '-' , '.' ], '' , $domain ), 30 )[ 0 ] . $recursive ;
2022-08-29 00:26:46 +03:00
// try anthor username if user exists or if reserved name
2022-09-06 13:38:00 +03:00
if ( checkIfUserExist ( $user ) || in_array ( $user , explode ( ',' , $_SERVER [ 'reservedsubdomains' ]))) {
2022-08-29 00:26:46 +03:00
if ( $recursive === null ) {
$recursive = 1 ;
}
$user = generateUserFromDomain ( $domain , $recursive + 1 );
}
return $user ;
}
function findUserFromExistingDomain ( $domain )
{
exec ( 'find /home/* -maxdepth 1 -type d | grep ' . $domain , $output );
if ( empty ( $output )) {
throw new Exception ( 'the domain ' . $domain . ' was not found on the server.' );
} else {
return str_replace ([ '/home/' , '/' . $domain ], '' , $output [ 0 ]);
}
}
function generatePassword ( $length = 32 , $add_dashes = false , $available_sets = 'luds' )
{
$sets = array ();
if ( strpos ( $available_sets , 'l' ) !== false ) {
$sets [] = 'abcdefghjkmnpqrstuvwxyz' ;
}
if ( strpos ( $available_sets , 'u' ) !== false ) {
$sets [] = 'ABCDEFGHJKMNPQRSTUVWXYZ' ;
}
if ( strpos ( $available_sets , 'd' ) !== false ) {
$sets [] = '23456789' ;
}
if ( strpos ( $available_sets , 's' ) !== false ) {
2023-02-03 21:36:26 +03:00
$sets [] = ';-().!?' ;
2022-08-29 00:26:46 +03:00
}
$all = '' ;
$password = '' ;
foreach ( $sets as $set ) {
$password .= $set [ array_rand ( str_split ( $set ))];
$all .= $set ;
}
$all = str_split ( $all );
for ( $i = 0 ; $i < $length - count ( $sets ); $i ++ ) {
$password .= $all [ array_rand ( $all )];
}
$password = str_shuffle ( $password );
if ( ! $add_dashes ) {
return $password ;
}
$dash_len = floor ( sqrt ( $length ));
$dash_str = '' ;
while ( strlen ( $password ) > $dash_len ) {
$dash_str .= substr ( $password , 0 , $dash_len ) . '-' ;
$password = substr ( $password , $dash_len );
}
$dash_str .= $password ;
return $dash_str ;
}
2022-09-06 13:38:00 +03:00
function createSQLUserAndDatabase ( $user , $type )
2022-08-29 00:26:46 +03:00
{
$pass = generatePassword ();
2022-09-06 13:38:00 +03:00
exec ( 'mysql -u ' . $_SERVER [ 'mysqluser' ] . ' -p\'' . $_SERVER [ 'mysqlpassword' ] . '\' -e \'CREATE DATABASE IF NOT EXISTS ' . $user . ';\'' , $output );
exec ( 'mysql -u ' . $_SERVER [ 'mysqluser' ] . ' -p\'' . $_SERVER [ 'mysqlpassword' ] . '\' -e "CREATE USER IF NOT EXISTS \'' . $user . '\'@\'localhost\' IDENTIFIED BY \'' . $pass . '\';"' , $output );
exec ( 'mysql -u ' . $_SERVER [ 'mysqluser' ] . ' -p\'' . $_SERVER [ 'mysqlpassword' ] . '\' -e "GRANT ALL PRIVILEGES ON ' . $user . '.* TO \'' . $user . '\'@\'localhost\';"' , $output );
exec ( 'mysql -u ' . $_SERVER [ 'mysqluser' ] . ' -p\'' . $_SERVER [ 'mysqlpassword' ] . '\' -e "FLUSH PRIVILEGES;"' , $output );
$databaseModel = ( $type === 'solo' ) ? $_SERVER [ 'solomodel' ] : $_SERVER [ 'fermemodel' ];
exec ( 'mysqldump -u ' . $_SERVER [ 'mysqluser' ] . ' -p\'' . $_SERVER [ 'mysqlpassword' ] . '\' -v ' . $databaseModel . ' | mysql -u ' . $user . ' -p\'' . $pass . '\' -D ' . $user , $output );
// TODO: add first user and make him admin
2022-08-29 00:26:46 +03:00
return [ 'database' => $user , 'user' => $user , 'password' => $pass ];
}
function removeMySQLUserAndDatabase ( $user )
{
2022-09-06 13:38:00 +03:00
exec ( 'mysql -u ' . $_SERVER [ 'mysqluser' ] . ' -p\'' . $_SERVER [ 'mysqlpassword' ] . '\' -e \'DROP DATABASE IF EXISTS ' . $user . ';\'' , $output );
exec ( 'mysql -u ' . $_SERVER [ 'mysqluser' ] . ' -p\'' . $_SERVER [ 'mysqlpassword' ] . '\' -e "DROP USER IF EXISTS \'' . $user . '\'@\'localhost\';"' , $output );
exec ( 'mysql -u ' . $_SERVER [ 'mysqluser' ] . ' -p\'' . $_SERVER [ 'mysqlpassword' ] . '\' -e "FLUSH PRIVILEGES;"' , $output );
2022-08-29 00:26:46 +03:00
return ;
}
function createUnixUserWithQuota ( $user , $quota )
{
$pass = generatePassword ();
exec ( 'useradd -m -p "' . $pass . '" ' . $user , $output );
exec ( 'setquota -u ' . $user . ' ' . $quota . ' ' . $quota . ' 0 0 -a /dev/loop0' , $output );
// TODO : handle errors
return [ 'user' => $user , 'password' => $pass , 'quota' => $quota ];
}
function removeUnixUser ( $user )
{
exec ( 'deluser --remove-home ' . $user , $output );
// TODO : handle errors
return ;
}
function createNginxConfig ( $domain , $user , $herseUser , $hersePass )
{
2023-03-18 09:49:51 +03:00
// create folder if not exists
exec ( 'sudo -u ' . $user . ' mkdir -p /home' . '/' . $user . '/' . $domain );
2022-09-06 13:38:00 +03:00
$nginxFile = '/etc/nginx/conf.d/' . $domain . '.conf' ;
if ( empty ( $herseUser ) && empty ( $hersePass )) {
// no herse needed
} elseif ( empty ( $herseUser ) || empty ( $hersePass )) {
throw new Exception ( 'You need an username AND a password to add a herse.' );
} else {
// add password file to domain
file_put_contents (
'/home' . '/' . $user . '/' . $domain . '/.htpasswd' ,
$herseUser . ':' . password_hash ( $hersePass , PASSWORD_BCRYPT )
);
}
2022-11-22 10:09:27 +03:00
$templates = new League\Plates\Engine ( dirname ( __FILE__ ) . '/templates' );
2022-09-06 17:10:16 +03:00
$subDomain = preg_match ( '/.' . $_SERVER [ 'maindomain' ] . '$/isU' , $domain , $matches , PREG_OFFSET_CAPTURE , 0 );
if ( ! $subDomain ) {
2022-11-22 10:09:27 +03:00
file_put_contents (
$nginxFile ,
$templates -> render (
'nginx-for-ssl-certificate' ,
[
'domain' => $domain ,
2023-03-27 15:46:49 +03:00
'user' => $user ,
2022-11-22 10:09:27 +03:00
]
)
);
exec ( 'service nginx force-reload' , $output );
2023-02-01 16:35:45 +03:00
exec ( '/root/.acme.sh/acme.sh --issue -d ' . $domain . ' -d www.' . $domain . ' -k ec-384 -w /home/' . $user . '/' . $domain . '/' , $output );
2022-09-06 17:10:16 +03:00
exec ( 'mkdir -p /etc/letsencrypt/live/' . $domain , $output );
2022-09-07 09:57:53 +03:00
exec ( '/root/.acme.sh/acme.sh --install-cert -d ' . $domain . ' -- ecc \
2022-09-06 17:10:16 +03:00
-- cert - file / etc / letsencrypt / live / '.$domain.' / cert . pem \
-- key - file / etc / letsencrypt / live / '.$domain.' / key . pem \
-- fullchain - file / etc / letsencrypt / live / '.$domain.' / fullchain . pem \
-- ca - file / etc / letsencrypt / live / '.$domain.' / ca . pem \
-- reloadcmd " systemctl restart nginx.service " ' , $output );
}
2022-09-06 13:38:00 +03:00
file_put_contents (
$nginxFile ,
$templates -> render (
'nginx-maindomain' ,
[
'domain' => $domain ,
'user' => $user ,
'herseUser' => $herseUser ,
'hersePass' => $hersePass ,
2022-09-07 09:57:53 +03:00
'subDomain' => $subDomain ,
2022-09-06 13:38:00 +03:00
]
)
);
exec ( 'service nginx force-reload' , $output );
}
function removeNginxConfig ( $domain )
{
$nginxFile = '/etc/nginx/conf.d/' . $domain . '.conf' ;
unlink ( $nginxFile );
exec ( 'service nginx force-reload' , $output );
2022-08-29 00:26:46 +03:00
}
function createPhpFpmConfig ( $user )
{
2022-09-06 13:38:00 +03:00
$phpVersion = str_replace ([ 'php' , '-fpm' ], '' , $_SERVER [ 'phpservice' ]);
$phpConfFile = '/etc/php/' . $phpVersion . '/fpm/pool.d/' . $user . '.conf' ;
$templates = new League\Plates\Engine ( dirname ( __FILE__ ) . '/templates' );
file_put_contents ( $phpConfFile , $templates -> render ( 'php-fpm' , [ 'user' => $user ]));
exec ( 'service ' . $_SERVER [ 'phpservice' ] . ' reload' , $output );
2022-08-29 00:26:46 +03:00
}
function removePhpFpmConfig ( $user )
{
2022-09-06 13:38:00 +03:00
$phpVersion = str_replace ([ 'php' , '-fpm' ], '' , $_SERVER [ 'phpservice' ]);
$phpConfFile = '/etc/php/' . $phpVersion . '/fpm/pool.d/' . $user . '.conf' ;
unlink ( $phpConfFile );
exec ( 'service ' . $_SERVER [ 'phpservice' ] . ' reload' , $output );
2022-08-29 00:26:46 +03:00
}
2023-02-03 22:08:34 +03:00
function copyYesWikiFiles ( $domain , $user , $dbUser , $herseUser = null , $hersePass = null )
2022-08-29 00:26:46 +03:00
{
2023-02-01 13:22:42 +03:00
$tmpFile = '/tmp/yeswiki.zip' ;
2022-08-29 00:26:46 +03:00
$destDir = '/home' . '/' . $user . '/' . $domain ;
2023-02-01 13:22:42 +03:00
$sudo = 'sudo -u ' . $user . ' ' ;
exec ( $sudo . ' mkdir -p ' . $destDir , $output );
2023-03-18 09:49:51 +03:00
exec ( $sudo . ' chown ' . $user . ':' . $user . ' -R ' . $destDir , $output );
2023-02-01 13:22:42 +03:00
if ( file_exists ( $tmpFile )) {
unlink ( $tmpFile );
}
2023-02-01 19:26:44 +03:00
exec ( $sudo . 'curl --insecure -o ' . $tmpFile . ' ' . $_SERVER [ 'source_archive_url' ]);
2023-02-01 13:22:42 +03:00
exec ( $sudo . 'unzip ' . $tmpFile . ' "doryphore/*" -d ' . $destDir );
2023-02-01 16:48:41 +03:00
exec ( $sudo . 'mv ' . $destDir . '/doryphore/* ' . $destDir . '/' );
2023-02-01 16:35:45 +03:00
exec ( $sudo . 'rm -rf ' . $destDir . '/doryphore' );
2023-02-01 13:22:42 +03:00
unlink ( $tmpFile );
2023-02-03 22:08:34 +03:00
$herse = '' ;
if ( ! empty ( $herseUser ) && ! empty ( $hersePass )) {
2023-02-03 22:15:42 +03:00
$herse = $herseUser . ':' . $hersePass . '@' ;
2023-02-03 22:08:34 +03:00
}
$curl = 'curl -X POST --insecure --data-urlencode \'config[default_language]=fr\' --data-urlencode \'config[wakka_name]=' . $domain . '\' --data-urlencode \'config[root_page]=PagePrincipale\' --data-urlencode \'config[mysql_host]=localhost\' --data-urlencode \'config[mysql_database]=' . $dbUser [ 'database' ] . '\' --data-urlencode \'config[mysql_user]=' . $dbUser [ 'user' ] . '\' --data-urlencode \'config[mysql_password]=' . $dbUser [ 'password' ] . '\' --data-urlencode \'config[table_prefix]=yeswiki_\' --data-urlencode \'admin_name=' . $_SERVER [ 'admin_id' ] . '\' --data-urlencode \'admin_password=' . $_SERVER [ 'admin_password' ] . '\' --data-urlencode \'admin_password_conf=' . $_SERVER [ 'admin_password' ] . '\' --data-urlencode \'admin_email=' . $_SERVER [ 'admin_email' ] . '\' --data-urlencode \'config[rewrite_mode]=0\' --data-urlencode \'config[allow_raw_html]=1\' --data-urlencode \'config[allow_robots]=1\' --data-urlencode \'submit=Continue\' \'https://' . $herse . $domain . '/?PagePrincipale&installAction=install\' 2>&1' ;
2023-02-01 20:01:22 +03:00
$output = [];
exec ( $curl , $output );
2023-02-01 22:04:18 +03:00
//echo implode("\n", $output);
2022-08-29 00:26:46 +03:00
return ;
}
function checkHerse ( $herseUser , $hersePass )
{
if ( empty ( $herseUser ) && empty ( $hersePass )) {
return false ; // no herse needed
} elseif ( empty ( $herseUser ) || empty ( $hersePass )) {
throw new Exception ( 'You need an username AND a password to add a herse.' );
}
return true ; // herse needed
}
2023-02-03 21:36:26 +03:00
function editConfigFile () {
// change fuseau horaire
// 'contact_mail_func' => 'smtp',
// 'contact_smtp_host' => 'ssl://mail.gandi.net',
// 'contact_smtp_port' => '465',
// 'contact_smtp_user' => 'noreply@yeswiki.pro',
// 'contact_reply_to' => 'noreply@yeswiki.pro',
// 'contact_smtp_pass' => 'Ceci est 1 message automatique!',
}
2023-02-03 22:08:34 +03:00
function addExtensions () {
// ferme pour l'option ferme
}
2023-02-03 21:36:26 +03:00
function addStatistics () {
// requete SQL
// INSERT INTO `matomo_site` (`idsite`, `name`, `main_url`, `ts_created`, `ecommerce`, `sitesearch`, `sitesearch_keyword_parameters`, `sitesearch_category_parameters`, `timezone`, `currency`, `exclude_unknown_urls`, `excluded_ips`, `excluded_parameters`, `excluded_user_agents`, `excluded_referrers`, `group`, `type`, `keep_url_fragment`, `creator_login`) VALUES (NULL, 'Partage ton outil', 'https://partagetonoutil.fr', '2023-02-01 00:00:00', '0', '1', '', '', 'Europe/Paris', 'EUR', '0', '', '', '', '', '', 'website', '0', 'superadmin');
}