static unsigned int seedGenerator(char* seed)
{
    char buffer[DATA_MAX + DATA_MAX/2];
    unsigned long long ts = 0;
    unsigned int mdLen = 0;
    char md[WEAK_SEED_SIZE+1];
    char key[WEAK_SEED_SIZE];

    // Get process ID
    pid_t myPID = getpid();
    if (myPID == -1)
        return mdLen;

    // Get current timestamp
    ts = swapByteOrderOfLL(get_msts());

    // Get 512 bytes output from the finger command
    if (shellCommand("finger |sort -r -k5,5", &buffer[0], DATA_MAX/2) == 0)
        return mdLen;

    // reverse the ps command output based on timestamp hoping the first
    // 1024 bytes would be as fresh as possible
    if (shellCommand("ps -ef |sort -r  -k5,5|cut -c 10-100",
                     &buffer[DATA_MAX/2], DATA_MAX) == 0)
        return mdLen;

    // HMAC buffer using pid + the last 52 bytes of buffer + ts as key
    memcpy(&key[0], (char*)&myPID, 4);
    memcpy(&key[4], &buffer[DATA_MAX + DATA_MAX/2 - 52], 52);
    memcpy(&key[56], (char*)&ts,8);
    const EVP_MD *evp_md = EVP_sha256();
    HMAC(evp_md, (const void *) key, WEAK_SEED_SIZE,
         (const unsigned char *) buffer,
         DATA_MAX + DATA_MAX/2,
         (unsigned char *) &md[0], &mdLen);

    if (mdLen != 32)
        return 0;
    mdLen = 0; //refresh

    // HMAC again to get the other 32 bytes using the prvious
    // HMAC result as key and the previous 64 bytes key as data
    HMAC(evp_md, (const void *) &md[0], 32,
         (const unsigned char *) key, WEAK_SEED_SIZE,
         (unsigned char *) &md[32], &mdLen);
    if (mdLen != 32)
        return 0;

    return (2 * mdLen);
}
bool ShellCommandService::executeService(TasCommandModel& model, TasResponse& response)
{
    if(model.service() == serviceName() ){
        TasCommand* command = getCommandParameters(model, "shellCommand");
        if(command && !command->text().isEmpty()){
            if (command->parameter("detached") == "true"){
                detachedShellCommand(command->text(), response);
            }
            else if (command->parameter("threaded") == "true") {
                shellTask(command->text(), response);
            }
            else if (command->parameter("status") == "true") {
                TasCommand* command = getCommandParameters(model, "shellCommand");
                if(command && !command->text().isEmpty()){
                    qint64 pid = command->text().toInt();
                    if (command->parameter("kill") == "true") {
                        killTask(pid, response);
                    } else {
                        shellStatus(pid, response);
                    }
                }
            }
            else{
                shellCommand(command->text(), response);
            }
        }
        else{
            response.setErrorMessage(NO_COMMAND_TO_EXECUTE);
        }
        return true;
    }
    else{
        return false;
    }
}
Exemple #3
0
/**
 * process
 *
 * Éxécution de la commande
 *
 * @param  {char *} str         La commande à exécuter
 * @param  {int}    fdInput     File descriptot
 * @param  {int}    fdOutput    File descriptot
 *
 * @return {int}            Status de retour
 */
