~ubuntu-branches/debian/squeeze/ntp/squeeze-201010051545

« back to all changes in this revision

Viewing changes to ntpdc/ntpdc.c

  • Committer: Bazaar Package Importer
  • Author(s): Kurt Roeckx
  • Date: 2009-01-05 21:10:03 UTC
  • mfrom: (1.2.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20090105211003-mh6zc3um4k1uhsj7
Tags: 1:4.2.4p4+dfsg-8
It did not properly check the return value of EVP_VerifyFinal
which results in an malformed DSA signature being treated as
a good signature rather than as an error.  (CVE-2009-0021)

Show diffs side-by-side

added added

removed removed

Lines of Context:
4
4
 
5
5
#include <stdio.h>
6
6
 
 
7
#include <ctype.h>
 
8
#include <signal.h>
 
9
#include <setjmp.h>
 
10
 
7
11
#include "ntpdc.h"
8
12
#include "ntp_select.h"
9
13
#include "ntp_io.h"
13
17
#include "isc/net.h"
14
18
#include "isc/result.h"
15
19
 
16
 
#include <ctype.h>
17
 
#include <signal.h>
18
 
#include <setjmp.h>
19
 
#include <netdb.h>
 
20
#include "ntpdc-opts.h"
20
21
 
21
22
#ifdef SYS_WINNT
 
23
# include <Mswsock.h>
22
24
# include <io.h>
23
25
#else
24
26
# define closesocket close
30
32
#endif /* HAVE_LIBREADLINE || HAVE_LIBEDIT */
31
33
 
32
34
#ifdef SYS_VXWORKS
33
 
/* vxWorks needs mode flag -casey*/
34
 
#define open(name, flags)   open(name, flags, 0777)
35
 
#define SERVER_PORT_NUM     123
 
35
                                /* vxWorks needs mode flag -casey*/
 
36
# define open(name, flags)   open(name, flags, 0777)
 
37
# define SERVER_PORT_NUM     123
 
38
#endif
 
39
 
 
40
/* We use COMMAND as an autogen keyword */
 
41
#ifdef COMMAND
 
42
# undef COMMAND
36
43
#endif
37
44
 
38
45
/*
47
54
 * Keyid used for authenticated requests.  Obtained on the fly.
48
55
 */
49
56
static  u_long  info_auth_keyid;
 
57
static int keyid_entered = 0;
50
58
 
51
59
/*
52
60
 * Type of key md5
56
64
static  int info_auth_keytype = KEY_TYPE_MD5;   /* MD5 */
57
65
u_long  current_time;           /* needed by authkeys; not used */
58
66
 
 
67
/*
 
68
 * for get_systime()
 
69
 */
 
70
s_char  sys_precision;          /* local clock precision (log2 s) */
 
71
 
59
72
int             ntpdcmain       P((int, char **));
60
73
/*
61
74
 * Built in command handler declarations
105
118
        { "help",       help,           {  OPT|NTP_STR, NO, NO, NO },
106
119
          { "command", "", "", "" },
107
120
          "tell the use and syntax of commands" },
108
 
        { "timeout",    timeout,        { OPT|UINT, NO, NO, NO },
 
121
        { "timeout",    timeout,        { OPT|NTP_UINT, NO, NO, NO },
109
122
          { "msec", "", "", "" },
110
123
          "set the primary receive time out" },
111
 
        { "delay",      my_delay,       { OPT|INT, NO, NO, NO },
 
124
        { "delay",      my_delay,       { OPT|NTP_INT, NO, NO, NO },
112
125
          { "msec", "", "", "" },
113
126
          "set the delay added to encryption time stamps" },
114
127
        { "host",       host,           { OPT|NTP_STR, OPT|NTP_STR, NO, NO },
129
142
        { "exit",       quit,           { NO, NO, NO, NO },
130
143
          { "", "", "", "" },
131
144
          "exit ntpdc" },
132
 
        { "keyid",      keyid,          { OPT|UINT, NO, NO, NO },
 
145
        { "keyid",      keyid,          { OPT|NTP_UINT, NO, NO, NO },
133
146
          { "key#", "", "", "" },
134
147
          "set/show keyid to use for authenticated requests" },
135
148
        { "keytype",    keytype,        { OPT|NTP_STR, NO, NO, NO },
154
167
#define MAXCMDS         100             /* maximum commands on cmd line */
155
168
#define MAXHOSTS        200             /* maximum hosts on cmd line */
156
169
#define MAXLINE         512             /* maximum line length */
157
 
#define MAXTOKENS       (1+1+MAXARGS+2) /* maximum number of usable tokens */
158
 
                                        /* command + -4|-6 + MAXARGS + */
159
 
                                        /* redirection */
 
170
#define MAXTOKENS       (1+1+MAXARGS+MOREARGS+2)        /* maximum number of usable tokens */
 
171
#define SCREENWIDTH     78              /* nominal screen width in columns */
160
172
 
161
173
/*
162
174
 * Some variables used and manipulated locally
268
280
#ifdef SYS_VXWORKS
269
281
void clear_globals(void)
270
282
{
271
 
    extern int ntp_optind;
272
 
    extern char *ntp_optarg;
273
283
    showhostnames = 0;              /* show host names by default */
274
 
    ntp_optind = 0;
275
 
    ntp_optarg = 0;
276
284
    havehost = 0;                   /* set to 1 when host open */
277
285
    numcmds = 0;
278
286
    numhosts = 0;
288
296
        char *argv[]
289
297
        )
