From 6d21a249dff42ac16ff30dea642c88936ef736e8 Mon Sep 17 00:00:00 2001 From: ru Date: Thu, 17 Jun 1999 09:24:37 +0000 Subject: [PATCH] Merge from non-crypto version: - "-N" option - "-E" security fix - "-s src_addr" option Requested by: markm git-svn-id: http://svn0.us-east.freebsd.org/base/head/contrib/telnet@47973 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f --- telnet/commands.c | 43 +++++++++++++++++++++++++++++++++++++++---- telnet/externs.h | 1 + telnet/main.c | 31 ++++++++++++++++++++++--------- telnet/telnet.1 | 12 +++++++++++- telnet/telnet.c | 3 ++- 5 files changed, 75 insertions(+), 15 deletions(-) diff --git a/telnet/commands.c b/telnet/commands.c index 8073fb5..40e7315 100644 --- a/telnet/commands.c +++ b/telnet/commands.c @@ -1125,7 +1125,7 @@ unsetcmd(argc, argv) #ifdef KLUDGELINEMODE extern int kludgelinemode; - static void + static int dokludgemode() { kludgelinemode = 1; @@ -2277,7 +2277,7 @@ tn(argc, argv) char *argv[]; { register struct hostent *host = 0; - struct sockaddr_in sin; + struct sockaddr_in sin, src_sin; struct servent *sp = 0; unsigned long temp; extern char *inet_ntoa(); @@ -2286,6 +2286,7 @@ tn(argc, argv) unsigned long sourceroute(), srlen; #endif char *cmd, *hostp = 0, *portp = 0, *user = 0; + char *src_addr = NULL; /* clear the socket address prior to use */ memset((char *)&sin, 0, sizeof(sin)); @@ -2321,6 +2322,14 @@ tn(argc, argv) autologin = 1; continue; } + if (strcmp(*argv, "-s") == 0) { + --argc; ++argv; + if (argc == 0) + goto usage; + src_addr = *argv++; + --argc; + continue; + } if (hostp == 0) { hostp = *argv++; --argc; @@ -2332,13 +2341,31 @@ tn(argc, argv) continue; } usage: - printf("usage: %s [-l user] [-a] host-name [port]\n", cmd); + printf("usage: %s [-l user] [-a] [-s src_addr] host-name [port]\n", cmd); setuid(getuid()); return 0; } if (hostp == 0) goto usage; + if (src_addr != NULL) { + bzero((char *)&src_sin, sizeof(src_sin)); + src_sin.sin_family = AF_INET; + if (!inet_aton(src_addr, &src_sin.sin_addr)) { + host = gethostbyname2(src_addr, AF_INET); + if (host == NULL) { + herror(src_addr); + return 0; + } + if (host->h_length != sizeof(src_sin.sin_addr)) { + fprintf(stderr, "telnet: gethostbyname2: invalid address\n"); + return 0; + } + memcpy((void *)&src_sin.sin_addr, (void *)host->h_addr_list[0], + sizeof(src_sin.sin_addr)); + } + } + #if defined(IP_OPTIONS) && defined(IPPROTO_IP) if (hostp[0] == '@' || hostp[0] == '!') { if ((hostname = strrchr(hostp, ':')) == NULL) @@ -2364,7 +2391,8 @@ tn(argc, argv) if (temp != INADDR_NONE) { sin.sin_addr.s_addr = temp; sin.sin_family = AF_INET; - host = gethostbyaddr((char *)&temp, sizeof(temp), AF_INET); + if (doaddrlookup) + host = gethostbyaddr((char *)&temp, sizeof(temp), AF_INET); if (host) (void) strncpy(_hostname, host->h_name, sizeof(_hostname)); else @@ -2460,6 +2488,13 @@ tn(argc, argv) perror("setsockopt (SO_DEBUG)"); } + if (src_addr != NULL) { + if (bind(net, (struct sockaddr *)&src_sin, sizeof(src_sin)) == -1) { + perror("bind"); + return 0; + } + } + if (connect(net, (struct sockaddr *)&sin, sizeof (sin)) < 0) { #if defined(h_addr) /* In 4.3, this is a #define */ if (host && host->h_addr_list[1]) { diff --git a/telnet/externs.h b/telnet/externs.h index a834c61..0c6894f 100644 --- a/telnet/externs.h +++ b/telnet/externs.h @@ -146,6 +146,7 @@ extern int termdata, /* Print out terminal data flow */ #endif /* defined(unix) */ debug, /* Debug level */ + doaddrlookup, /* do a reverse lookup? */ clienteof; /* Client received EOF */ extern cc_t escape; /* Escape to command mode */ diff --git a/telnet/main.c b/telnet/main.c index 9049385..2dc05fd 100644 --- a/telnet/main.c +++ b/telnet/main.c @@ -95,20 +95,22 @@ usage() fprintf(stderr, "Usage: %s %s%s%s%s\n", prompt, #ifdef AUTHENTICATION - "[-8] [-E] [-K] [-L] [-S tos] [-X atype] [-a] [-c] [-d] [-e char]", - "\n\t[-k realm] [-l user] [-f/-F] [-n tracefile] ", + "[-8] [-E] [-K] [-L] [-N] [-S tos] [-X atype] [-a] [-c] [-d]", + "\n\t[-e char] [-k realm] [-l user] [-f/-F] [-n tracefile] ", #else - "[-8] [-E] [-L] [-S tos] [-a] [-c] [-d] [-e char] [-l user]", - "\n\t[-n tracefile]", + "[-8] [-E] [-L] [-N] [-S tos] [-a] [-c] [-d] [-e char] [-l user]", + "\n\t[-n tracefile] ", #endif #if defined(TN3270) && defined(unix) # ifdef AUTHENTICATION - "[-noasynch] [-noasynctty]\n\t[-noasyncnet] [-r] [-t transcom] ", + "[-noasynch] [-noasynctty]\n\t" + "[-noasyncnet] [-r] [-s src_addr] [-t transcom] ", # else - "[-noasynch] [-noasynctty] [-noasyncnet] [-r]\n\t[-t transcom]", + "[-noasynch] [-noasynctty] [-noasyncnet] [-r]\n\t" + "[-s src_addr] [-t transcom]", # endif #else - "[-r] ", + "[-r] [-s src_addr] ", #endif #ifdef ENCRYPTION "[-x] [host-name [port]]" @@ -132,6 +134,7 @@ main(argc, argv) extern int optind; int ch; char *user, *strrchr(); + char *src_addr = NULL; #ifdef FORWARD extern int forward_flags; #endif /* FORWARD */ @@ -153,7 +156,7 @@ main(argc, argv) rlogin = (strncmp(prompt, "rlog", 4) == 0) ? '~' : _POSIX_VDISABLE; autologin = -1; - while ((ch = getopt(argc, argv, "8EKLS:X:acde:fFk:l:n:rt:x")) != EOF) { + while ((ch = getopt(argc, argv, "8EKLNS:X:acde:fFk:l:n:rs:t:x")) != EOF) { switch(ch) { case '8': eight = 3; /* binary output and input */ @@ -169,6 +172,9 @@ main(argc, argv) case 'L': eight |= 2; /* binary output only */ break; + case 'N': + doaddrlookup = 0; + break; case 'S': { #ifdef HAS_GETTOS @@ -270,6 +276,9 @@ main(argc, argv) case 'r': rlogin = '~'; break; + case 's': + src_addr = optarg; + break; case 't': #if defined(TN3270) && defined(unix) transcom = tline; @@ -303,7 +312,7 @@ main(argc, argv) argv += optind; if (argc) { - char *args[7], **argp = args; + char *args[9], **argp = args; if (argc > 2) usage(); @@ -312,6 +321,10 @@ main(argc, argv) *argp++ = "-l"; *argp++ = user; } + if (src_addr) { + *argp++ = "-s"; + *argp++ = src_addr; + } *argp++ = argv[0]; /* host */ if (argc > 1) *argp++ = argv[1]; /* port */ diff --git a/telnet/telnet.1 b/telnet/telnet.1 index b996fea..06b2b8e 100644 --- a/telnet/telnet.1 +++ b/telnet/telnet.1 @@ -41,13 +41,14 @@ protocol .Sh SYNOPSIS .Nm telnet -.Op Fl 8EFKLacdfrx +.Op Fl 8EFKLNacdfrx .Op Fl S Ar tos .Op Fl X Ar authtype .Op Fl e Ar escapechar .Op Fl k Ar realm .Op Fl l Ar user .Op Fl n Ar tracefile +.Op Fl s Ar src_addr .Oo .Ar host .Op port @@ -91,6 +92,9 @@ Specifies no automatic login to the remote system. .It Fl L Specifies an 8-bit data path on output. This causes the BINARY option to be negotiated on output. +.It Fl N +Prevents IP address to name lookup when destination host is given +as an IP address. .It Fl S Ar tos Sets the IP type-of-service (TOS) option for the telnet connection to the value @@ -173,6 +177,12 @@ Specifies a user interface similar to In this mode, the escape character is set to the tilde (~) character, unless modified by the -e option. +.It Fl s Ar src_addr +Set the source IP address for the +.Nm +connection to +.Ar src_addr , +which can be an IP address or a host name. .It Fl x Turns on encryption of the data stream if possible. This option is not available outside of the United States and diff --git a/telnet/telnet.c b/telnet/telnet.c index 1c1ee33..e171685 100644 --- a/telnet/telnet.c +++ b/telnet/telnet.c @@ -116,6 +116,7 @@ int donebinarytoggle, /* the user has put us in binary */ dontlecho, /* do we suppress local echoing right now? */ globalmode, + doaddrlookup = 1, /* do a reverse address lookup? */ clienteof = 0; char *prompt = 0; @@ -2083,7 +2084,7 @@ telsnd() } if ((sc == '\n') || (sc == '\r')) bol = 1; - } else if (sc == escape) { + } else if (escape != _POSIX_VDISABLE && sc == escape) { /* * Double escape is a pass through of a single escape character. */