2013年6月3日 星期一

use pseudo-terminal send password to scp

需要使用 scp 來將檔案傳送到 ssh server 上, scp 沒有提供接受密碼的參數, 網路上的一些方法大多是使用 expect script。不過在我的系統上沒有 expect, 自己胡亂打造了一個類似的功能。

不知道為什麼不能單純轉接標準輸出/輸入, 一定要用 pseudo-terminal, 雖然最後沒用到, 留著作為日後參考。

pseudo-terminal_prog.cpp
  1 /*
  2  * use pseudo-terminal to auto fill password or yes to scp.
  3  */
  4 #include <cstdio>
  5 #include <cstring>
  6 #include <cstdlib>
  7 
  8 #include <unistd.h>
  9 #include <pty.h>
 10 #include <sys/select.h>
 11 
 12 
 13 #define SIZE 1024
 14 fd_set rset, wset, testfds_w, testfds_r;
 15 
 16 int write_data(int pty, const char *input)
 17 {
 18   int count=0;
 19 
 20   //while (1)
 21   {
 22     int result = select (pty+1, NULL, &testfds_w, NULL, NULL);
 23     if (FD_ISSET (pty, &testfds_w)) 
 24     {
 25       char password[SIZE] = "iampasswd\n";
 26       printf("to w\n");
 27       count=write(pty, input, strlen(input) );
 28       printf("w: %d\n", count);
 29       //sleep(5);
 30     }
 31   }
 32 }
 33 
 34 int main(int argc, char *argv[])
 35 {
 36   int pty,child;
 37   int ret;
 38 
 39 
 40   child = forkpty(&pty,0,0,0);
 41 
 42 
 43   if(!child)
 44   {
 45     struct termios tios;
 46 
 47     tcgetattr(0, &tios);
 48     tios.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
 49     tios.c_oflag &= ~(ONLCR);
 50     tcsetattr(0, TCSANOW, &tios);
 51     const char *fp="/var/log/mmadplayer_play.log";
 52 
 53     if (argc >= 2)
 54       fp=argv[1];
 55 
 56     execl("/usr/bin/scp", "scp", fp, "a@1.18.2.3:/q/w/z/", NULL);
 57     //execv(argv[1],&argv[1]);
 58 
 59 
 60     //execl("/bin/ls", "./ls", "/", "/home", NULL);
 61 
 62   }
 63   else
 64   {
 65     char message[SIZE];
 66     int count=0;
 67 
 68     FD_ZERO (&rset);
 69     FD_SET (pty, &rset);
 70     FD_ZERO (&wset);
 71     FD_SET (pty, &wset);
 72     char input[SIZE] = "wei\n";
 73 
 74 #if 1
 75 
 76     while(1)
 77     {
 78       testfds_w = wset;
 79       testfds_r = rset;
 80       //struct timeval timeout;
 81       //timeout.tv_sec=2;
 82       //timeout.tv_usec=500000;
 83       int result = select (pty+1, &testfds_r, NULL, NULL, NULL);
 84       if (result == -1)
 85       {
 86         continue;
 87       }
 88 
 89       if (FD_ISSET (pty, &testfds_r)) 
 90       {
 91         count=read(pty, message, SIZE);
 92         if (count == -1)
 93           return 0;
 94         printf("r: %d\n", count);
 95         message[count]=0;
 96         printf("msg: %s\n", message);
 97         if (strstr(message, "password:")!=NULL)
 98         {
 99           printf("pwd\n");
100           strcpy(input, "wei\n");
101         }
102         if (strstr(message, "yes")!=NULL)
103         {
104           printf("yy\n");
105           strcpy(input, "yes\n");
106         }
107         printf("input: %s\n", input);
108 
109         write_data(pty, input);
110 
111 
112       }
113 
114 
115 
116     }
117 #endif
118 
119 
120 
121   }
122 
123   return 0;
124 }

沒有留言:

張貼留言

使用 google 的 reCAPTCHA 驗證碼, 總算可以輕鬆留言了。

我實在受不了 spam 了, 又不想讓大家的眼睛花掉, 只好放棄匿名留言。這是沒辦法中的辦法了。留言的朋友需要有 google 帳號。