290
298
{
291
 
        int c;
292
 
        int errflg = 0;
293
299
        extern int ntp_optind;
294
 
        extern char *ntp_optarg;
295
300
 
296
301
        delay_time.l_ui = 0;
297
302
        delay_time.l_uf = DEFDELAY;
315
320
        }
316
321
 
317
322
        progname = argv[0];
 
323
 
 
324
        {
 
325
                int optct = optionProcess(&ntpdcOptions, argc, argv);
 
326
                argc -= optct;
 
327
                argv += optct;
 
328
        }
 
329
 
 
330
        switch (WHICH_IDX_IPV4) {
 
331
            case INDEX_OPT_IPV4:
 
332
                ai_fam_templ = AF_INET;
 
333
                break;
 
334
            case INDEX_OPT_IPV6:
 
335
                ai_fam_templ = AF_INET6;
 
336
                break;
 
337
            default:
 
338
                ai_fam_templ = ai_fam_default;
 
339
                break;
 
340
        }
 
341
 
 
342
        if (HAVE_OPT(COMMAND)) {
 
343
                int             cmdct = STACKCT_OPT( COMMAND );
 
344
                const char**    cmds  = STACKLST_OPT( COMMAND );
 
345
 
 
346
                while (cmdct-- > 0) {
 
347
                        ADDCMD(*cmds++);
 
348
                }
 
349
        }
 
350
 
 
351
        debug = DESC(DEBUG_LEVEL).optOccCt;
 
352
 
 
353
        if (HAVE_OPT(INTERACTIVE)) {
 
354
                interactive = 1;
 
355
        }
 
356
 
 
357
        if (HAVE_OPT(NUMERIC)) {
 
358
                showhostnames = 0;
 
359
        }
 
360
 
 
361
        if (HAVE_OPT(LISTPEERS)) {
 
362
                ADDCMD("listpeers");
 
363
        }
 
364
 
 
365
        if (HAVE_OPT(PEERS)) {
 
366
                ADDCMD("peers");
 
367
        }
 
368
 
 
369
        if (HAVE_OPT(SHOWPEERS)) {
 
370
                ADDCMD("dmpeers");
 
371
        }
 
372
 
 
373
        if (ntp_optind == argc) {
 
374
                ADDHOST(DEFHOST);
 
375
        } else {
 
376
                for (; ntp_optind < argc; ntp_optind++)
 
377
                    ADDHOST(argv[ntp_optind]);
 
378
        }
 
379
 
 
380
        if (numcmds == 0 && interactive == 0
 
381
            && isatty(fileno(stdin)) && isatty(fileno(stderr))) {
 
382
                interactive = 1;
 
383
        }
 
384
 
 
385
#if 0
318
386
        ai_fam_templ = ai_fam_default;
319
387
        while ((c = ntp_getopt(argc, argv, "46c:dilnps")) != EOF)
