Как изменить execlp на execv и запустить другие команды, тогда просто 'ls' - PullRequest
0 голосов
/ 15 мая 2019

В данный момент я запускаю веб-сервер HTML, который может выполнять команды, данные ему через текстовое поле и кнопку отправки, но мне нужно преобразовать execlp в execv, и я не понимаю часть массива execv.Я попытался просто сделать это execv(command, command);, но он дает мне проходной аргумент несовместимой проблемы типа указателя.Кроме того, по какой-то причине мое выполнение будет запускать только одно слово команды, такие как ls, и не будет принимать флаги, и я не совсем уверен, почему это так.Раздел выполнения и синтаксического анализа кода ниже, может предоставить полный код, если это необходимо.

Exection.c

char *parse(char *command){
    char * newCommand = (char *) malloc(sizeof(char)*50);
    int tgt = 0;
     newCommand = strstr(command, "/run?command=");
    newCommand = strtok(newCommand, " ");
    newCommand = newCommand + 13;
     for(int src = 0; src< strlen(newCommand); src++){
        if(newCommand[src] == '+')
        {
            newCommand[src] = ' ';
        }
        else if(newCommand[src] == '%')
        {
            newCommand[src] = ' ';
        }
        else if(newCommand[src] == '7')
        {
            newCommand[src] = ' ';
        }
        else if(newCommand[src] == 'C')
        {
            newCommand[src] = '|';
        }


    }

     return newCommand;
}

char * execution(char *command){

  int piper[2];
    size_t len = 0;
    pipe(piper);
  char* output =  malloc(1000 * sizeof(char));
    memset(output, '\0', 1000* sizeof(char));
    pid_t pid = fork();
    if(pid != 0)// parent
        {
            wait(NULL);
            close(piper[1]);
      int n = sizeof(output);

            struct pollfd * poll_fd = malloc(sizeof(struct pollfd));
             poll_fd->fd = piper[0];
             poll_fd->events = POLLIN;

            if(poll(poll_fd, 1, 0) == 1){ // pipe data check
            read(piper[0], output, 1000);
            }

        }
        else{

            close(1);
            dup(piper[1]);
            execlp(command, command, NULL);
        exit(1);
        }
                return output;
}

int main (void){
    int sockfd;
    int new_fd; 
    struct addrinfo hints;
    struct addrinfo *serverinfo; 
    struct addrinfo *p;
    struct sockaddr_storage client_addr;
    socklen_t addrsize;
    struct sigaction sa;
    int yes = 1;
    char s[INET6_ADDRSTRLEN];
    int status;

    memset(&hints, 0, sizeof hints); //makes struct empty 
    hints.ai_family = AF_UNSPEC; //IPv4 or v6 
    hints.ai_socktype = SOCK_STREAM; //TCP type need 
    hints.ai_flags = AI_PASSIVE; //Fill in IP for us 


    //if can't get address info print error 
    if((status = getaddrinfo(NULL, PORT, &hints, &serverinfo)) != 0){
        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(status));
        return 1;
    }


    for(p = serverinfo; p != NULL; p = p->ai_next){
        if((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1){
            perror("server: socket");
            continue;
        }

        if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1){
            perror("setsockopt");
            exit(1);
        }

        if(bind(sockfd, p->ai_addr, p->ai_addrlen) == -1){
            close(sockfd);
            perror("server: bind");
            continue;
        }

        break;
    }

    freeaddrinfo(serverinfo);

    if(p == NULL){
        fprintf(stderr, "server: failed to bind\n");
        exit(1);
    }

    if(listen(sockfd, BACKLOG) == -1){
        perror("listen");
        exit(1);
    }

    sa.sa_handler = sigchld_handler; // reap all dead processes
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = SA_RESTART;
    if (sigaction(SIGCHLD, &sa, NULL) == -1) {
        perror("sigaction");
        exit(1);
    }

    printf("server: waiting for connections....\n");

    while(1){
        addrsize = sizeof client_addr;
        new_fd = accept(sockfd, (struct sockaddr *)&client_addr, &addrsize);
        if(new_fd == -1){
            perror("Did not accept");
            continue;
        }

        inet_ntop(client_addr.ss_family, get_in_addr((struct sockaddr *)&client_addr), s, sizeof s);
        printf("server: got connection from %s\n", s);

        if(!fork()){
            close(sockfd);
            int bufsize = 1024;

            char *buffer = malloc(bufsize);
            recv(new_fd, buffer, bufsize, 0);
            send(new_fd, header, bufsize, 0);

            if(send(new_fd, execution(parse(buffer)), 1000, 0) == -1)
                perror("send");
            close(new_fd);
            exit(0);
        }
        close(new_fd);
    }

    return 0;


}

1 Ответ

1 голос
/ 15 мая 2019

Если вы хотите, чтобы command интерпретировался оболочкой, вам нужно будет передать его в качестве аргумента, что-то вроде:

const char *args[] = {"/bin/sh", "-c", command};
execve("/bin/sh", args, NULL);

Помните, что веб-оболочки в основном считаются вредоносными программами или будущими CVE.

...