]> git.ipfire.org Git - ipfire-3.x.git/blame - telnet/patches/020-from_18_to_24.diff
telnet: FTBFS
[ipfire-3.x.git] / telnet / patches / 020-from_18_to_24.diff
CommitLineData
dce228b2
SS
1Description: Incremental patches from 0.17-18 to 0.17-24.
2 A large set of mixed code patches on top of upstream's source.
3 It has been pruned to reproduce the step from source package
4 netkit-telnet_0.17-18 to netkit-telnet_0.17-24.
5 .
6 Support also Hurd.
7 [telnetd/sys_term.c, telnetd/ext.h]
8 .
9 Do not reset access mode and owner of TTY when client ends the session.
10 [telnetd/sys_term.c (cleanup)]
11 .
12 Path of telnetlogin.
13 [telnetd/telnetd.8]
14 .
15 Adjust 8-bit mode to be without mandatory binary option.
16 A new command line switch `-7' is added to telnet.
17 [telnet/main.cc, telnet/telnet.cc, telnet/terminal.cc,
18 telnet/defines.h, telnet/externs.h]
19 .
20 Allow telnetrc files to specify a port in addition to host name.
21 [telnet/commands.cc, telnet/proto.h, telnet/telnet.1]
22 .
23 Disable 8-bit mode of client if parity bit is enabled.
24 [telnet/main.cc]
25 .
26 Remove obsolete compiler warnings, and disable trigraph warning.
27 Protect tokens ifter #endif.
28 [configure, telnet/terminal.cc]
29 .
30 Support option `-b' in client.
31 [telnet/commands.cc, telnet/main.cc, telnet/netlink.cc,
32 telnet/netlink.h, telnet/telnet.1]
33 .
34 Accept numeric telnet options.
35 [telnet/command.cc]
36 .
37 Buffer overflow due to $HOME, moved to a separate file.
38 .
39 Remote DOS hole, CAN-2004-0911, moved to a separate file.
40 .
41 Buffer overflow, CAN-2005-0469, moved to a separate file.
42
43Comment: interdiff netkit-telnet_0.17-{18woody3,29}.diff
44Author: Herbert Xu, Robert Millan
45Bug-Debian: http://bugs.debian.org/149325
46 http://bugs.debian.org/150812
47 http://bugs.debian.org/144921
48 http://bugs.debian.org/194736
49 http://bugs.debian.org/203544
50 http://bugs.debian.org/242018
51Forwarded: no
52Last-Update: 2015-01-27
53
54--- a/telnet/commands.cc
55+++ b/telnet/commands.cc
56@@ -476,6 +476,7 @@
57 int send_tncmd(int (*func)(int, int), const char *cmd, const char *name) {
58 char **cpp;
59 extern char *telopts[];
60+ long opt;
61
62 if (isprefix(name, "help") || isprefix(name, "?")) {
63 register int col, len;
64@@ -502,16 +503,23 @@
65 name, cmd);
66 return 0;
67 }
68+
69+ opt = cpp - telopts;
70 if (cpp == 0) {
71- fprintf(stderr, "'%s': unknown argument ('send %s ?' for help).\n",
72+ char *end;
73+
74+ opt = strtol(name, &end, 10);
75+ if (*end || opt < 0 || opt > 255) {
76+ fprintf(stderr, "'%s': unknown argument ('send %s ?' for help).\n",
77 name, cmd);
78- return 0;
79+ return 0;
80+ }
81 }
82 if (!connected) {
83 printf("?Need to be connected first.\n");
84 return 0;
85 }
86- (*func)(cpp - telopts, 1);
87+ (*func)(opt, 1);
88 return 1;
89 }
90
91@@ -1615,7 +1623,7 @@
92 char *srp = NULL;
93 int srlen;
94 int family = 0;
95- const char *cmd, *volatile user = 0;
96+ const char *cmd, *volatile user = 0, *srchostp = 0;
97 const char *portp = NULL;
98 char *hostp = NULL;
99 char *resolv_hostp;
100@@ -1662,6 +1670,14 @@
101 --argc;
102 continue;
103 }
104+ if (strcmp(*argv, "-b") == 0) {
105+ --argc; ++argv;
106+ if (argc == 0)
107+ goto usage;
108+ srchostp = *argv++;
109+ --argc;
110+ continue;
111+ }
112 if (strcmp(*argv, "-a") == 0) {
113 --argc; ++argv;
114 autologin = 1;
115@@ -1744,6 +1760,20 @@
116 hints.ai_socktype = SOCK_STREAM;
117 hints.ai_flags = AI_NUMERICHOST;
118 hints.ai_family = family;
119+
120+ if (srchostp) {
121+ res = getaddrinfo(srchostp, "0", &hints, &hostaddr);
122+ if (res) {
123+ fprintf(stderr, "telnet: could not resolve %s: %s\n", srchostp,
124+ gai_strerror(res));
125+ return 0;
126+ }
127+ hints.ai_family = hostaddr->ai_family;
128+ res = nlink.bind(hostaddr);
129+ freeaddrinfo(hostaddr);
130+ if (res < 0)
131+ return 0;
132+ }
133
134 /* Resolve both the host and service simultaneously. */
135 res = getaddrinfo(resolv_hostp, portp, &hints, &hostaddr);
136@@ -1803,7 +1833,7 @@
137 strcpy(hostname, tmpaddr->ai_canonname);
138 }
139
140- cmdrc(hostp, hostname);
141+ cmdrc(hostp, hostname, portp);
142 freeaddrinfo(hostaddr);
143 if (autologin && user == NULL) {
144 struct passwd *pw;
145@@ -2050,15 +2080,21 @@
146 return 0;
147 }
148
149-static void readrc(const char *m1, const char *m2, const char *rcname) {
150+static void readrc(const char *m1, const char *m2, const char *port,
151+ const char *rcname)
152+{
153 FILE *rcfile;
154 int gotmachine = 0;
155 int l1 = strlen(m1);
156 int l2 = strlen(m2);
157- char m1save[strlen(m1) + 1];
158+ int lport = strlen(port);
159+ char m1save[l1 + 1];
160+ char portsave[lport + 1];
161
162 strcpy(m1save, m1);
163 m1 = m1save;
164+ strcpy(portsave, port);
165+ port = portsave;
166
167 rcfile = fopen(rcname, "r");
168 if (!rcfile) return;
169@@ -2083,6 +2119,13 @@
170 strncpy(line, &line[7], sizeof(line) - 7);
171 else
172 continue;
173+
174+ if (line[0] == ':') {
175+ if (!strncasecmp(&line[1], port, lport))
176+ continue;
177+ strncpy(line, &line[lport + 1], sizeof(line) - lport - 1);
178+ }
179+
180 if (line[0] != ' ' && line[0] != '\t' && line[0] != '\n')
181 continue;
182 gotmachine = 1;
183@@ -2095,13 +2138,13 @@
184 fclose(rcfile);
185 }
186
187-void cmdrc(const char *m1, const char *m2) {
188+void cmdrc(const char *m1, const char *m2, const char *port) {
189 static char *rcname = 0;
190 static char rcbuf[128];
191
192 if (skiprc) return;
193
194- readrc(m1, m2, "/etc/telnetrc");
195+ readrc(m1, m2, port, "/etc/telnetrc");
196 if (rcname == 0) {
197 rcname = getenv("HOME");
198 if (rcname)
199@@ -2111,7 +2154,7 @@
200 strcat(rcbuf, "/.telnetrc");
201 rcname = rcbuf;
202 }
203- readrc(m1, m2, rcname);
204+ readrc(m1, m2, port, rcname);
205 }
206
207 #if defined(IP_OPTIONS) && defined(HAS_IPPROTO_IP)
208--- a/telnet/main.cc
209+++ b/telnet/main.cc
210@@ -84,7 +84,7 @@
211 fprintf(stderr, "Usage: %s %s%s%s%s\n",
212 prompt,
213 "[-4] [-6] [-8] [-E] [-L] [-a] [-d] [-e char] [-l user]",
214- "\n\t[-n tracefile]",
215+ "\n\t[-n tracefile] [ -b addr ]",
216 #ifdef TN3270
217 "\n\t"
218 "[-noasynch] [-noasynctty] [-noasyncnet] [-r] [-t transcom]\n\t",
219@@ -106,7 +106,7 @@
220 extern char *optarg;
221 extern int optind;
222 int ch;
223- char *user;
224+ char *user, *srcaddr;
225 int family;
226
227 tninit(); /* Clear out things */
228@@ -115,19 +115,22 @@
229 #endif
230
231 TerminalSaveState();
232+ if ((old_tc.c_cflag & (CSIZE|PARENB)) != CS8)
233+ eight = 0;
234
235 if ((prompt = strrchr(argv[0], '/'))!=NULL)
236 ++prompt;
237 else
238 prompt = argv[0];
239
240- user = NULL;
241+ user = srcaddr = NULL;
242 family = 0;
243
244 rlogin = (strncmp(prompt, "rlog", 4) == 0) ? '~' : _POSIX_VDISABLE;
245 autologin = -1;
246
247- while ((ch = getopt(argc, argv, "468EKLS:X:ade:k:l:n:rt:x")) != EOF) {
248+ while ((ch = getopt(argc, argv,
249+ "4678EKLS:X:ab:de:k:l:n:rt:x")) != EOF) {
250 switch(ch) {
251 case '4':
252 family = AF_INET;
253@@ -139,8 +142,11 @@
254 fputs("IPv6 unsupported\n", stderr);
255 #endif
256 break;
257+ case '7':
258+ eight = 0; /* 7-bit ouput and input */
259+ break;
260 case '8':
261- eight = 3; /* binary output and input */
262+ binary = 3; /* binary output and input */
263 break;
264 case 'E':
265 rlogin = escapechar = _POSIX_VDISABLE;
266@@ -149,7 +155,7 @@
267 //autologin = 0;
268 break;
269 case 'L':
270- eight |= 2; /* binary output only */
271+ binary |= 2; /* binary output only */
272 break;
273 case 'S':
274 {
275@@ -229,6 +235,9 @@
276 "%s: -x ignored, no encryption support.\n",
277 prompt);
278 break;
279+ case 'b':
280+ srcaddr = optarg;
281+ break;
282 case '?':
283 default:
284 usage();
285@@ -252,6 +261,10 @@
286 *argp++ = "-l";
287 *argp++ = user;
288 }
289+ if (srcaddr) {
290+ *argp++ = "-b";
291+ *argp++ = srcaddr;
292+ }
293 if (family) {
294 *argp++ = family == AF_INET ? "-4" : "-6";
295 }
296--- a/telnet/netlink.cc
297+++ b/telnet/netlink.cc
298@@ -79,20 +79,56 @@
299 shutdown(net, 2);
300 }
301 ::close(net);
302+ net = -1;
303+}
304+
305+int netlink::bind(struct addrinfo *addr)
306+{
307+ int res;
308+
309+ res = socket(addr->ai_family);
310+ if (res < 2) {
311+ if (res == 1)
312+ perror("telnet: socket");
313+ return -1;
314+ }
315+
316+ if (::bind(net, addr->ai_addr, addr->ai_addrlen) < 0) {
317+ perror("telnet: bind");
318+ return -1;
319+ }
320+
321+ return 0;
322+}
323+
324+int netlink::socket(int family)
325+{
326+ if (this->family != family)
327+ close(0);
328+
329+ if (net < 0) {
330+ this->family = family;
331+ net = ::socket(family, SOCK_STREAM, 0);
332+ if (net < 0) {
333+ if (errno == EAFNOSUPPORT)
334+ return 1;
335+ perror("telnet: socket");
336+ return 0;
337+ }
338+ }
339+
340+ return 2;
341 }
342
343 int netlink::connect(int debug, struct addrinfo *addr,
344 char *srcroute, int srlen, int tos)
345 {
346 int on=1;
347+ int res;
348
349- net = socket(addr->ai_family, SOCK_STREAM, 0);
350- if (net < 0) {
351- if (errno == EAFNOSUPPORT)
352- return 1;
353- perror("telnet: socket");
354- return 0;
355- }
356+ res = socket(addr->ai_family);
357+ if (res < 2)
358+ return res;
359
360 #if defined(IP_OPTIONS) && defined(HAS_IPPROTO_IP)
361 if (srcroute) {
362--- a/telnet/netlink.h
363+++ b/telnet/netlink.h
364@@ -1,11 +1,15 @@
365
366 class netlink {
367+ private:
368+ int family;
369 protected:
370 int net;
371 public:
372 netlink();
373 ~netlink();
374
375+ int bind(struct addrinfo *hostaddr);
376+ int socket(int family);
377 int connect(int debug, struct addrinfo *hostaddr,
378 char *srcroute, int srlen,
379 int tos);
380--- a/telnet/telnet.1
381+++ b/telnet/telnet.1
382@@ -44,6 +44,7 @@
383 .Nm telnet
384 .Op Fl 468ELadr
385 .Op Fl S Ar tos
386+.Op Fl b Ar address
387 .Op Fl e Ar escapechar
388 .Op Fl l Ar user
389 .Op Fl n Ar tracefile
390@@ -93,6 +94,8 @@
391 option if supported by the remote system. The username is retrieved
392 via
393 .Xr getlogin 3 .
394+.It Fl b Ar address
395+Use bind(2) on the local socket to bind it to a specific local address.
396 .It Fl d
397 Sets the initial value of the
398 .Ic debug
399@@ -492,7 +495,15 @@
400 indented by whitespace; lines beginning without whitespace are
401 interpreted as hostnames. Lines beginning with the special hostname
402 .Ql DEFAULT
403-will apply to all hosts. Upon connecting to a particular host, the
404+will apply to all hosts. Hostnames including
405+.Ql DEFAULT
406+may be followed immediately by a colon and a port number or string.
407+If a port is specified it must match exactly with what is specified
408+on the command line. If no port was specified on the command line,
409+then the value
410+.Ql telnet
411+is used.
412+Upon connecting to a particular host, the
413 commands associated with that host are executed.
414 .It Ic quit
415 Close any open session and exit
416--- a/telnet/telnet.cc
417+++ b/telnet/telnet.cc
418@@ -88,7 +88,8 @@
419 char will_wont_resp[256];
420
421 int
422-eight = 0,
423+ eight = 3,
424+ binary = 0,
425 autologin = 0, /* Autologin anyone? */
426 skiprc = 0,
427 connected,
428@@ -1743,8 +1744,8 @@
429 send_do(TELOPT_STATUS, 1);
430 if (env_getvalue("DISPLAY", 0))
431 send_will(TELOPT_XDISPLOC, 1);
432- if (eight)
433- tel_enter_binary(eight);
434+ if (binary)
435+ tel_enter_binary(binary);
436 }
437 #endif /* !defined(TN3270) */
438
439--- a/telnet/terminal.cc
440+++ b/telnet/terminal.cc
441@@ -157,9 +157,11 @@
442 if (localflow)
443 mode |= MODE_FLOW;
444
445- if (my_want_state_is_will(TELOPT_BINARY))
446+ if ((eight & 1) || my_want_state_is_will(TELOPT_BINARY))
447 mode |= MODE_INBIN;
448
449+ if (eight & 2)
450+ mode |= MODE_OUT8;
451 if (his_want_state_is_will(TELOPT_BINARY))
452 mode |= MODE_OUTBIN;
453
454@@ -451,10 +453,13 @@
455 // breaks SunOS.
456 tmp_tc.c_iflag |= ISTRIP;
457 }
458- if (f & MODE_OUTBIN) {
459+ if (f & (MODE_OUTBIN|MODE_OUT8)) {
460 tmp_tc.c_cflag &= ~(CSIZE|PARENB);
461 tmp_tc.c_cflag |= CS8;
462- tmp_tc.c_oflag &= ~OPOST;
463+ if (f & MODE_OUTBIN)
464+ tmp_tc.c_oflag &= ~OPOST;
465+ else
466+ tmp_tc.c_oflag |= OPOST;
467 } else {
468 tmp_tc.c_cflag &= ~(CSIZE|PARENB);
469 tmp_tc.c_cflag |= old_tc.c_cflag & (CSIZE|PARENB);
470@@ -470,7 +475,7 @@
471
472 #ifdef SIGINFO
473 signal(SIGINFO, ayt);
474-#endif SIGINFO
475+#endif /* SIGINFO */
476
477 #if defined(NOKERNINFO)
478 tmp_tc.c_lflag |= NOKERNINFO;
479@@ -506,7 +511,7 @@
480
481 #ifdef SIGINFO
482 signal(SIGINFO, ayt_status);
483-#endif SIGINFO
484+#endif /* SIGINFO */
485
486 #ifdef SIGTSTP
487 signal(SIGTSTP, SIG_DFL);
488--- a/telnetd/ext.h
489+++ b/telnetd/ext.h
490@@ -88,7 +88,7 @@
491 #define netoprintf(fmt, ...) fprintf(netfile, fmt, ## __VA_ARGS__)
492
493 extern int pty, net;
494-extern char *line;
495+extern const char *line;
496 extern int SYNCHing; /* we are in TELNET SYNCH mode */
497
498 void _termstat(void);
499--- a/telnetd/sys_term.c
500+++ b/telnetd/sys_term.c
501@@ -204,17 +204,17 @@
502 *
503 * Returns the file descriptor of the opened pty.
504 */
505-static char linedata[PATH_MAX];
506-char *line = linedata;
507+const char *line;
508
509 static int ptyslavefd=-1;
510
511 int getpty(void) {
512 int masterfd;
513
514- if (openpty(&masterfd, &ptyslavefd, line, NULL, NULL)) {
515+ if (openpty(&masterfd, &ptyslavefd, NULL, NULL, NULL)) {
516 return -1;
517 }
518+ line = ttyname(ptyslavefd);
519 return masterfd;
520 }
521
522@@ -720,25 +720,11 @@
523 * clean up anything that needs to be cleaned up.
524 */
525 void cleanup(int sig) {
526- char *p;
527+ const char *p;
528 (void)sig;
529
530 p = line + sizeof("/dev/") - 1;
531 if (logout(p)) logwtmp(p, "", "");
532-#ifdef PARANOID_TTYS
533- /*
534- * dholland 16-Aug-96 chmod the tty when not in use
535- * This will make it harder to attach unwanted stuff to it
536- * (which is a security risk) but will break some programs.
537- */
538- chmod(line, 0600);
539-#else
540- chmod(line, 0666);
541-#endif
542- chown(line, 0, 0);
543- *p = 'p';
544- chmod(line, 0666);
545- chown(line, 0, 0);
546 shutdown(net, 2);
547 exit(0);
548 }
549--- a/telnetd/telnetd.8
550+++ b/telnetd/telnetd.8
551@@ -161,7 +161,7 @@
552 .It Fl L Ar loginprg
553 This option may be used to specify a different login program.
554 By default,
555-.Pa /usr/sbin/telnetlogin
556+.Pa /usr/lib/telnetlogin
557 is used.
558 .It Fl n
559 Disable
560--- a/telnet/defines.h
561+++ b/telnet/defines.h
562@@ -50,3 +50,5 @@
563 #define MODE_COMMAND_LINE(m) ((m)==-1)
564
565 #define CONTROL(x) ((x)&0x1f) /* CTRL(x) is not portable */
566+
567+#define MODE_OUT8 0x8000 /* binary mode sans -opost */
568--- a/telnet/proto.h
569+++ b/telnet/proto.h
570@@ -13,7 +13,7 @@
571 void auth_encrypt_user(char *);
572 void auth_name(unsigned char *, int);
573 void auth_printsub(unsigned char *, int, unsigned char *, int);
574-void cmdrc(const char *m1, const char *m2);
575+void cmdrc(const char *, const char *, const char *);
576 void env_init(void);
577 int getconnmode(void);
578 void init_network(void);
579--- a/telnet/externs.h
580+++ b/telnet/externs.h
581@@ -48,9 +48,7 @@
582 typedef unsigned char cc_t;
583 #endif
584
585-#ifdef __linux__
586 #include <unistd.h> /* get _POSIX_VDISABLE */
587-#endif
588
589 #ifndef _POSIX_VDISABLE
590 #error "Please fix externs.h to define _POSIX_VDISABLE"
591@@ -60,7 +58,8 @@
592
593 extern int autologin; /* Autologin enabled */
594 extern int skiprc; /* Don't process the ~/.telnetrc file */
595-extern int eight; /* use eight bit mode (binary in and/or out */
596+extern int eight; /* use eight bit mode (binary in and/or out) */
597+extern int binary; /* use binary option (in and/or out) */
598 extern int flushout; /* flush output */
599 extern int connected; /* Are we connected to the other side? */
600 extern int globalmode; /* Mode tty should be in */
601@@ -225,6 +224,8 @@
602
603 //#if 0
604 extern struct termios new_tc;
605+extern struct termios old_tc;
606+
607
608 #define termEofChar new_tc.c_cc[VEOF]
609 #define termEraseChar new_tc.c_cc[VERASE]