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

« back to all changes in this revision

Viewing changes to ntpd/ntp_request.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:
98
98
static  void    do_setclr_trap  P((struct sockaddr_storage *, struct interface *, struct req_pkt *, int));
99
99
static  void    set_request_keyid P((struct sockaddr_storage *, struct interface *, struct req_pkt *));
100
100
static  void    set_control_keyid P((struct sockaddr_storage *, struct interface *, struct req_pkt *));
101
 
static  void    get_ctl_stats P((struct sockaddr_storage *, struct interface *, struct req_pkt *));
 
101
static  void    get_ctl_stats   P((struct sockaddr_storage *, struct interface *, struct req_pkt *));
 
102
static  void    get_if_stats    P((struct sockaddr_storage *, struct interface *, struct req_pkt *));
 
103
static  void    do_if_reload    P((struct sockaddr_storage *, struct interface *, struct req_pkt *));
102
104
#ifdef KERNEL_PLL
103
105
static  void    get_kernel_info P((struct sockaddr_storage *, struct interface *, struct req_pkt *));
104
106
#endif /* KERNEL_PLL */
171
173
        { REQ_GET_CLKBUGINFO, NOAUTH, sizeof(u_int32), sizeof(u_int32),
172
174
                                get_clkbug_info },
173
175
#endif
 
176
        { REQ_IF_STATS,         AUTH, 0, 0,     get_if_stats },
 
177
        { REQ_IF_RELOAD,        AUTH, 0, 0,     do_if_reload },
 
178
 
174
179
        { NO_REQUEST,           NOAUTH, 0, 0,   0 }
175
180
};
176
181
 
495
500
            !(inpkt->implementation == IMPL_XNTPD &&
496
501
            inpkt->request == REQ_CONFIG &&
497
502
            temp_size == sizeof(struct old_conf_peer))) {
 
503
#ifdef DEBUG
498
504
                if (debug > 2)
499
505
                        printf("process_private: wrong item size, received %d, should be %d or %d\n",
500
506
                            temp_size, proc->sizeofitem, proc->v6_sizeofitem);
 
507
#endif
501
508
                req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
502
509
                return;
503
510
        }
504
511
        if ((proc->sizeofitem != 0) &&
505
512
            ((temp_size * INFO_NITEMS(inpkt->err_nitems)) >
506
513
            (rbufp->recv_length - REQ_LEN_HDR))) {
 
514
#ifdef DEBUG
507
515
                if (debug > 2)
508
516
                        printf("process_private: not enough data\n");
 
517
#endif
509
518
                req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
510
519
                return;
511
520
        }
727
736
                                if (client_v6_capable) {
728
737
                                        ips->srcadr6 = GET_INADDR6(pp->srcadr);
729
738
                                        ips->v6_flag = 1;
730
 
                                        ips->dstadr6 = GET_INADDR6(pp->dstadr->sin);
 
739
                                        if (pp->dstadr)
 
740
                                                ips->dstadr6 = GET_INADDR6(pp->dstadr->sin);
 
741
                                        else
 
742
                                                memset(&ips->dstadr6, 0, sizeof(ips->dstadr6));
731
743
                                        skip = 0;
732
744
                                } else {
733
745
                                        skip = 1;
738
750
                                if (client_v6_capable)
739
751
                                        ips->v6_flag = 0;
740
752
/* XXX PDM This code is buggy. Need to replace with a straightforward assignment */
741
 
                                ips->dstadr = (pp->processed) ?
742
 
                                        pp->cast_flags == MDF_BCAST ?
743
 
                                        GET_INADDR(pp->dstadr->bcast):
744
 
                                        pp->cast_flags ?
745
 
                                        GET_INADDR(pp->dstadr->sin) ?
746
 
                                        GET_INADDR(pp->dstadr->sin):
747
 
                                        GET_INADDR(pp->dstadr->bcast):
748
 
                                        1 : GET_INADDR(pp->dstadr->sin);
 
753
                                
 
754
                                if (pp->dstadr)
 
755
                                        ips->dstadr = (pp->processed) ?
 
756
                                                pp->cast_flags == MDF_BCAST ?
 
757
                                                GET_INADDR(pp->dstadr->bcast):
 
758
                                                pp->cast_flags ?
 
759
                                                GET_INADDR(pp->dstadr->sin) ?
 
760
                                                GET_INADDR(pp->dstadr->sin):
 
761
                                                GET_INADDR(pp->dstadr->bcast):
 
762
                                                1 : GET_INADDR(pp->dstadr->sin);
 
763
                                else
 
764
                                                memset(&ips->dstadr, 0, sizeof(ips->dstadr));
749
765
 
750
766
                                skip = 0;
751
767
                        }
 