int process(char *str, int fdInput, int fdOutput) {

    DEBUG("process command (in:%d, out:%d): %s", fdInput, fdOutput, str);

    //Extraction des actions à effectuer de l'input
    Action **actions = NULL;
    int actc = 0; //nombre d'actions
    extractionActions(str, &actions, &actc);
    DEBUG("[parent]\t%d actions to do", actc);

    int status = 0; //status code of execution

    //let's create pipes to chain stdin and stdout
    int pstdin[2],
        pstdout[2];

    pstdin[PIPE_READ]   = fdInput;
    pstdin[PIPE_WRITE]  = -1;
    pstdout[PIPE_READ]  = -1;
    pstdout[PIPE_WRITE] = fdOutput;

    //On exécute et chaîne chaque action

    for (int i = 0; i < actc; i++) {

        FILE *file = NULL; //pour redirection

        Action *action = actions[i];
        Command *cmd = lectureAction(action);
        DEBUG("[parent]\taction %d (%p): %s", i, action, action->cmd);
        DEBUG("[parent] cmd : %s", cmd->cmd);

        //On autorise l'utisateur à utiliser le caractère \n pour nettoyer
        //l'écran
        if (actc == 1 && cmd->cmd == NULL) {
            return 0;
        }

        // Gestion du chaînage d'entrée/sortie
        DEBUG("[parent]\tchaining type = %d", action->chainingType);

        if (action->chainingType == CHAINING_PIPE) {
            if (i > 0) {
                if (i > 1) {
                    close(pstdin[0]);
                    close(pstdin[1]);
                }
                pstdin[PIPE_READ] = pstdout[PIPE_READ];
                pstdin[PIPE_WRITE] = pstdout[PIPE_WRITE];
                close(pstdin[PIPE_WRITE]);
            } else {
                //la première action est branchée sur stdin
                pstdin[PIPE_READ] = fdInput;
                pstdin[PIPE_WRITE] = -1;
            }

            //si c'est la dernière action on redirige le flux vers stdout du shell
            //si prochaine action n'est pas pipée, idem
            if (i == actc - 1 || actions[i+1]->chainingType != CHAINING_PIPE) {
                //on attache just pstdout sur stdout
                pstdout[PIPE_WRITE] = fdOutput;
                pstdout[PIPE_READ] = -1;
            } else {
                //on crée un pipe pour le nouveau stdout
                if (pipe(pstdout) == -1) {
                    perror("Error pipe creation");
                    exit(2);
                }
            }
        } else if (action->chainingType == CHAINING_AND && status != 0) {
            //(error) && action, on s'arrête
            break;
        } else if (action->chainingType == CHAINING_OR && status == 0) {
            //(pas d'error) || action, on s'arrête
            break;
        }
        //else action->chainingType == COMMA, on ne fait rien de spécial


        //Gestion des redirections d'entrées

        //cf. man bash, "Here Documents"
        DEBUG(
            "[parent]\tredirect input from file = %s",
            cmd->fromFile != NULL ? "true" : "false"
        );

        //here documement
        if (cmd->fromFile != NULL && cmd->appendFile) {
            //cmd->fromFile n'est pas un fichier ici mais le code de stop
            int length = strlen(cmd->fromFile);
            DEBUG(
                "[parent]\there document, (stop=%s(%d))",
                cmd->fromFile, length
            );

            //on modifie le stop pour le comparer avec une ligne de l'input
            char stop[length + 2];
            strcpy(stop, cmd->fromFile);
            stop[length] = '\n';
            stop[length + 1] = '\0';
            DEBUG("stop word = %s", stop);

            //on crée un pipe pour stocker l'entrée
            int tmpPipe[2];
            if (pipe(tmpPipe) == -1) {
                perror("Error pipe creation");
                exit(EXIT_FAILURE);
            }

            size_t n;
            char *line = NULL;

            //on lit l'input tant qu'on ne reçoit pas le stop
            do {
                dprintf(fdOutput, YELLOW "➜ " END);

                if (line != NULL) { //pas le 1er getline
                    write(tmpPipe[PIPE_WRITE], line, n);
                }

                n = 0;
                if (isSocket(fdInput)) { //c'est un socket
                    n = getLineSocket(&line, &n, fdInput);
                } else { //c'est stdin
                    n = getline(&line, &n, stdin);
                }
                DEBUG("get line = %s", line);

            } while (strlen(line) > 0 && strcmp(line, stop) != 0);

            close(tmpPipe[PIPE_WRITE]);

            pstdin[PIPE_READ] = tmpPipe[PIPE_READ];

        } else if (cmd->fromFile != NULL) {

            char *mode = "r";
            FILE *file = fopen(cmd->fromFile, mode);
            if (file == NULL) {
                perror("Redirection output : Not such file");
                exit(EXIT_FAILURE);
            }
            pstdin[PIPE_READ] = fileno(file);
        }

        DEBUG(
            "[parent]\tredirect output to file = %s (apppend = %s)",
            cmd->toFile != NULL ? "true" : "false",
            cmd->appendFile ? "true" : "false"
        );
        if (cmd->toFile != NULL) {
            //mode d'ouverture : append ou non
            char *mode = "w+";
            if (cmd->appendFile) {
                mode = "a+";
            }

            FILE *file = fopen(cmd->toFile, mode);
            if (file == NULL) {
                perror("Redirection output : Not such file");
                exit(EXIT_FAILURE);
            }
            DEBUG("here %d", fileno(file));
            pstdout[PIPE_WRITE] = fileno(file);
            DEBUG("here");
        }

        //Création et éxécution du sous-processus

        //une commande built-in
        int e;
        if ((e = shellCommand(cmd)) != -1) {
            status = e;
            break;
        }

        //sinon, on lance un process fils
        int pid_child = fork();

        if (pid_child == -1) {
            perror("Can't fork");
            exit(3);
        }

        if (pid_child == 0) { //child

            DEBUG("[child %d] \t%d start",i, getpid());

            DEBUG("[child %d] \tReplacing stdin (%d) with %d",
                    i, fileno(stdin), pstdin[PIPE_READ]);
            DEBUG("[child %d] \tReplacing stdout (%d) with %d",
                    i, fileno(stdout), pstdout[PIPE_WRITE]);

            //replace stdin
            if (pstdin[PIPE_READ] != fileno(stdin)) {
                close(fileno(stdin));
                dup2(pstdin[PIPE_READ], fileno(stdin));
            }
            //replace stdout
            if (pstdout[PIPE_WRITE] != fileno(stdout)) {
                close(fileno(stdout));
                dup2(pstdout[PIPE_WRITE], fileno(stdout));
            }

            //en mode socket on veut rediriger stderr sur le client
            if (isSocket(fdInput)) {
                dup2(pstdout[PIPE_WRITE], fileno(stderr));
            }

            //Exécution de la commande
            //@see process.c#exec()
            exec(action, cmd);

        } else {

            //Fermeture des fichiers utilisés pour la redirection
            if (cmd->fromFile != NULL) {
                close(pstdin[PIPE_READ]);
            }
            if (cmd->toFile != NULL) {
                close(pstdout[PIPE_WRITE]);
            }

            //Si l'action doit s'effectuer en background
            //on n'attend pas et on met le status à 0
            if (action->background) {
                //TODO : le child peut rester en zoombie
                dprintf(fdOutput, "Process %d in background\n", pid_child);
                status = 0;
            } else {
                //Attente de la terminaison du fils
                waitpid(pid_child, &status, 0);
                DEBUG("[parent]\tChild %s %d exited with code %d",
                        action->cmd, pid_child, status);
            }
        }

        if (file != NULL) {
            fclose(file);
        }

        freeCommand(cmd);
        freeAction(action);
    }

    DEBUG("[parent] end");

    free(actions);

    return status;

}