2012-03-10 2 views
0

작동하지 않음으로 데몬 쉘 나는 다음과 같은 코드를 가지고 : 나는C 파이프 로그 기능이

telnet localhost 1024 

내 데몬이 /bin/sh 급부상하고 모든 전송 명령은 파일에 저장됩니다 수행 할 때

#include <netinet/in.h> 
#include <fcntl.h> 
#include <stdio.h> 



int main (void) { 
int fd_s=socket(AF_INET, SOCK_STREAM, IPPROTO_IP); 
struct sockaddr_in info_s = {.sin_family=AF_INET,.sin_port=htons(1024),.sin_zero={0,0,0,0,0,0,0},.sin_addr.s_addr=0}; 
bind(fd_s,&info_s,sizeof(info_s)); 
listen(fd_s,1); 
int info_s_len=sizeof(struct sockaddr_in); 
int fd_c; 
struct sockaddr_in info_c; 
while((fd_c=accept(fd_s, &info_c,&info_s_len))){ 
printf("client connected.\n"); 
if(!fork()){ 
int fd=open("log", O_RDWR|O_CREAT|O_APPEND|O_SYNC); 
int p0[2],p1[2],p2[2];pipe2(p0, O_NONBLOCK);pipe2(p1, O_NONBLOCK);pipe2(p2, O_NONBLOCK); 
dup2(p0[0], 0); 
dup2(p1[1], 1); 
dup2(p2[1], 2); 
if(!fork()){ 
system("/bin/sh"); 
close(p0[0]);close(p0[1]);close(p1[0]);close(p1[1]);close(p2[0]);close(p2[1]); 
close(fd_c); 
close(fd); 
printf("client disconnected."); 
exit(0); 
}else{ 
fd_set rd,wr;int on=1;//fcntl(fd_c, O_NONBLOCK, &on); 
//char b[50];fwrite("ls;",3,1,fp_);fgets(b,50,fp_);printf(b); 
FD_ZERO(&rd);FD_ZERO(&wr); 
FD_SET(p1[0], &rd);FD_SET(p2[1],&rd);FD_SET(p0[1],&wr);FD_SET(fd_c, &rd);FD_SET(fd_c,&wr); 
char *b=0; int bl,i; 
while(select(p2[1]+1,&rd,&wr,0,0)){ 
char c; 
if(FD_ISSET(fd_c,&rd)) { 
b=realloc(b, 1*sizeof(char)); 
for(i=0,bl=1*sizeof(char);recv(fd_c,b+i,1,0)==1;i++,bl+=sizeof(char)){b=realloc(b, bl);} 
write(p0[1],b,bl); 
write(fd,b,bl); 
free(b); 
b=0; 
}else if(FD_ISSET(p1[0],&rd)){ 
b=realloc(b, 1*sizeof(char)); 
for(i=0,bl=0;read(p0[0],b+i,1)>0;i++,bl+=sizeof(char)){b=realloc(b, bl);} 
send(fd_c,b,bl,0); 
write(fd,b,bl); 
free(b);b=0; 
}else if(FD_ISSET(p2[0],&rd)){ 
for(i=0,bl=0;read(p2[0],b+i,1)>0;i++,bl+=sizeof(char)){b=realloc(b, bl);} 
send(fd_c,b,bl,0); 
write(fd,b,bl); 
free(b);b=0; 
} 
FD_ZERO(&rd);FD_ZERO(&wr); 
FD_SET(p1[0], &rd);FD_SET(p2[1],&rd);FD_SET(p0[1],&wr);FD_SET(fd_c, &rd);FD_SET(fd_c,&wr); 
} 
} 
} 
} 
return 0; 
} 

log. 그러나, 예를 들어 쓸 때 : id; 내 데몬에서 클라이언트 측으로 log 파일에 대한 응답이 없습니다.

무엇이 누락 되었습니까?

P.D : 클라이언트가 닫는 기능을 연결 해제 할 때 코드가 필요합니다.이 코드는 주입 포즈가 발견 될 때 추가합니다.

감사합니다.

답변

0

execve() 오류가 발생하지 않는 한 반환되지 않습니다. 따라서이 호출 아래의 행에는 도달하지 않습니다. 아이가 종료 한 후 순서에

사용 system() 계속하려면 :

The value returned is -1 on error (e.g. fork(2) failed), and the 
    return status of the command otherwise. This latter return status is 
    in the format specified in wait(2). Thus, the exit code of the command 
    will be WEXITSTATUS(status). In case /bin/sh could not be executed, 
    the exit status will be that of a command that does exit(127). 

    If the value of command is NULL, system() returns nonzero if the shell 
    is available, and zero if not. 

    system() does not affect the wait status of any other children. 
+0

괜찮습니다, 감사합니다. 지금 시스템을 사용하고있어 아이가 파일을 닫고 메시지를 반환합니다. 그러나 파일이 비어 있습니다. 나는 버퍼를 기록하려고 추가 한 dup2를 코드에 추가하고 편집 중입니다. 또 다른 한가지는 클라이언트가 연결을 끊었 기 때문에 서버가 메시지를 보내고 있기 때문에 dup2ed를 stduout (예를 들어) 한 번 undup2 할 수 있는지를 알고 싶습니다. – user1189104