320
388
            switch (c) {
349
417
                    errflg++;
350
418
                    break;
351
419
            }
 
420
 
352
421
        if (errflg) {
353
422
                (void) fprintf(stderr,
354
423
                               "usage: %s [-46dilnps] [-c cmd] host ...\n",
355
424
                               progname);
356
425
                exit(2);
357
426
        }
 
427
 
358
428
        if (ntp_optind == argc) {
359
429
                ADDHOST(DEFHOST);
360
430
        } else {
366
436
            && isatty(fileno(stdin)) && isatty(fileno(stderr))) {
367
437
                interactive = 1;
368
438
        }
 
439
#endif
369
440
 
370
441
#ifndef SYS_WINNT /* Under NT cannot handle SIGINT, WIN32 spawns a handler */
371
442
        if (interactive)
449
520
        hints.ai_flags = AI_NUMERICHOST;
450
521
 
451
522
        a_info = getaddrinfo(hname, service, &hints, &ai);
452
 
        if (a_info == EAI_NONAME || a_info == EAI_NODATA) {
 
523
        if (a_info == EAI_NONAME
 
524
#ifdef EAI_NODATA
 
525
            || a_info == EAI_NODATA
 
526
#endif
 
527
           ) {
453
528
                hints.ai_flags = AI_CANONNAME;
454
529
#ifdef AI_ADDRCONFIG
455
530
                hints.ai_flags |= AI_ADDRCONFIG;
463
538
        }
464
539
        if (a_info != 0) {
465
540
                (void) fprintf(stderr, "%s\n", gai_strerror(a_info));
 
541
                if (ai != NULL)
 
542
                        freeaddrinfo(ai);
466
543
                return 0;
467
544
        }
468
545
 
542
619
                    ai->ai_addrlen) == -1)
543
620
#endif /* SYS_VXWORKS */
544
621
            error("connect", "", "");
545
 
        if (a_info)
 
622
        if (ai != NULL)
546
623
                freeaddrinfo(ai);
547
624
        havehost = 1;
548
625
        req_pkt_size = REQ_LEN_NOMAC;
854
931
                qpkt.mbz_itemsize = MBZ_ITEMSIZE(qsize);
855
932
        } else {
856
933
                qpkt.err_nitems = ERR_NITEMS(0, 0);
857
 
                qpkt.mbz_itemsize = MBZ_ITEMSIZE(0);
 
934
                qpkt.mbz_itemsize = MBZ_ITEMSIZE(qsize);  /* allow for optional first item */
858
935
        }
859
936
 