768
                        
752
769
                        if (!skip){ 
753
770
                                ips->srcport = NSRCPORT(&pp->srcadr);
754
771
                                ips->stratum = pp->stratum;
828
845
                if ((pp = findexistingpeer(&addr, (struct peer *)0, -1)) == 0)
829
846
                    continue;
830
847
                if (pp->srcadr.ss_family == AF_INET6) {
831
 
                        ip->dstadr6 = pp->cast_flags == MDF_BCAST ?
832
 
                                GET_INADDR6(pp->dstadr->bcast) :
833
 
                                GET_INADDR6(pp->dstadr->sin);
 
848
                        if (pp->dstadr)
 
849
                                ip->dstadr6 = pp->cast_flags == MDF_BCAST ?
 
850
                                        GET_INADDR6(pp->dstadr->bcast) :
 
851
                                        GET_INADDR6(pp->dstadr->sin);
 
852
                        else
 
853
                                memset(&ip->dstadr6, 0, sizeof(ip->dstadr6));
 
854
 
834
855
                        ip->srcadr6 = GET_INADDR6(pp->srcadr);
835
856
                        ip->v6_flag = 1;
836
857
                } else {
837
858
/* XXX PDM This code is buggy. Need to replace with a straightforward assignment */
838
 
                        ip->dstadr = (pp->processed) ?
839
 
                                pp->cast_flags == MDF_BCAST ?
840
 
                                GET_INADDR(pp->dstadr->bcast):
841
 
                                pp->cast_flags ?
842
 
                                GET_INADDR(pp->dstadr->sin) ?
843
 
                                GET_INADDR(pp->dstadr->sin):
844
 
                                GET_INADDR(pp->dstadr->bcast):
845
 
                                2 : GET_INADDR(pp->dstadr->sin);
 
859
                        if (pp->dstadr)
 
860
                                ip->dstadr = (pp->processed) ?
 
861
                                        pp->cast_flags == MDF_BCAST ?
 
862
                                        GET_INADDR(pp->dstadr->bcast):
 
863
                                        pp->cast_flags ?
 
864
                                        GET_INADDR(pp->dstadr->sin) ?
 
865
                                        GET_INADDR(pp->dstadr->sin):
 
866
                                        GET_INADDR(pp->dstadr->bcast):
 
867
                                        2 : GET_INADDR(pp->dstadr->sin);
 
868
                        else
 
869
                                memset(&ip->dstadr, 0, sizeof(ip->dstadr));
846
870
 
847
871
                        ip->srcadr = GET_INADDR(pp->srcadr);
848
872
                        if (client_v6_capable)
928
952
        struct sockaddr_storage addr;
929
953
        extern struct peer *sys_peer;
930
954
 
931
 
        printf("peer_stats: called\n");
 
955
#ifdef DEBUG
 
956
        if (debug)
 
957
             printf("peer_stats: called\n");
 
958
#endif
932
959
        items = INFO_NITEMS(inpkt->err_nitems);
933
960
        ipl = (struct info_peer_list *) inpkt->data;
934
961
        ip = (struct info_peer_stats *)prepare_pkt(srcadr, inter, inpkt,
946
973
#ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR
947
974
                addr.ss_len = SOCKLEN(&addr);
948
975
#endif
949
 
                printf("peer_stats: looking for %s, %d, %d\n", stoa(&addr),
 
976
#ifdef DEBUG
 
977
                if (debug)
 
978
                    printf("peer_stats: looking for %s, %d, %d\n", stoa(&addr),
950
979
                    ipl->port, ((struct sockaddr_in6 *)&addr)->sin6_port);
 
980
#endif
951
981
                ipl = (struct info_peer_list *)((char *)ipl +
952
982
                    INFO_ITEMSIZE(inpkt->mbz_itemsize));
953
983
 
954
984
                if ((pp = findexistingpeer(&addr, (struct peer *)0, -1)) == 0)
955
985
                    continue;
956
 
                printf("peer_stats: found %s\n", stoa(&addr));
 
986
#ifdef DEBUG
 
987
                if (debug)
 
988
                     printf("peer_stats: found %s\n", stoa(&addr));
 
989
#endif
957
990
                if (pp->srcadr.ss_family == AF_INET) {
958
 
                        ip->dstadr = (pp->processed) ?
959
 
                                pp->cast_flags == MDF_BCAST ?
960
 
                                GET_INADDR(pp->dstadr->bcast):
961
 
                                pp->cast_flags ?
962
 
                                GET_INADDR(pp->dstadr->sin) ?
963
 
                                GET_INADDR(pp->dstadr->sin):
964
 
                                GET_INADDR(pp->dstadr->bcast):
965
 
                                3 : 7;
 
991
                        if (pp->dstadr)
 
992
                                ip->dstadr = (pp->processed) ?
 
993
                                        pp->cast_flags == MDF_BCAST ?
 
994
                                        GET_INADDR(pp->dstadr->bcast):
 
995
                                        pp->cast_flags ?
 
996
                                        GET_INADDR(pp->dstadr->sin) ?
 
997
                                        GET_INADDR(pp->dstadr->sin):
 
998
                                        GET_INADDR(pp->dstadr->bcast):
 
999
                                        3 : 7;
 
1000
                        else
 
1001
                                memset(&ip->dstadr, 0, sizeof(ip->dstadr));
 
1002
                        
966
1003
                        ip->srcadr = GET_INADDR(pp->srcadr);
967
1004
                        if (client_v6_capable)
968
1005
                                ip->v6_flag = 0;
969
1006
                } else {
970
 
                        ip->dstadr6 = pp->cast_flags == MDF_BCAST ?
971
 
                                GET_INADDR6(pp->dstadr->bcast):
972
 
                                GET_INADDR6(pp->dstadr->sin);
 
1007
                        if (pp->dstadr)
 
1008
                                ip->dstadr6 = pp->cast_flags == MDF_BCAST ?
 
1009
                                        GET_INADDR6(pp->dstadr->bcast):
 
1010
                                        GET_INADDR6(pp->dstadr->sin);
 
1011
                        else
 
1012
                                memset(&ip->dstadr6, 0, sizeof(ip->dstadr6));
 
1013
                        
973
1014
                        ip->srcadr6 = GET_INADDR6(pp->srcadr);
974
1015
                        ip->v6_flag = 1;
975
1016
                }       
987
1028
                    ip->flags |= INFO_FLAG_PREFER;
988
1029
                if (pp->flags & FLAG_BURST)
989
1030
                    ip->flags |= INFO_FLAG_BURST;
 
1031
                if (pp->flags & FLAG_IBURST)
 
1032
                    ip->flags |= INFO_FLAG_IBURST;
990
1033
                if (pp->status == CTL_PST_SEL_SYNCCAND)
991
1034
                    ip->flags |= INFO_FLAG_SEL_CANDIDATE;
992
1035
                if (pp->status >= CTL_PST_SEL_SYSPEER)
993
1036
                    ip->flags |= INFO_FLAG_SHORTLIST;
 
1037
                ip->flags = htons(ip->flags);
994
1038
                ip->timereceived = htonl((u_int32)(current_time - pp->timereceived));
995
1039
                ip->timetosend = htonl(pp->nextdate - current_time);
996
1040
                ip->timereachable = htonl((u_int32)(current_time - pp->timereachable));
1020
1064
{
1021
1065
        register struct info_sys *is;
1022
1066
 
1023
 
        /*
1024
 
         * Importations from the protocol module
1025
 
         */
1026
 
        extern u_char sys_leap;
1027
 
        extern u_char sys_stratum;
1028
 
        extern s_char sys_precision;
1029
 
        extern double sys_rootdelay;
1030
 
        extern double sys_rootdispersion;
1031
 
        extern u_int32 sys_refid;
1032
 
        extern l_fp sys_reftime;
1033
 
        extern u_char sys_poll;
1034
 
        extern struct peer *sys_peer;
1035
 
        extern int sys_bclient;
1036
 
        extern double sys_bdelay;
1037
 
        extern l_fp sys_authdelay;
1038
 
        extern double clock_stability;
1039
 
        extern double sys_jitter;
1040
 
 
1041
1067
        is = (struct info_sys *)prepare_pkt(srcadr, inter, inpkt,
1042
1068
            v6sizeof(struct info_sys));
1043
1069
 
1065
1091
        is->rootdelay = htonl(DTOFP(sys_rootdelay));
1066
1092
        is->rootdispersion = htonl(DTOUFP(sys_rootdispersion));
1067
1093
        is->frequency = htonl(DTOFP(sys_jitter));
1068
 
        is->stability = htonl(DTOUFP(clock_stability * 1e6));
 
1094
        is->stability = htonl(DTOUFP(clock_stability));
1069
1095
        is->refid = sys_refid;
1070
1096
        HTONL_FP(&sys_reftime, &is->reftime);
1071
1097
 
1266
1292
        extern double last_offset;
1267
1293
        extern double drift_comp;
1268
1294
        extern int tc_counter;
1269
 
        extern u_long last_time;
 
1295
        extern u_long sys_clocktime;
1270
1296
 
1271
1297
        li = (struct info_loop *)prepare_pkt(srcadr, inter, inpkt,
1272
1298
            sizeof(struct info_loop));
1276
1302
        DTOLFP(drift_comp * 1e6, &ltmp);
1277
1303
        HTONL_FP(&ltmp, &li->drift_comp);
1278
1304
        li->compliance = htonl((u_int32)(tc_counter));
1279
 
        li->watchdog_timer = htonl((u_int32)(current_time - last_time));
 
1305
        li->watchdog_timer = htonl((u_int32)(current_time - sys_clocktime));
1280
1306
 
1281
1307
        (void) more_pkt();
1282
1308
        flush_pkt();
1319
1345
                    && temp_cp.hmode != MODE_BROADCAST)
1320
1346
                    fl = 1;
1321
1347
                if (temp_cp.flags & ~(CONF_FLAG_AUTHENABLE | CONF_FLAG_PREFER
1322
 
                                  | CONF_FLAG_BURST | CONF_FLAG_SKEY))
 
1348
                                  | CONF_FLAG_BURST | CONF_FLAG_IBURST | CONF_FLAG_SKEY | CONF_FLAG_DYNAMIC))
1323
1349
                    fl = 1;
1324
1350
                cp = (struct conf_peer *)
1325
1351
                    ((char *)cp + INFO_ITEMSIZE(inpkt->mbz_itemsize));
1343
1369
 
1344
1370
                fl = 0;
1345
1371
                if (temp_cp.flags & CONF_FLAG_AUTHENABLE)
1346
 
                    fl |= FLAG_AUTHENABLE;
 
1372
                        fl |= FLAG_AUTHENABLE;
1347
1373
                if (temp_cp.flags & CONF_FLAG_PREFER)
1348
 
                    fl |= FLAG_PREFER;
 
1374
                        fl |= FLAG_PREFER;
1349
1375
                if (temp_cp.flags & CONF_FLAG_BURST)
1350
1376
                    fl |= FLAG_BURST;
 
1377
                if (temp_cp.flags & CONF_FLAG_IBURST)
 
1378
                    fl |= FLAG_IBURST;
1351
1379
                if (temp_cp.flags & CONF_FLAG_SKEY)
1352
1380
                        fl |= FLAG_SKEY;
 
1381
                if (temp_cp.flags & CONF_FLAG_DYNAMIC)
 
1382
                        fl |= FLAG_DYNAMIC;
 
1383
                
1353
1384
                if (client_v6_capable && temp_cp.v6_flag != 0) {
1354
1385
                        peeraddr.ss_family = AF_INET6;
1355
1386
                        GET_INADDR6(peeraddr) = temp_cp.peeraddr6; 
1531
1562
#endif
1532
1563
                found = 0;
1533
1564
                peer = (struct peer *)0;
1534
 
                printf("searching for %s\n", stoa(&peeraddr));
 
1565
#ifdef DEBUG
 
1566
                if (debug)
 
1567
                     printf("searching for %s\n", stoa(&peeraddr));
 
1568
#endif
1535
1569
                while (!found) {
1536
1570
                        peer = findexistingpeer(&peeraddr, peer, -1);
1537
1571
                        if (peer == (struct peer *)0)
1620
1654
        )
1621
1655
{
1622
1656
        register u_int flags;
 
1657
        int prev_kern_enable;
1623
1658
 
 
1659
        prev_kern_enable = kern_enable;
1624
1660
        if (INFO_NITEMS(inpkt->err_nitems) > 1) {
1625
1661
                msyslog(LOG_ERR, "setclr_flags: err_nitems > 1");
1626
1662
                req_ack(srcadr, inter, inpkt, INFO_ERR_FMT);
1628
1664
        }
1629
1665
 
1630
1666
        flags = ((struct conf_sys_flags *)inpkt->data)->flags;
1631
 
 
 
1667
        flags = ntohl(flags);
 
1668
        
1632
1669
        if (flags & ~(SYS_FLAG_BCLIENT | SYS_FLAG_PPS |
1633
1670
                      SYS_FLAG_NTP | SYS_FLAG_KERNEL | SYS_FLAG_MONITOR |
1634
1671
                      SYS_FLAG_FILEGEN | SYS_FLAG_AUTH | SYS_FLAG_CAL)) {
1658
1695
        if (flags & SYS_FLAG_CAL)
1659
1696
                proto_config(PROTO_CAL, set, 0., NULL);
1660
1697
        req_ack(srcadr, inter, inpkt, INFO_OKAY);
 
1698
 
 
1699
        /* Reset the kernel ntp parameters if the kernel flag changed. */
 
1700
        if (prev_kern_enable && !kern_enable)
 
1701
                loop_config(LOOP_KERN_CLEAR, 0.0);
 
1702
        if (!prev_kern_enable && kern_enable)
 
1703
                loop_config(LOOP_DRIFTCOMP, drift_comp);
1661
1704
}
1662
1705
 
1663
1706
 
1780
1823
        cr = (struct conf_restrict *)inpkt->data;
1781
1824
 
1782
1825
        bad = 0;
 
1826
        cr->flags = ntohs(cr->flags);
 
1827
        cr->mflags = ntohs(cr->mflags);
1783
1828
        while (items-- > 0 && !bad) {
1784
1829
                if (cr->mflags & ~(RESM_NTPONLY))
1785
1830
                    bad |= 1;
1926
1971
                                : GET_INADDR(md->interface->bcast))
1927
1972
                                : 4);
1928
1973
                }
1929
 
                im->flags = md->cast_flags;
 
1974
                im->flags = htonl(md->cast_flags);
1930
1975
                im->port = md->rmtport;
1931
1976
                im->mode = md->mode;
1932
1977
                im->version = md->version;
1974
2019
        }
1975
2020
 
1976
2021
        flags = ((struct reset_flags *)inpkt->data)->flags;
1977
 
 
 
2022
        flags = ntohl(flags);
 
2023
     
1978
2024
        if (flags & ~RESET_ALLFLAGS) {
1979
2025
                msyslog(LOG_ERR, "reset_stats: reset leaves %#lx",
1980
2026
                        flags & ~RESET_ALLFLAGS);
2754
2800
        flush_pkt();
2755
2801
}
2756
2802
#endif
 
2803
 
 
2804
/*
 
2805
 * receiver of interface structures
 
2806
 */
 
2807
static void
 
2808
fill_info_if_stats(void *data, interface_info_t *interface_info)
 
2809
{
 
2810
        struct info_if_stats **ifsp = (struct info_if_stats **)data;
 
2811
        struct info_if_stats *ifs = *ifsp;
 
2812
        struct interface *interface = interface_info->interface;
 
2813
        
 
2814
        memset((char*)ifs, 0, sizeof(*ifs));
 
2815
        
 
2816
        if (interface->sin.ss_family == AF_INET6) {
 
2817
                if (!client_v6_capable) {
 
2818
                        return;
 
2819
                }
 
2820
                ifs->v6_flag = 1;
 
2821
                memcpy((char *)&ifs->unaddr.addr6, (char *)&CAST_V6(interface->sin)->sin6_addr, sizeof(struct in6_addr));
 
2822
                memcpy((char *)&ifs->unbcast.addr6, (char *)&CAST_V6(interface->bcast)->sin6_addr, sizeof(struct in6_addr));
 
2823
                memcpy((char *)&ifs->unmask.addr6, (char *)&CAST_V6(interface->mask)->sin6_addr, sizeof(struct in6_addr));
 
2824
        } else {
 
2825
                ifs->v6_flag = 0;
 
2826
                memcpy((char *)&ifs->unaddr.addr, (char *)&CAST_V4(interface->sin)->sin_addr, sizeof(struct in_addr));
 
2827
                memcpy((char *)&ifs->unbcast.addr, (char *)&CAST_V4(interface->bcast)->sin_addr, sizeof(struct in_addr));
 
2828
                memcpy((char *)&ifs->unmask.addr, (char *)&CAST_V4(interface->mask)->sin_addr, sizeof(struct in_addr));
 
2829
        }
 
2830
        ifs->v6_flag = htonl(ifs->v6_flag);
 
2831
        strcpy(ifs->name, interface->name);
 
2832
        ifs->family = htons(interface->family);
 
2833
        ifs->flags = htonl(interface->flags);
 
2834
        ifs->last_ttl = htonl(interface->last_ttl);
 
2835
        ifs->num_mcast = htonl(interface->num_mcast);
 
2836
        ifs->received = htonl(interface->received);
 
2837
        ifs->sent = htonl(interface->sent);
 
2838
        ifs->notsent = htonl(interface->notsent);
 
2839
        ifs->scopeid = htonl(interface->scopeid);
 
2840
        ifs->ifindex = htonl(interface->ifindex);
 
2841
        ifs->ifnum = htonl(interface->ifnum);
 
2842
        ifs->uptime = htonl(current_time - interface->starttime);
 
2843
        ifs->ignore_packets = interface->ignore_packets;
 
2844
        ifs->peercnt = htonl(interface->peercnt);
 
2845
        ifs->action = interface_info->action;
 
2846
        
 
2847
        *ifsp = (struct info_if_stats *)more_pkt();
 
2848
}
 
2849
 
 
2850
/*
 
2851
 * get_if_stats - get interface statistics
 
2852
 */
 
2853
static void
 
2854
get_if_stats(
 
2855
        struct sockaddr_storage *srcadr,
 
2856
        struct interface *inter,
 
2857
        struct req_pkt *inpkt
 
2858
        )
 
2859
{
 
2860
        struct info_if_stats *ifs;
 
2861
 
 
2862
        DPRINTF(3, ("wants interface statistics\n"));
 
2863
 
 
2864
        ifs = (struct info_if_stats *)prepare_pkt(srcadr, inter, inpkt,
 
2865
            v6sizeof(struct info_if_stats));
 
2866
 
 
2867
        interface_enumerate(fill_info_if_stats, &ifs);
 
2868
        
 
2869
        flush_pkt();
 
2870
}
 
2871
 
 
2872
static void
 
2873
do_if_reload(
 
2874
        struct sockaddr_storage *srcadr,
 
2875
        struct interface *inter,
 
2876
        struct req_pkt *inpkt
 
2877
        )
 
2878
{
 
2879
        struct info_if_stats *ifs;
 
2880
 
 
2881
        DPRINTF(3, ("wants interface reload\n"));
 
2882
 
 
2883
        ifs = (struct info_if_stats *)prepare_pkt(srcadr, inter, inpkt,
 
2884
            v6sizeof(struct info_if_stats));
 
2885
 
 
2886
        interface_update(fill_info_if_stats, &ifs);
 
2887
        
 
2888
        flush_pkt();
 
2889
}
 
2890