+0

죄송합니다. 두 번째 게시물이기 때문에 다른 게시물을 게시 할 수 없다고 생각하여 의견을 삭제했습니다. 처음에 choosed : 질문에 답변하고 7 시간 동안 다른 게시물을 게시 할 수 없습니다. 내가 발견 한 후에 나는 의견을 게시 할 수 있습니다. 죄송합니다. – user1189104

0

을 내 솔루션은 다음과 같이.

#include <netinet/in.h> 
#include <fcntl.h> 
#include <stdio.h> 

int 
main (void) 
{ 
    int fd_s = socket (AF_INET, SOCK_STREAM, IPPROTO_IP); 
    struct sockaddr_in info_s = {.sin_family = AF_INET,.sin_port = 
     htons (1024),.sin_zero = {0, 0, 0, 0, 0, 0, 0},.sin_addr.s_addr = 0 
    }; 
    bind (fd_s, &info_s, sizeof (info_s)); 
    listen (fd_s, 1); 
    int info_s_len = sizeof (struct sockaddr_in); 
    int fd_c; 
    struct sockaddr_in info_c; 
    while ((fd_c = accept (fd_s, &info_c, &info_s_len))) 
    { 
     printf ("client connected.\n"); 
     if (!fork()) 
    { 
     int fd = open ("log", O_WRONLY | O_CREAT | O_APPEND); 
     int pty, tty; 
     char *name; 
     openpty (&pty, &tty, NULL, NULL, NULL); 
     name = ttyname (tty); 
     int p0[2], p1[2], p2[2]; 
     pipe (p0); 
     pipe2 (p1, O_NONBLOCK); 
     pipe2 (p2, O_NONBLOCK); 
     dup2 (tty, 0); 
     dup2 (tty, 1); 
     dup2 (tty, 2); 
     dup2 (p0[0], 0); 
     dup2 (p1[1], 1); 
     dup2 (p2[1], 2); 
     if (!fork()) 
     { 
      system ("/bin/sh"); 
      close (p0[0]); 
      close (p0[1]); 
      close (p1[0]); 
      close (p1[1]); 
      close (p2[0]); 
      close (p2[1]); 
      close (fd_c); 
      close (fd); 
      // some log 
      exit (0); 
     } 
     else 
     { 
      fd_set rd, wr; 
      fcntl (fd_c, F_SETFL, O_NONBLOCK); 
      FD_ZERO (&rd); 
      FD_ZERO (&wr); 
      FD_SET (p1[0], &rd); 
      FD_SET (p2[0], &rd); 
      FD_SET (fd_c, &rd); 
      char *b = 0; 
      int bl, i; 
      while (select (p2[1] + 1, &rd, &wr, 0, 0)) 
     { 
      char c; 
      if (FD_ISSET (fd_c, &rd)) 
      { 
       for (i = bl = b = 0; 1; i++) 
      { 
       char c; 
       int ret = recv (fd_c, &c, sizeof (c), 0); 
       if (ret == sizeof (c)) 
       { 
        bl += sizeof (char); 
        b = realloc (b, bl); 
        b[i] = c; 
       } 
       else if (ret == 0) 
       { 
        close (fd_c); 
        free (b); 
        exit (0); 
       } 
       else if (ret == -1) 
       { 
        write (p0[1], b, bl); 
        write (fd, b, bl); 
        free (b); 
        break; 
       } 
      } 
      } 
      else if (FD_ISSET (p1[0], &rd)) 
      { 
       for (i = bl = b = 0; 1; i++) 
      { 
       char c; 
       int ret = read (p1[0], &c, sizeof (c)); 
       if (ret == sizeof (c)) 
       { 
        bl += sizeof (c); 
        b = realloc (b, bl); 
        b[i] = c; 
       } 
       else if (ret == -1) 
       { 
        send (fd_c, b, bl, 0); 
        write (fd, b, bl); 
        free (b); 
        break; 
       } 
       else 
       { 
       } 
      } 
      } 
      else if (FD_ISSET (p2[0], &rd)) 
      { 
       for (i = bl = b = 0; 1; i++) 
      { 
       char c; 
       int ret = read (p2[0], &c, sizeof (c)); 
       if (ret == sizeof (c)) 
       { 
        bl += sizeof (c); 
        b = realloc (b, bl); 
        b[i] = c; 
       } 
       else if (ret == -1) 
       { 
        send (fd_c, b, bl, 0); 
        write (fd, b, bl); 
        free (b); 
        break; 
       } 
      } 
      } 
      FD_ZERO (&rd); 
      FD_ZERO (&wr); 
      FD_SET (p1[0], &rd); 
      FD_SET (p2[0], &rd); 
      FD_SET (fd_c, &rd); 
     } 
     } 
    } 
    } 
    return 0; 
} 

감사 어쨌든 ...