aboutsummaryrefslogtreecommitdiff
path: root/ntpdc/ntpdc.c
diff options
context:
space:
mode:
Diffstat (limited to 'ntpdc/ntpdc.c')
-rw-r--r--ntpdc/ntpdc.c555
1 files changed, 273 insertions, 282 deletions
diff --git a/ntpdc/ntpdc.c b/ntpdc/ntpdc.c
index 9126533396aa..bffaf09a02c1 100644
--- a/ntpdc/ntpdc.c
+++ b/ntpdc/ntpdc.c
@@ -3,7 +3,7 @@
*/
#include <stdio.h>
-
+#include <stddef.h>
#include <ctype.h>
#include <signal.h>
#include <setjmp.h>
@@ -12,25 +12,20 @@
#include "ntp_select.h"
#include "ntp_io.h"
#include "ntp_stdlib.h"
-/* Don't include ISC's version of IPv6 variables and structures */
-#define ISC_IPV6_H 1
+#include "ntp_assert.h"
+#include "ntp_lineedit.h"
#include "isc/net.h"
#include "isc/result.h"
+#include <ssl_applink.c>
+#include "ntp_libopts.h"
#include "ntpdc-opts.h"
#ifdef SYS_WINNT
# include <Mswsock.h>
# include <io.h>
-#else
-# define closesocket close
#endif /* SYS_WINNT */
-#if defined(HAVE_LIBREADLINE) || defined (HAVE_LIBEDIT)
-# include <readline/readline.h>
-# include <readline/history.h>
-#endif /* HAVE_LIBREADLINE || HAVE_LIBEDIT */
-
#ifdef SYS_VXWORKS
/* vxWorks needs mode flag -casey*/
# define open(name, flags) open(name, flags, 0777)
@@ -56,12 +51,8 @@ static const char * prompt = "ntpdc> "; /* prompt to ask him about */
static u_long info_auth_keyid;
static int keyid_entered = 0;
-/*
- * Type of key md5
- */
-#define KEY_TYPE_MD5 4
-
-static int info_auth_keytype = KEY_TYPE_MD5; /* MD5 */
+static int info_auth_keytype = NID_md5; /* MD5 */
+static size_t info_auth_hashlen = 16; /* MD5 */
u_long current_time; /* needed by authkeys; not used */
/*
@@ -69,42 +60,38 @@ u_long current_time; /* needed by authkeys; not used */
*/
s_char sys_precision; /* local clock precision (log2 s) */
-int ntpdcmain P((int, char **));
+int ntpdcmain (int, char **);
/*
* Built in command handler declarations
*/
-static int openhost P((const char *));
-static int sendpkt P((char *, int));
-static void growpktdata P((void));
-static int getresponse P((int, int, int *, int *, char **, int));
-static int sendrequest P((int, int, int, int, int, char *));
-static void getcmds P((void));
-static RETSIGTYPE abortcmd P((int));
-static void docmd P((const char *));
-static void tokenize P((const char *, char **, int *));
-static int findcmd P((char *, struct xcmd *, struct xcmd *, struct xcmd **));
-static int getarg P((char *, int, arg_v *));
-static int getnetnum P((const char *, struct sockaddr_storage *, char *, int));
-static void help P((struct parse *, FILE *));
-#ifdef QSORT_USES_VOID_P
-static int helpsort P((const void *, const void *));
-#else
-static int helpsort P((char **, char **));
-#endif
-static void printusage P((struct xcmd *, FILE *));
-static void timeout P((struct parse *, FILE *));
-static void my_delay P((struct parse *, FILE *));
-static void host P((struct parse *, FILE *));
-static void keyid P((struct parse *, FILE *));
-static void keytype P((struct parse *, FILE *));
-static void passwd P((struct parse *, FILE *));
-static void hostnames P((struct parse *, FILE *));
-static void setdebug P((struct parse *, FILE *));
-static void quit P((struct parse *, FILE *));
-static void version P((struct parse *, FILE *));
-static void warning P((const char *, const char *, const char *));
-static void error P((const char *, const char *, const char *));
-static u_long getkeyid P((const char *));
+static int openhost (const char *);
+static int sendpkt (void *, size_t);
+static void growpktdata (void);
+static int getresponse (int, int, int *, int *, char **, int);
+static int sendrequest (int, int, int, u_int, size_t, char *);
+static void getcmds (void);
+static RETSIGTYPE abortcmd (int);
+static void docmd (const char *);
+static void tokenize (const char *, char **, int *);
+static int findcmd (char *, struct xcmd *, struct xcmd *, struct xcmd **);
+static int getarg (char *, int, arg_v *);
+static int getnetnum (const char *, sockaddr_u *, char *, int);
+static void help (struct parse *, FILE *);
+static int helpsort (const void *, const void *);
+static void printusage (struct xcmd *, FILE *);
+static void timeout (struct parse *, FILE *);
+static void my_delay (struct parse *, FILE *);
+static void host (struct parse *, FILE *);
+static void keyid (struct parse *, FILE *);
+static void keytype (struct parse *, FILE *);
+static void passwd (struct parse *, FILE *);
+static void hostnames (struct parse *, FILE *);
+static void setdebug (struct parse *, FILE *);
+static void quit (struct parse *, FILE *);
+static void version (struct parse *, FILE *);
+static void warning (const char *, const char *, const char *);
+static void error (const char *, const char *, const char *);
+static u_long getkeyid (const char *);
@@ -159,10 +146,10 @@ static struct xcmd builtins[] = {
/*
* Default values we use.
*/
+#define DEFHOST "localhost" /* default host name */
#define DEFTIMEOUT (5) /* 5 second time out */
#define DEFSTIMEOUT (2) /* 2 second time out after first */
#define DEFDELAY 0x51EB852 /* 20 milliseconds, l_fp fraction */
-#define DEFHOST "localhost" /* default host name */
#define LENHOSTNAME 256 /* host name is 256 characters long */
#define MAXCMDS 100 /* maximum commands on cmd line */
#define MAXHOSTS 200 /* maximum hosts on cmd line */
@@ -173,8 +160,8 @@ static struct xcmd builtins[] = {
/*
* Some variables used and manipulated locally
*/
-static struct timeval tvout = { DEFTIMEOUT, 0 }; /* time out for reads */
-static struct timeval tvsout = { DEFSTIMEOUT, 0 }; /* secondary time out */
+static struct sock_timeval tvout = { DEFTIMEOUT, 0 }; /* time out for reads */
+static struct sock_timeval tvsout = { DEFSTIMEOUT, 0 };/* secondary time out */
static l_fp delay_time; /* delay time */
static char currenthost[LENHOSTNAME]; /* current host name */
int showhostnames = 1; /* show host names by default */
@@ -185,18 +172,6 @@ static SOCKET sockfd; /* fd socket is opened on */
static int havehost = 0; /* set to 1 when host open */
int s_port = 0;
-#if defined (SYS_WINNT) || defined (SYS_VXWORKS)
-char password[9];
-#endif /* SYS_WINNT || SYS_VXWORKS */
-
-#ifdef SYS_WINNT
-DWORD NumberOfBytesWritten;
-
-HANDLE TimerThreadHandle = NULL; /* 1998/06/03 - Used in ntplib/machines.c */
-void timer(void) { ; }; /* 1998/06/03 - Used in ntplib/machines.c */
-
-#endif /* SYS_WINNT */
-
/*
* Holds data returned from queries. We allocate INITDATASIZE
* octets to begin with, increasing this as we need to.
@@ -306,38 +281,27 @@ ntpdcmain(
taskPrioritySet(taskIdSelf(), 100 );
#endif
-#ifdef SYS_WINNT
- if (!Win32InitSockets())
- {
- fprintf(stderr, "No useable winsock.dll:");
- exit(1);
- }
-#endif /* SYS_WINNT */
+ init_lib(); /* sets up ipv4_works, ipv6_works */
+ ssl_applink();
- /* Check to see if we have IPv6. Otherwise force the -4 flag */
- if (isc_net_probeipv6() != ISC_R_SUCCESS) {
+ /* Check to see if we have IPv6. Otherwise default to IPv4 */
+ if (!ipv6_works)
ai_fam_default = AF_INET;
- }
progname = argv[0];
{
- int optct = optionProcess(&ntpdcOptions, argc, argv);
+ int optct = ntpOptionProcess(&ntpdcOptions, argc, argv);
argc -= optct;
argv += optct;
}
- switch (WHICH_IDX_IPV4) {
- case INDEX_OPT_IPV4:
+ if (HAVE_OPT(IPV4))
ai_fam_templ = AF_INET;
- break;
- case INDEX_OPT_IPV6:
+ else if (HAVE_OPT(IPV6))
ai_fam_templ = AF_INET6;
- break;
- default:
+ else
ai_fam_templ = ai_fam_default;
- break;
- }
if (HAVE_OPT(COMMAND)) {
int cmdct = STACKCT_OPT( COMMAND );
@@ -446,12 +410,8 @@ ntpdcmain(
/*
* Initialize the packet data buffer
*/
- pktdata = (char *)malloc(INITDATASIZE);
- if (pktdata == NULL) {
- (void) fprintf(stderr, "%s: malloc() failed!\n", progname);
- exit(1);
- }
pktdatasize = INITDATASIZE;
+ pktdata = emalloc(INITDATASIZE);
if (numcmds == 0) {
(void) openhost(chosts[0]);
@@ -499,10 +459,14 @@ openhost(
if (*cp == '[') {
cp++;
- for(i = 0; *cp != ']'; cp++, i++)
- name[i] = *cp;
- name[i] = '\0';
- hname = name;
+ for (i = 0; *cp && *cp != ']'; cp++, i++)
+ name[i] = *cp;
+ if (*cp == ']') {
+ name[i] = '\0';
+ hname = name;
+ } else {
+ return 0;
+ }
}
/*
@@ -517,7 +481,7 @@ openhost(
hints.ai_family = ai_fam_templ;
hints.ai_protocol = IPPROTO_UDP;
hints.ai_socktype = SOCK_DGRAM;
- hints.ai_flags = AI_NUMERICHOST;
+ hints.ai_flags = Z_AI_NUMERICHOST;
a_info = getaddrinfo(hname, service, &hints, &ai);
if (a_info == EAI_NONAME
@@ -543,8 +507,14 @@ openhost(
return 0;
}
+ /*
+ * getaddrinfo() has returned without error so ai should not
+ * be NULL.
+ */
+ NTP_INSIST(ai != NULL);
+
if (ai->ai_canonname == NULL) {
- strncpy(temphost, stoa((struct sockaddr_storage *)ai->ai_addr),
+ strncpy(temphost, stoa((sockaddr_u *)ai->ai_addr),
LENHOSTNAME);
temphost[LENHOSTNAME-1] = '\0';
} else {
@@ -619,8 +589,8 @@ openhost(
ai->ai_addrlen) == -1)
#endif /* SYS_VXWORKS */
error("connect", "", "");
- if (ai != NULL)
- freeaddrinfo(ai);
+
+ freeaddrinfo(ai);
havehost = 1;
req_pkt_size = REQ_LEN_NOMAC;
impl_ver = IMPL_XNTPD;
@@ -634,11 +604,11 @@ openhost(
*/
static int
sendpkt(
- char *xdata,
- int xdatalen
+ void * xdata,
+ size_t xdatalen
)
{
- if (send(sockfd, xdata, (size_t)xdatalen, 0) == -1) {
+ if (send(sockfd, xdata, xdatalen, 0) == -1) {
warning("write to %s failed", currenthost, "");
return -1;
}
@@ -654,11 +624,7 @@ static void
growpktdata(void)
{
pktdatasize += INCDATASIZE;
- pktdata = (char *)realloc(pktdata, (unsigned)pktdatasize);
- if (pktdata == 0) {
- (void) fprintf(stderr, "%s: realloc() failed!\n", progname);
- exit(1);
- }
+ pktdata = erealloc(pktdata, (size_t)pktdatasize);
}
@@ -676,7 +642,7 @@ getresponse(
)
{
struct resp_pkt rpkt;
- struct timeval tvo;
+ struct sock_timeval tvo;
int items;
int i;
int size;
@@ -710,9 +676,9 @@ getresponse(
again:
if (firstpkt)
- tvo = tvout;
+ tvo = tvout;
else
- tvo = tvsout;
+ tvo = tvsout;
FD_SET(sockfd, &fds);
n = select(sockfd+1, &fds, (fd_set *)0, (fd_set *)0, &tvo);
@@ -823,11 +789,12 @@ getresponse(
pad = esize - size;
else
pad = 0;
- if ((datasize = items*size) > (n-RESP_HEADER_SIZE)) {
+ datasize = items * size;
+ if ((size_t)datasize > (n-RESP_HEADER_SIZE)) {
if (debug)
printf(
- "Received items %d, size %d (total %d), data in packet is %d\n",
- items, size, datasize, n-RESP_HEADER_SIZE);
+ "Received items %d, size %d (total %d), data in packet is %lu\n",
+ items, size, datasize, (u_long)(n-RESP_HEADER_SIZE));
goto again;
}
@@ -869,7 +836,7 @@ getresponse(
if ((datap + datasize + (pad * items)) > (pktdata + pktdatasize)) {
int offset = datap - pktdata;
growpktdata();
- *rdata = pktdata; /* might have been realloced ! */
+ *rdata = pktdata; /* might have been realloced ! */
datap = pktdata + offset;
}
/*
@@ -877,9 +844,9 @@ getresponse(
* items. This is so we can play nice with older implementations
*/
- tmp_data = (char *)rpkt.data;
- for(i = 0; i <items; i++){
- memmove(datap, tmp_data, (unsigned)size);
+ tmp_data = rpkt.data;
+ for (i = 0; i < items; i++) {
+ memcpy(datap, tmp_data, (unsigned)size);
tmp_data += size;
memset(datap + size, 0, pad);
datap += size + pad;
@@ -897,36 +864,62 @@ getresponse(
*/
++numrecv;
if (numrecv <= lastseq)
- goto again;
+ goto again;
return INFO_OKAY;
}
/*
* sendrequest - format and send a request packet
+ *
+ * Historically, ntpdc has used a fixed-size request packet regardless
+ * of the actual payload size. When authenticating, the timestamp, key
+ * ID, and digest have been placed just before the end of the packet.
+ * With the introduction in late 2009 of support for authenticated
+ * ntpdc requests using larger 20-octet digests (vs. 16 for MD5), we
+ * come up four bytes short.
+ *
+ * To maintain interop while allowing for larger digests, the behavior
+ * is unchanged when using 16-octet digests. For larger digests, the
+ * timestamp, key ID, and digest are placed immediately following the
+ * request payload, with the overall packet size variable. ntpd can
+ * distinguish 16-octet digests by the overall request size being
+ * REQ_LEN_NOMAC + 4 + 16 with the auth bit enabled. When using a
+ * longer digest, that request size should be avoided.
+ *
+ * With the form used with 20-octet and larger digests, the timestamp,
+ * key ID, and digest are located by ntpd relative to the start of the
+ * packet, and the size of the digest is then implied by the packet
+ * size.
*/
static int
sendrequest(
int implcode,
int reqcode,
int auth,
- int qitems,
- int qsize,
+ u_int qitems,
+ size_t qsize,
char *qdata
)
{
struct req_pkt qpkt;
- int datasize;
+ size_t datasize;
+ size_t reqsize;
+ u_long key_id;
+ l_fp ts;
+ l_fp * ptstamp;
+ int maclen;
+ char * pass;
- memset((char *)&qpkt, 0, sizeof qpkt);
+ memset(&qpkt, 0, sizeof(qpkt));
qpkt.rm_vn_mode = RM_VN_MODE(0, 0, 0);
qpkt.implementation = (u_char)implcode;
qpkt.request = (u_char)reqcode;
datasize = qitems * qsize;
- if (datasize != 0 && qdata != NULL) {
- memmove((char *)qpkt.data, qdata, (unsigned)datasize);
+ if (datasize && qdata != NULL) {
+ memcpy(qpkt.data, qdata, datasize);
qpkt.err_nitems = ERR_NITEMS(0, qitems);
qpkt.mbz_itemsize = MBZ_ITEMSIZE(qsize);
} else {
@@ -936,53 +929,61 @@ sendrequest(
if (!auth || (keyid_entered && info_auth_keyid == 0)) {
qpkt.auth_seq = AUTH_SEQ(0, 0);
- return sendpkt((char *)&qpkt, req_pkt_size);
- } else {
- l_fp ts;
- int maclen = 0;
- const char *pass = "\0";
- struct req_pkt_tail *qpktail;
-
- qpktail = (struct req_pkt_tail *)((char *)&qpkt + req_pkt_size
- + MAX_MAC_LEN - sizeof(struct req_pkt_tail));
+ return sendpkt(&qpkt, req_pkt_size);
+ }
- if (info_auth_keyid == 0) {
- if (((struct conf_peer *)qpkt.data)->keyid > 0)
- info_auth_keyid = ((struct conf_peer *)qpkt.data)->keyid;
- else {
- maclen = getkeyid("Keyid: ");
- if (maclen == 0) {
- (void) fprintf(stderr,
- "Invalid key identifier\n");
- return 1;
- }
- info_auth_keyid = maclen;
- }
+ if (info_auth_keyid == 0) {
+ key_id = getkeyid("Keyid: ");
+ if (!key_id) {
+ fprintf(stderr, "Invalid key identifier\n");
+ return 1;
}
- if (!authistrusted(info_auth_keyid)) {
- pass = getpass("MD5 Password: ");
- if (*pass == '\0') {
- (void) fprintf(stderr,
- "Invalid password\n");
- return (1);
- }
+ info_auth_keyid = key_id;
+ }
+ if (!authistrusted(info_auth_keyid)) {
+ pass = getpass_keytype(info_auth_keytype);
+ if ('\0' == pass[0]) {
+ fprintf(stderr, "Invalid password\n");
+ return 1;
}
- authusekey(info_auth_keyid, info_auth_keytype, (const u_char *)pass);
+ authusekey(info_auth_keyid, info_auth_keytype,
+ (u_char *)pass);
authtrust(info_auth_keyid, 1);
- qpkt.auth_seq = AUTH_SEQ(1, 0);
- qpktail->keyid = htonl(info_auth_keyid);
- get_systime(&ts);
- L_ADD(&ts, &delay_time);
- HTONL_FP(&ts, &qpktail->tstamp);
- maclen = authencrypt(info_auth_keyid, (u_int32 *)&qpkt,
- req_pkt_size);
- if (maclen == 0) {
- (void) fprintf(stderr, "Key not found\n");
- return (1);
- }
- return sendpkt((char *)&qpkt, (int)(req_pkt_size + maclen));
}
- /*NOTREACHED*/
+ qpkt.auth_seq = AUTH_SEQ(1, 0);
+ if (info_auth_hashlen > 16) {
+ /*
+ * Only ntpd which expects REQ_LEN_NOMAC plus maclen
+ * octets in an authenticated request using a 16 octet
+ * digest (that is, a newer ntpd) will handle digests
+ * larger than 16 octets, so for longer digests, do
+ * not attempt to shorten the requests for downlevel
+ * ntpd compatibility.
+ */
+ if (REQ_LEN_NOMAC != req_pkt_size)
+ return 1;
+ reqsize = REQ_LEN_HDR + datasize + sizeof(*ptstamp);
+ /* align to 32 bits */
+ reqsize = (reqsize + 3) & ~3;
+ } else
+ reqsize = req_pkt_size;
+ ptstamp = (void *)((char *)&qpkt + reqsize);
+ ptstamp--;
+ get_systime(&ts);
+ L_ADD(&ts, &delay_time);
+ HTONL_FP(&ts, ptstamp);
+ maclen = authencrypt(info_auth_keyid, (void *)&qpkt, reqsize);
+ if (!maclen) {
+ fprintf(stderr, "Key not found\n");
+ return 1;
+ } else if (maclen != (info_auth_hashlen + sizeof(keyid_t))) {
+ fprintf(stderr,
+ "%d octet MAC, %lu expected with %lu octet digest\n",
+ maclen, (u_long)(info_auth_hashlen + sizeof(keyid_t)),
+ (u_long)info_auth_hashlen);
+ return 1;
+ }
+ return sendpkt(&qpkt, reqsize + maclen);
}
@@ -1007,7 +1008,7 @@ doquery(
int res;
char junk[512];
fd_set fds;
- struct timeval tvzero;
+ struct sock_timeval tvzero;
/*
* Check to make sure host is open
@@ -1041,7 +1042,7 @@ again:
*/
res = sendrequest(implcode, reqcode, auth, qitems, qsize, qdata);
if (res != 0)
- return res;
+ return res;
/*
* Get the response. If we got a standard error, print a message
@@ -1079,36 +1080,36 @@ again:
/* log error message if not told to be quiet */
if ((res > 0) && (((1 << res) & quiet_mask) == 0)) {
switch(res) {
- case INFO_ERR_IMPL:
+ case INFO_ERR_IMPL:
/* Give us a chance to try the older implementation. */
if (implcode == IMPL_XNTPD)
break;
(void) fprintf(stderr,
"***Server implementation incompatable with our own\n");
break;
- case INFO_ERR_REQ:
+ case INFO_ERR_REQ:
(void) fprintf(stderr,
"***Server doesn't implement this request\n");
break;
- case INFO_ERR_FMT:
+ case INFO_ERR_FMT:
(void) fprintf(stderr,
"***Server reports a format error in the received packet (shouldn't happen)\n");
break;
- case INFO_ERR_NODATA:
+ case INFO_ERR_NODATA:
(void) fprintf(stderr,
"***Server reports data not found\n");
break;
- case INFO_ERR_AUTH:
+ case INFO_ERR_AUTH:
(void) fprintf(stderr, "***Permission denied\n");
break;
- case ERR_TIMEOUT:
+ case ERR_TIMEOUT:
(void) fprintf(stderr, "***Request timed out\n");
break;
- case ERR_INCOMPLETE:
+ case ERR_INCOMPLETE:
(void) fprintf(stderr,
"***Response from server was incomplete\n");
break;
- default:
+ default:
(void) fprintf(stderr,
"***Server returns unknown error code %d\n", res);
break;
@@ -1124,33 +1125,20 @@ again:
static void
getcmds(void)
{
-#if defined(HAVE_LIBREADLINE) || defined(HAVE_LIBEDIT)
- char *line;
+ char * line;
+ int count;
+
+ ntp_readline_init(interactive ? prompt : NULL);
for (;;) {
- if ((line = readline(interactive?prompt:"")) == NULL) return;
- if (*line) add_history(line);
+ line = ntp_readline(&count);
+ if (NULL == line)
+ break;
docmd(line);
free(line);
}
-#else /* not (HAVE_LIBREADLINE || HAVE_LIBEDIT) */
- char line[MAXLINE];
- for (;;) {
- if (interactive) {
-#ifdef VMS /* work around a problem with mixing stdout & stderr */
- fputs("",stdout);
-#endif
- (void) fputs(prompt, stderr);
- (void) fflush(stderr);
- }
-
- if (fgets(line, sizeof line, stdin) == NULL)
- return;
-
- docmd(line);
- }
-#endif /* not HAVE_LIBREADLINE || HAVE_LIBEDIT */
+ ntp_readline_uninit();
}
@@ -1482,41 +1470,47 @@ getarg(
static int
getnetnum(
const char *hname,
- struct sockaddr_storage *num,
+ sockaddr_u *num,
char *fullhost,
int af
)
{
- int sockaddr_len;
struct addrinfo hints, *ai = NULL;
- sockaddr_len = (af == AF_INET)
- ? sizeof(struct sockaddr_in)
- : sizeof(struct sockaddr_in6);
- memset((char *)&hints, 0, sizeof(struct addrinfo));
+ ZERO(hints);
hints.ai_flags = AI_CANONNAME;
#ifdef AI_ADDRCONFIG
hints.ai_flags |= AI_ADDRCONFIG;
#endif
- /* decodenetnum only works with addresses */
+ /*
+ * decodenetnum only works with addresses, but handles syntax
+ * that getaddrinfo doesn't: [2001::1]:1234
+ */
if (decodenetnum(hname, num)) {
- if (fullhost != 0) {
- getnameinfo((struct sockaddr *)num, sockaddr_len,
- fullhost, sizeof(fullhost), NULL, 0,
- NI_NUMERICHOST);
- }
+ if (fullhost != NULL)
+ getnameinfo(&num->sa, SOCKLEN(num), fullhost,
+ LENHOSTNAME, NULL, 0, 0);
return 1;
} else if (getaddrinfo(hname, "ntp", &hints, &ai) == 0) {
- memmove((char *)num, ai->ai_addr, ai->ai_addrlen);
- if (fullhost != 0)
- (void) strcpy(fullhost, ai->ai_canonname);
+ NTP_INSIST(sizeof(*num) >= ai->ai_addrlen);
+ memcpy(num, ai->ai_addr, ai->ai_addrlen);
+ if (fullhost != NULL) {
+ if (ai->ai_canonname != NULL) {
+ strncpy(fullhost, ai->ai_canonname,
+ LENHOSTNAME);
+ fullhost[LENHOSTNAME - 1] = '\0';
+ } else {
+ getnameinfo(&num->sa, SOCKLEN(num),
+ fullhost, LENHOSTNAME, NULL,
+ 0, 0);
+ }
+ }
return 1;
- } else {
- (void) fprintf(stderr, "***Can't find host %s\n", hname);
- return 0;
}
- /*NOTREACHED*/
+ fprintf(stderr, "***Can't find host %s\n", hname);
+
+ return 0;
}
/*
@@ -1525,13 +1519,13 @@ getnetnum(
*/
char *
nntohost(
- struct sockaddr_storage *netnum
+ sockaddr_u *netnum
)
{
if (!showhostnames)
- return stoa(netnum);
+ return stoa(netnum);
- if ((netnum->ss_family == AF_INET) && ISREFCLOCKADR(netnum))
+ if (ISREFCLOCKADR(netnum))
return refnumtoa(netnum);
return socktohost(netnum);
}
@@ -1553,58 +1547,51 @@ help(
struct xcmd *xcp;
char *cmd;
const char *list[100];
- int word, words;
- int row, rows;
- int col, cols;
+ size_t word, words;
+ size_t row, rows;
+ size_t col, cols;
+ size_t length;
if (pcmd->nargs == 0) {
words = 0;
for (xcp = builtins; xcp->keyword != 0; xcp++) {
if (*(xcp->keyword) != '?')
- list[words++] = xcp->keyword;
+ list[words++] = xcp->keyword;
}
- for (xcp = opcmds; xcp->keyword != 0; xcp++)
- list[words++] = xcp->keyword;
+ for (xcp = opcmds; xcp->keyword != 0; xcp++)
+ list[words++] = xcp->keyword;
- qsort(
-#ifdef QSORT_USES_VOID_P
- (void *)
-#else
- (char *)
-#endif
- (list), (size_t)(words), sizeof(char *), helpsort);
+ qsort((void *)list, (size_t)words, sizeof(list[0]),
+ helpsort);
col = 0;
for (word = 0; word < words; word++) {
- int length = strlen(list[word]);
- if (col < length) {
- col = length;
- }
+ length = strlen(list[word]);
+ col = max(col, length);
}
cols = SCREENWIDTH / ++col;
- rows = (words + cols - 1) / cols;
+ rows = (words + cols - 1) / cols;
- (void) fprintf(fp, "ntpdc commands:\n");
+ fprintf(fp, "ntpdc commands:\n");
for (row = 0; row < rows; row++) {
- for (word = row; word < words; word += rows) {
- (void) fprintf(fp, "%-*.*s", col, col-1, list[word]);
- }
- (void) fprintf(fp, "\n");
+ for (word = row; word < words; word += rows)
+ fprintf(fp, "%-*.*s", col, col-1, list[word]);
+ fprintf(fp, "\n");
}
} else {
cmd = pcmd->argval[0].string;
words = findcmd(cmd, builtins, opcmds, &xcp);
if (words == 0) {
- (void) fprintf(stderr,
- "Command `%s' is unknown\n", cmd);
+ fprintf(stderr,
+ "Command `%s' is unknown\n", cmd);
return;
} else if (words >= 2) {
- (void) fprintf(stderr,
- "Command `%s' is ambiguous\n", cmd);
+ fprintf(stderr,
+ "Command `%s' is ambiguous\n", cmd);
return;
}
- (void) fprintf(fp, "function: %s\n", xcp->comment);
+ fprintf(fp, "function: %s\n", xcp->comment);
printusage(xcp, fp);
}
}
@@ -1613,28 +1600,17 @@ help(
/*
* helpsort - do hostname qsort comparisons
*/
-#ifdef QSORT_USES_VOID_P
static int
helpsort(
const void *t1,
const void *t2
)
{
- char const * const * name1 = (char const * const *)t1;
- char const * const * name2 = (char const * const *)t2;
+ const char * const * name1 = t1;
+ const char * const * name2 = t2;
return strcmp(*name1, *name2);
}
-#else
-static int
-helpsort(
- char **name1,
- char **name2
- )
-{
- return strcmp(*name1, *name2);
-}
-#endif
/*
@@ -1799,21 +1775,34 @@ keytype(
FILE *fp
)
{
- if (pcmd->nargs == 0)
- fprintf(fp, "keytype is %s\n",
- (info_auth_keytype == KEY_TYPE_MD5) ? "MD5" : "???");
- else
- switch (*(pcmd->argval[0].string)) {
- case 'm':
- case 'M':
- info_auth_keytype = KEY_TYPE_MD5;
- break;
+ const char * digest_name;
+ size_t digest_len;
+ int key_type;
+
+ if (!pcmd->nargs) {
+ fprintf(fp, "keytype is %s with %lu octet digests\n",
+ keytype_name(info_auth_keytype),
+ (u_long)info_auth_hashlen);
+ return;
+ }
- default:
- fprintf(fp, "keytype must be 'md5'\n");
- }
-}
+ digest_name = pcmd->argval[0].string;
+ digest_len = 0;
+ key_type = keytype_from_text(digest_name, &digest_len);
+ if (!key_type) {
+ fprintf(fp, "keytype must be 'md5'%s\n",
+#ifdef OPENSSL
+ " or a digest type provided by OpenSSL");
+#else
+ "");
+#endif
+ return;
+ }
+
+ info_auth_keytype = key_type;
+ info_auth_hashlen = digest_len;
+}
/*
@@ -1840,7 +1829,7 @@ passwd(
(u_char *)pcmd->argval[0].string);
authtrust(info_auth_keyid, 1);
} else {
- pass = getpass("MD5 Password: ");
+ pass = getpass_keytype(info_auth_keytype);
if (*pass == '\0')
(void) fprintf(fp, "Password unchanged\n");
else {
@@ -1974,26 +1963,28 @@ getkeyid(
const char *keyprompt
)
{
- register char *p;
- register int c;
+ int c;
FILE *fi;
char pbuf[20];
+ size_t i;
+ size_t ilim;
#ifndef SYS_WINNT
if ((fi = fdopen(open("/dev/tty", 2), "r")) == NULL)
#else
- if ((fi = _fdopen((int)GetStdHandle(STD_INPUT_HANDLE), "r")) == NULL)
+ if ((fi = _fdopen(open("CONIN$", _O_TEXT), "r")) == NULL)
#endif /* SYS_WINNT */
fi = stdin;
- else
+ else
setbuf(fi, (char *)NULL);
fprintf(stderr, "%s", keyprompt); fflush(stderr);
- for (p=pbuf; (c = getc(fi))!='\n' && c!=EOF;) {
- if (p < &pbuf[18])
- *p++ = (char) c;
- }
- *p = '\0';
+ for (i = 0, ilim = COUNTOF(pbuf) - 1;
+ i < ilim && (c = getc(fi)) != '\n' && c != EOF;
+ )
+ pbuf[i++] = (char)c;
+ pbuf[i] = '\0';
if (fi != stdin)
- fclose(fi);
- return (u_int32)atoi(pbuf);
+ fclose(fi);
+
+ return (u_long) atoi(pbuf);
}