diff --git a/src/BashModule.cpp b/src/BashModule.cpp index 7c0f68c..00929bb 100644 --- a/src/BashModule.cpp +++ b/src/BashModule.cpp @@ -12,11 +12,12 @@ using namespace std; -//destructor inline +//constructor BashModule::BashModule() { name="Bash"; } +//destructor inline //private methods int BashModule::executeScript(string serviceUsername, string script) @@ -51,10 +52,7 @@ int BashModule::executeScript(string serviceUsername, string script) return status; } else { //child process - if(execl("/bin/bash", "/bin/bash", "--noediting", "--noprofile", "--norc", "--", script.c_str(), (char *)0)==-1) - { - cerr << "Error in the execl call of " << script << endl; - } + execl("/bin/bash", "/bin/bash", "--noediting", "--noprofile", "--norc", "--", script.c_str(), (char *)0); } } } @@ -94,6 +92,7 @@ int BashModule::executeScriptAs(string serviceUsername, string script) return -1; } else if (pid > 0) { //parent process + cout << "in parent process" << endl; int status; waitpid(-1,&status,0); if(status==-1){ @@ -105,10 +104,7 @@ int BashModule::executeScriptAs(string serviceUsername, string script) //executing as the user corresponding to the service setgid(p->pw_gid); setuid(p->pw_uid); - if(execl("/bin/bash", "/bin/bash", "--noediting", "--noprofile", "--norc", "--",script.c_str(), serviceUsername, (char *)0)==-1) - { - cerr << "Error in the execl call of " << script << endl; - } + execl("/bin/bash", "/bin/bash", "--noediting", "--noprofile", "--norc", "--",script.c_str(), serviceUsername, (char *)0); } } } @@ -121,7 +117,7 @@ int BashModule::Prepare() return 0; } -int BashModule::Deploy (string serviceUsername) +int BashModule::Deploy(string serviceUsername) { string deployScript="./services/"+serviceUsername+"/deploy.sh"; //to be executed as current user string deployAsScript="./services/"+serviceUsername+"/deploy_user.sh"; //to be executed as the user corresponding to the service diff --git a/src/DockerModule.h b/src/DockerModule.h index ed1ab12..7d75105 100644 --- a/src/DockerModule.h +++ b/src/DockerModule.h @@ -12,10 +12,10 @@ class DockerModule : public Module public: DockerModule(); ~DockerModule(){} //inline - int Prepare (); - int Deploy (string serviceUsername); + int Prepare(); + int Deploy(string serviceUsername); int Remove(string serviceUsername); - int Clean (); + int Clean(); private: int removeContainersCreatedByDockerCompose(); int removeContainersWithServiceName (string serviceUsename); diff --git a/src/NginxModule.cpp b/src/NginxModule.cpp index 0d4c1b4..5c40193 100644 --- a/src/NginxModule.cpp +++ b/src/NginxModule.cpp @@ -2,12 +2,15 @@ // Copyright (C) 2024 Jean-Cloud // GNU General Public License v3 +#include +#include #include "NginxModule.h" using namespace std; +namespace fs=filesystem; //constructor NginxModule::NginxModule(){ - name="Let's Encrypt"; + name="Nginx"; } //destructor inline @@ -15,11 +18,48 @@ NginxModule::NginxModule(){ //public methods int NginxModule::Prepare () { + cout << "nginx preparation" << endl; + //create proxy_dir + string proxy_dir=getenv("proxy_dir"); + fs::create_directories(proxy_dir); + + //delete current new_conf directory (to start from scratch) + string new_nginx_conf_path=getenv("new_nginx_conf_path"); + fs::remove_all(new_nginx_conf_path); + + //create new new_conf directory + fs::create_directories(new_nginx_conf_path); + + //create new conf file (for tests purposes) + string nginx_conf_path=getenv("nginx_conf_path"); + //open the old conf file + ifstream input("./services/_proxy/nginx.conf"); + if (!input) { + std::cerr << "Error when opening /services/_proxy/nginx.conf" << std::endl; + return 1; + } else { + stringstream buffer; + buffer << input.rdbuf(); + string content = buffer.str(); + input.close(); + //replace nginx_conf_path with the new nginx_conf_path in the conf + size_t pos=string::npos; + while (content.find(nginx_conf_path)!=string::npos){ + content.replace(content.find(nginx_conf_path),nginx_conf_path.length(),new_nginx_conf_path); + } + //fill the new conf file + ofstream output (proxy_dir+"/new_nginx.conf"); + output << content; + output.close(); + } return 0; } int NginxModule::Deploy (string serviceUsername) { + //write the new conf + + return 0; } @@ -30,5 +70,6 @@ int NginxModule::Remove(string serviceUsername) int NginxModule::Clean () { + cout << "nginx cleaning" << endl; return 0; } \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 1fce722..5229a61 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -28,10 +28,10 @@ int isServiceOnServer(string serviceUsername) string cmd ="getent hosts " +serviceUsername; string result = BashManager::ExecuteAndReadResult(cmd); if(result.find("::1")!=string::npos){ //if result contains "::1" which is the notation for loopback in IpV6 - cout << "service on server" << endl; + cout << "service " << serviceUsername << " on server" << endl; return 0; } - cout << "service not on server" << endl; + cout << "service" << serviceUsername << " not on server" << endl; return 1; return 0; } @@ -99,7 +99,6 @@ string findCertificate(string serviceUsername) string dns_certs_path=getenv("dns_certs_path"); //dns_certs_path is an environment variable //finding the serviceUsername* directory string cmd="ls $dns_certs_path/"+serviceUsername+" | grep '^"+serviceUsername+"\\(-[0-9]\\{4\\}\\)\\?$'"; - cout << "before"<< endl; string name = BashManager::ExecuteAndReadResult(cmd); cout << "result 1: " << name << endl; if (!name.empty()){ @@ -141,12 +140,12 @@ int createEnvService(string serviceUsername) string docker_dir="/services/"+serviceUsername; string jc_service=serviceUsername; string home="/data/"+serviceUsername; - string jc_id=to_string(services.FindByUsername(serviceUsername)->GetUserID()); + string jc_id=to_string(services.FindByUsername(serviceUsername)->GetUserID()+stoi(getenv("services_uid_start"))); string net="172.29."+jc_id; string jc_cert=findCertificate(serviceUsername); //create a .env file accessible outside the C++ program - string file = "/services/"+serviceUsername+"/.env"; + string file = "./services/"+serviceUsername+"/.env"; ofstream outfile(file); outfile << "http_dir=" << http_dir << endl; outfile << "data_dir=" << data_dir << endl; @@ -173,14 +172,12 @@ int createEnvService(string serviceUsername) //create the directories //data_dir fs::create_directories(data_dir); - if (chown(data_dir.c_str(), (unsigned int)stoi(jc_id),(unsigned int)stoi(jc_id)) != 0) { - cerr << "Error changing ownership of" << data_dir << endl; - return -1; - } + string cmd="chown "+ jc_id +" "+data_dir; + BashManager::Execute(cmd); fs::permissions(data_dir,fs::perms::owner_all|fs::perms::group_read|fs::perms::group_exec|fs::perms::others_exec,fs::perm_options::replace); //http_dir fs::create_directories(http_dir); - string cmd="chown "+ jc_id +":www-data -R "+http_dir; + cmd="chown "+ jc_id +":www-data -R "+http_dir; BashManager::Execute(cmd); //secret_dir fs::create_directories(secret_dir); @@ -189,8 +186,8 @@ int createEnvService(string serviceUsername) return -1; } fs::permissions(secret_dir,fs::perms::owner_all|fs::perms::group_read|fs::perms::group_exec|fs::perms::others_exec,fs::perm_options::replace); - cout << "service environment created" << endl; - return 0; + cout << "service " << serviceUsername << " environment created" << endl; + return 0; } int removeEnvService() diff --git a/test/IntegrationTests/src/main.cpp b/test/IntegrationTests/src/main.cpp index 8710026..13517ba 100644 --- a/test/IntegrationTests/src/main.cpp +++ b/test/IntegrationTests/src/main.cpp @@ -3,6 +3,7 @@ // GNU General Public License v3 #include +#include #include "BashManager.h" using namespace std; @@ -13,14 +14,65 @@ void Help() } //tests -void environmentTest() -{ - cout << "Test of the environment setup." << endl; -} - void bashTest() { - cout << "Test of BashModule" << endl; + //test of the execution of deploy.sh + int res1=-1; + ifstream deployResult("deployResult"); + if (!deployResult){ + cout << "The deployResult file cannot be opened. The Bash module must have failed at executing deploy.sh." << endl; + } else { + string user; //deploy.sh writes in deployResult the result of the whoami command + getline(deployResult,user); + if (user!="root"){ + cout << "The deploy.sh has not been executed with the right user." << endl; + } else { + res1=0; + } + } + //test of the execution of deploy_user.sh + //deploy_user.sh of test.sh8s.sh creates deployAsResult in the data_dir as the user associated with the service + int res2=-1; + //extract the data_dir path from the .env file + ifstream env ("services/test.sh8s.sh/.env"); + if (!env){ + cout << ".env file non-existent. The deployer must have failed to create it." << endl; + } else { + string line; + string data_dir; + size_t pos = string::npos; + while (getline (env, line)){ + pos=line.find("data_dir="); + if (pos!=string::npos){ + data_dir=line.substr(pos+9); + break; + } + } + if (data_dir.empty()){ + cout << "http_dir variable not defined in the .env. The deployer must have failed to initialize it." << endl; + } else { + //read the deployAsResult file + string path=data_dir+"/deployAsResult"; + ifstream deployAsResult(path); + if (!deployAsResult){ + cout << "The deployAsResult file cannot be opened. The Bash module must have failed at executing deploy_user.sh." << endl; + } else { + string user; //deploy.sh writes in deployAsResult the result of the whoami command + getline(deployAsResult,user); + if (user!="test.sh8s.sh"){ + cout << "The deploy.sh has not been executed with the right user." << endl; + } else { + res2=0; + } + } + } + } + int res=res1+res2; + if (res==0){ + cout << "Test of BashModule: OK" << endl; + } else { + cout << "Test of BashModule: FAIL" << endl; + } } void dockerTest() @@ -48,11 +100,9 @@ int main(int argc, char **argv) if(argc!=2){ cerr << "Invalid number of arguments." << endl; } else{ - BashManager::Execute("./deployer deploy all"); + BashManager::Execute("./deployer deploy test.sh8s.sh"); string action=argv[1]; - if (action=="environment"){ - environmentTest(); - } else if (action=="bash"){ + if (action=="bash"){ bashTest(); } else if (action=="docker"){ dockerTest(); @@ -63,7 +113,6 @@ int main(int argc, char **argv) } else if (action=="encryption"){ encryptionTest(); } else if (action=="all"){ - environmentTest(); bashTest(); dockerTest(); nginxTest(); diff --git a/testenv/services/_proxy/nginx b/testenv/services/_proxy/nginx new file mode 100644 index 0000000..33a9488 --- /dev/null +++ b/testenv/services/_proxy/nginx @@ -0,0 +1 @@ +example diff --git a/testenv/services/_proxy/nginx.conf b/testenv/services/_proxy/nginx.conf new file mode 100644 index 0000000..33a9488 --- /dev/null +++ b/testenv/services/_proxy/nginx.conf @@ -0,0 +1 @@ +example diff --git a/testenv/services/test.sh8s.sh/deploy_user.sh b/testenv/services/test.sh8s.sh/deploy_user.sh index 192a94d..0fe3a44 100755 --- a/testenv/services/test.sh8s.sh/deploy_user.sh +++ b/testenv/services/test.sh8s.sh/deploy_user.sh @@ -1,5 +1,5 @@ #!/bin/bash -touch $http_dir/deployAsResult -echo $(whoami) >> $http_dir/deployResult +touch $data_dir/deployAsResult +echo $(whoami) >> $data_dir/deployAsResult