860
 
        if (!auth) {
 
937
        if (!auth || (keyid_entered && info_auth_keyid == 0)) {
861
938
                qpkt.auth_seq = AUTH_SEQ(0, 0);
862
939
                return sendpkt((char *)&qpkt, req_pkt_size);
863
940
        } else {
870
947
                    + MAX_MAC_LEN - sizeof(struct req_pkt_tail));
871
948
 
872
949
                if (info_auth_keyid == 0) {
873
 
                        maclen = getkeyid("Keyid: ");
874
 
                        if (maclen == 0) {
875
 
                                (void) fprintf(stderr,
876
 
                                    "Invalid key identifier\n");
877
 
                                return 1;
 
950
                        if (((struct conf_peer *)qpkt.data)->keyid > 0)
 
951
                                info_auth_keyid = ((struct conf_peer *)qpkt.data)->keyid;
 
952
                        else {
 
953
                                maclen = getkeyid("Keyid: ");
 
954
                                if (maclen == 0) {
 
955
                                        (void) fprintf(stderr,
 
956
                                            "Invalid key identifier\n");
 
957
                                        return 1;
 
958
                                }
 
959
                                info_auth_keyid = maclen;
878
960
                        }
879
 
                        info_auth_keyid = maclen;
880
961
                }
881
962
                if (!authistrusted(info_auth_keyid)) {
882
963
                        pass = getpass("MD5 Password: ");
1099
1180
        const char *cmdline
1100
1181
        )
1101
1182
{
1102
 
        char *tokens[1+MAXARGS+2];
 
1183
        char *tokens[1+MAXARGS+MOREARGS+2];
1103
1184
        struct parse pcmd;
1104
1185
        int ntok;
1105
1186
        int i, ti;
1156
1237
                i++;
1157
1238
        }
1158
1239
 
 
1240
        /* Any extra args are assumed to be "OPT|NTP_STR". */
 
1241
        for ( ; i < MAXARGS + MOREARGS;) {
 
1242
             if ((i+ti) >= ntok)
 
1243
                  break;
 
1244
                rval = getarg(tokens[i+ti], (int)(OPT|NTP_STR), &pcmd.argval[i]);
 
1245
                if (rval == -1) {
 
1246
                        ti++;
 
1247
                        continue;
 
1248
                }
 
1249
                if (rval == 0)
 
1250
                        return;
 
1251
                pcmd.nargs++;
 
1252
                i++;
 
1253
        }
 
1254
 
1159
1255
        i += ti;
1160
1256
        if (i < ntok && *tokens[i] == '>') {
1161
1257
                char *fname;
1294
1390
/*
1295
1391
 * getarg - interpret an argument token
1296
1392
 *
 
1393
 * string is always set.
 
1394
 * type is set to the decoded type.
 
1395
 *
1297
1396
 * return:       0 - failure
1298
1397
 *               1 - success
1299
1398
 *              -1 - skip to next token
1309
1408
        char *cp, *np;
1310
1409
        static const char *digits = "0123456789";
1311
1410
 
1312
 
        switch (code & ~OPT) {
 
1411
        memset(argp, 0, sizeof(*argp));
 
1412
 
 
1413
        argp->string = str;
 
1414
        argp->type   = code & ~OPT;
 
1415
 
 
1416
        switch (argp->type) {
1313
1417
            case NTP_STR:
1314
 
                argp->string = str;
1315
1418
                break;
1316
 
            case ADD:
 
1419
            case NTP_ADD:
1317
1420
                if (!strcmp("-6", str)) {
1318
1421
                        ai_fam_templ = AF_INET6;
1319
1422
                        return -1;
1325
1428
                        return 0;
1326
1429
                }
1327
1430
                break;
1328
 
            case INT:
1329
 
            case UINT:
 
1431
            case NTP_INT:
 
1432
            case NTP_UINT:
1330
1433
                isneg = 0;
1331
1434
                np = str;
1332
1435
                if (*np == '-') {
1347
1450
                } while (*(++np) != '\0');
1348
1451
 
1349
1452
                if (isneg) {
1350
 
                        if ((code & ~OPT) == UINT) {
 
1453
                        if ((code & ~OPT) == NTP_UINT) {
1351
1454
                                (void) fprintf(stderr,
1352
1455
                                               "***Value %s should be unsigned\n", str);
1353
1456
                                return 0;
1447
1550
        FILE *fp
1448
1551
        )
1449
1552
{
1450
 
        int i;
1451
 
        int n;
1452
1553
        struct xcmd *xcp;
1453
1554
        char *cmd;
1454
 
        const char *cmdsort[100];
1455
 
        int length[100];
1456
 
        int maxlength;
1457
 
        int numperline;
1458
 
        static const char *spaces = "                    ";     /* 20 spaces */
 
1555
        const char *list[100];
 
1556
        int word, words;     
 
1557
        int row, rows;
 
1558
        int col, cols;
1459
1559
 
1460
1560
        if (pcmd->nargs == 0) {
1461
 
                n = 0;
 
1561
                words = 0;
1462
1562
                for (xcp = builtins; xcp->keyword != 0; xcp++) {
1463
1563
                        if (*(xcp->keyword) != '?')
1464
 
                            cmdsort[n++] = xcp->keyword;
 
1564
                            list[words++] = xcp->keyword;
1465
1565
                }
1466
 
                for (xcp = opcmds; xcp->keyword != 0; xcp++)
1467
 
                    cmdsort[n++] = xcp->keyword;
 
1566
                for (xcp = opcmds; xcp->keyword != 0; xcp++)
 
1567
                    list[words++] = xcp->keyword;
1468
1568
 
 
1569
                qsort(
1469
1570
#ifdef QSORT_USES_VOID_P
1470
 
                qsort(cmdsort, (size_t)n, sizeof(char *), helpsort);
 
1571
                    (void *)
1471
1572
#else
1472
 
                qsort((char *)cmdsort, (size_t)n, sizeof(char *), helpsort);
 
1573
                    (char *)
1473
1574
#endif
1474
 
 
1475
 
                maxlength = 0;
1476
 
                for (i = 0; i < n; i++) {
1477
 
                        length[i] = strlen(cmdsort[i]);
1478
 
                        if (length[i] > maxlength)
1479
 
                            maxlength = length[i];
 
1575
                        (list), (size_t)(words), sizeof(char *), helpsort);
 
1576
                col = 0;
 
1577
                for (word = 0; word < words; word++) {
 
1578
                        int length = strlen(list[word]);
 
1579
                        if (col < length) {
 
1580
                            col = length;
 
1581
                        }
1480
1582
                }
1481
 
                maxlength++;
1482
 
                numperline = 76 / maxlength;
1483
 
 
1484
 
                (void) fprintf(fp, "Commands available:\n");
1485
 
                for (i = 0; i < n; i++) {
1486
 
                        if ((i % numperline) == (numperline-1)
1487
 
                            || i == (n-1))
1488
 
                            (void) fprintf(fp, "%s\n", cmdsort[i]);
1489
 
                        else
1490
 
                            (void) fprintf(fp, "%s%s", cmdsort[i],
1491
 
                                           spaces+20-maxlength+length[i]);
 
1583
 
 
1584
                cols = SCREENWIDTH / ++col;
 
1585
                rows = (words + cols - 1) / cols;
 
1586
 
 
1587
                (void) fprintf(fp, "ntpdc commands:\n");
 
1588
 
 
1589
                for (row = 0; row < rows; row++) {
 
1590
                        for (word = row; word < words; word += rows) {
 
1591
                                (void) fprintf(fp, "%-*.*s", col, col-1, list[word]);
 
1592
                        }
 
1593
                        (void) fprintf(fp, "\n");
1492
1594
                }
1493
1595
        } else {
1494
1596
                cmd = pcmd->argval[0].string;
1495
 
                n = findcmd(cmd, builtins, opcmds, &xcp);
1496
 
                if (n == 0) {
 
1597
                words = findcmd(cmd, builtins, opcmds, &xcp);
 
1598
                if (words == 0) {
1497
1599
                        (void) fprintf(stderr,
1498
1600
                                       "Command `%s' is unknown\n", cmd);
1499
1601
                        return;
1500
 
                } else if (n >= 2) {
 
1602
                } else if (words >= 2) {
1501
1603
                        (void) fprintf(stderr,
1502
1604
                                       "Command `%s' is ambiguous\n", cmd);
1503
1605
                        return;
1549
1651
        opt46 = 0;
1550
1652
        (void) fprintf(fp, "usage: %s", xcp->keyword);
1551
1653
        for (i = 0; i < MAXARGS && xcp->arg[i] != NO; i++) {
1552
 
                if (opt46 == 0 && (xcp->arg[i] & ~OPT) == ADD) {
 
1654
                if (opt46 == 0 && (xcp->arg[i] & ~OPT) == NTP_ADD) {
1553
1655
                        (void) fprintf(fp, " [ -4|-6 ]");
1554
1656
                        opt46 = 1;
1555
1657
                }
1675
1777
        )
1676
1778
{
1677
1779
        if (pcmd->nargs == 0) {
1678
 
                if (info_auth_keyid == 0)
 
1780
                if (info_auth_keyid == 0 && !keyid_entered)
1679
1781
                    (void) fprintf(fp, "no keyid defined\n");
 
1782
                else if (info_auth_keyid == 0 && keyid_entered)
 
1783
                    (void) fprintf(fp, "no keyid will be sent\n");
1680
1784
                else
1681
1785
                    (void) fprintf(fp, "keyid is %lu\n", (u_long)info_auth_keyid);
1682
1786
        } else {
1683
1787
                info_auth_keyid = pcmd->argval[0].uval;
 
1788
                keyid_entered = 1;
1684
1789
        }
1685
1790
}
1686
1791