2022-08-29 00:26:46 +03:00
< ? php
require 'vendor/autoload.php' ;
function checkDNS ( $domain )
{
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' ]);
}
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 ) {
2022-11-22 11:35:18 +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 )
{
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 ,
]
)
);
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-01 13:22:42 +03:00
function copyYesWikiFiles ( $domain , $user , $dbUser )
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 );
if ( file_exists ( $tmpFile )) {
unlink ( $tmpFile );
}
exec ( $sudo . 'curl -o ' . $tmpFile . ' ' . $_SERVER [ 'source_archive_url' ]);
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-01 17:26:00 +03:00
$curl = ' curl \
2023-02-01 17:39:07 +03:00
-- 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 ] = 1 \ ' \
-- data - urlencode \ ' submit = Continue \ ' \
2023-02-01 17:26:00 +03:00
https :// '.$domain.' / ? PagePrincipale & installAction = install ' ;
2023-02-01 17:15:09 +03:00
echo $curl ;
exec ( $sudo . $curl );
2023-02-01 13:22:42 +03:00
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
}