Blame
Date:
Thu Sep 10 14:45:56 2020 UTC
Message:
I want to stick with ldns-verify-zone
0001
2014-11-14
pjp
/*
0002
2020-06-29
pjp
* Copyright (c) 2011-2020 Peter J. Philipp
0003
2014-11-14
pjp
* All rights reserved.
0004
2014-11-14
pjp
*
0005
2014-11-14
pjp
* Redistribution and use in source and binary forms, with or without
0006
2014-11-14
pjp
* modification, are permitted provided that the following conditions
0007
2014-11-14
pjp
* are met:
0008
2014-11-14
pjp
* 1. Redistributions of source code must retain the above copyright
0009
2014-11-14
pjp
* notice, this list of conditions and the following disclaimer.
0010
2014-11-14
pjp
* 2. Redistributions in binary form must reproduce the above copyright
0011
2014-11-14
pjp
* notice, this list of conditions and the following disclaimer in the
0012
2014-11-14
pjp
* documentation and/or other materials provided with the distribution.
0013
2014-11-14
pjp
* 3. The name of the author may not be used to endorse or promote products
0014
2014-11-14
pjp
* derived from this software without specific prior written permission
0015
2014-11-14
pjp
*
0016
2014-11-14
pjp
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
0017
2014-11-14
pjp
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0018
2014-11-14
pjp
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
0019
2014-11-14
pjp
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
0020
2014-11-14
pjp
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
0021
2014-11-14
pjp
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0022
2014-11-14
pjp
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0023
2014-11-14
pjp
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0024
2014-11-14
pjp
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
0025
2014-11-14
pjp
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0026
2014-11-14
pjp
*
0027
2014-11-14
pjp
*/
0028
2017-10-26
pjp
0029
2017-10-26
pjp
/*
0030
2020-08-26
pjp
* $Id: axfr.c,v 1.48 2020/08/26 07:17:26 pjp Exp $
0031
2017-10-26
pjp
*/
0032
2017-10-26
pjp
0033
2019-06-06
pjp
#include <sys/types.h>
0034
2019-06-06
pjp
#include <sys/socket.h>
0035
2019-06-06
pjp
#include <sys/select.h>
0036
2019-06-06
pjp
#include <sys/wait.h>
0037
2019-06-06
pjp
0038
2019-06-06
pjp
#include <netinet/in.h>
0039
2019-06-06
pjp
#include <arpa/inet.h>
0040
2019-06-06
pjp
#include <netdb.h>
0041
2019-06-06
pjp
0042
2019-06-06
pjp
#include <stdio.h>
0043
2019-06-06
pjp
#include <stdlib.h>
0044
2019-06-06
pjp
#include <string.h>
0045
2019-06-06
pjp
#include <unistd.h>
0046
2019-12-10
pjp
#include <fcntl.h>
0047
2019-06-06
pjp
#include <syslog.h>
0048
2019-06-06
pjp
#include <errno.h>
0049
2019-06-06
pjp
#include <signal.h>
0050
2019-06-06
pjp
0051
2019-06-06
pjp
#ifdef __linux__
0052
2019-06-06
pjp
#include <grp.h>
0053
2019-06-06
pjp
#define __USE_BSD 1
0054
2019-06-06
pjp
#include <endian.h>
0055
2019-06-06
pjp
#include <bsd/stdlib.h>
0056
2019-06-06
pjp
#include <bsd/string.h>
0057
2019-06-06
pjp
#include <bsd/sys/queue.h>
0058
2019-06-06
pjp
#define __unused
0059
2019-06-06
pjp
#include <bsd/sys/tree.h>
0060
2019-06-06
pjp
#include <bsd/sys/endian.h>
0061
2019-06-06
pjp
#include "imsg.h"
0062
2019-06-06
pjp
#else /* not linux */
0063
2019-06-06
pjp
#include <sys/queue.h>
0064
2019-06-06
pjp
#include <sys/tree.h>
0065
2019-06-06
pjp
#ifdef __FreeBSD__
0066
2019-06-06
pjp
#include "imsg.h"
0067
2019-06-06
pjp
#else
0068
2019-06-06
pjp
#include <imsg.h>
0069
2019-06-06
pjp
#endif /* __FreeBSD__ */
0070
2019-06-06
pjp
#endif /* __linux__ */
0071
2019-06-06
pjp
0072
2019-06-06
pjp
#ifndef NTOHS
0073
2019-06-06
pjp
#include "endian.h"
0074
2019-06-06
pjp
#endif
0075
2019-06-06
pjp
0076
2016-07-06
pjp
#include "ddd-dns.h"
0077
2016-07-06
pjp
#include "ddd-db.h"
0078
2016-07-06
pjp
0079
2019-02-27
pjp
#include <openssl/evp.h>
0080
2019-02-27
pjp
#include <openssl/hmac.h>
0081
2016-07-06
pjp
0082
2017-08-09
pjp
void axfrloop(int *, int, char **, ddDB *, struct imsgbuf *ibuf);
0083
2017-08-09
pjp
void axfr_connection(int, char *, int, ddDB *, char *, int);
0084
2017-06-26
pjp
int build_header(ddDB *, char *, char *, struct question *, int);
0085
2019-02-15
pjp
int build_soa(ddDB *, char *, int, struct rbtree *, struct question *);
0086
2019-02-15
pjp
int checklabel(ddDB *, struct rbtree *, struct rbtree *, struct question *);
0087
2017-08-09
pjp
int find_axfr(struct sockaddr_storage *, int);
0088
2017-06-26
pjp
void gather_notifydomains(ddDB *);
0089
2014-11-14
pjp
void init_axfr(void);
0090
2020-06-25
pjp
void init_notifyddd(void);
0091
2014-11-14
pjp
int insert_axfr(char *, char *);
0092
2020-06-25
pjp
int insert_notifyddd(char *, char *);
0093
2014-11-14
pjp
void notifypacket(int, void *, void *, int);
0094
2020-06-25
pjp
void notifyddds(int *);
0095
2014-11-14
pjp
void reap(int);
0096
2014-11-14
pjp
0097
2019-12-03
pjp
extern void pack(char *, char *, int);
0098
2019-12-03
pjp
extern void pack32(char *, u_int32_t);
0099
2019-12-03
pjp
extern void pack16(char *, u_int16_t);
0100
2019-12-03
pjp
extern void pack8(char *, u_int8_t);
0101
2019-12-03
pjp
extern uint32_t unpack32(char *);
0102
2019-12-03
pjp
extern uint16_t unpack16(char *);
0103
2019-12-03
pjp
extern void unpack(char *, char *, int);
0104
2019-12-03
pjp
0105
2017-06-26
pjp
extern int get_record_size(ddDB *, char *, int);
0106
2014-11-14
pjp
extern in_addr_t getmask(int);
0107
2014-11-14
pjp
extern int getmask6(int, struct sockaddr_in6 *);
0108
2019-01-25
pjp
extern void reply_fmterror(struct sreply *, ddDB *);
0109
2019-01-25
pjp
extern void reply_nxdomain(struct sreply *, ddDB *);
0110
2019-02-15
pjp
extern struct rbtree * get_soa(ddDB *, struct question *);
0111
2014-11-14
pjp
extern int compress_label(u_char *, int, int);
0112
2014-11-14
pjp
extern u_int16_t create_anyreply(struct sreply *, char *, int, int, int);
0113
2019-02-26
pjp
extern struct question *build_fake_question(char *, int, u_int16_t, char *, int);
0114
2019-02-26
pjp
extern struct question *build_question(char *, int, int, char *);
0115
2014-11-14
pjp
extern int free_question(struct question *);
0116
2014-11-14
pjp
extern void dolog(int, char *, ...);
0117
2020-06-29
pjp
extern void build_reply(struct sreply *, int, char *, int, struct question *, struct sockaddr *, socklen_t, struct rbtree *, struct rbtree *, u_int8_t, int, int, char *);
0118
2014-11-14
pjp
0119
2019-02-15
pjp
extern struct rbtree * find_rrset(ddDB *db, char *name, int len);
0120
2019-02-15
pjp
extern struct rrset * find_rr(struct rbtree *rbt, u_int16_t rrtype);
0121
2019-02-15
pjp
extern int display_rr(struct rrset *rrset);
0122
2019-02-15
pjp
extern int rotate_rr(struct rrset *rrset);
0123
2014-11-14
pjp
0124
2019-02-19
pjp
extern int domaincmp(struct node *e1, struct node *e2);
0125
2019-02-26
pjp
extern char * dns_label(char *, int *);
0126
2019-02-28
pjp
extern int additional_tsig(struct question *, char *, int, int, int, int, HMAC_CTX *);
0127
2019-02-27
pjp
extern int find_tsig_key(char *keyname, int keynamelen, char *key, int keylen);
0128
2020-08-26
pjp
extern int have_zone(char *zonename, int zonelen);
0129
2019-02-15
pjp
0130
2020-08-26
pjp
0131
2014-11-14
pjp
int notify = 0; /* do not notify when set to 0 */
0132
2014-11-14
pjp
0133
2014-11-14
pjp
extern int debug, verbose;
0134
2014-11-14
pjp
extern time_t time_changed;
0135
2019-02-26
pjp
extern int tsig;
0136
2020-03-10
pjp
extern long glob_time_offset;
0137
2020-08-26
pjp
extern struct zonetree zonehead;
0138
2014-11-14
pjp
0139
2019-02-26
pjp
SLIST_HEAD(, axfrentry) axfrhead;
0140
2014-11-14
pjp
0141
2014-11-14
pjp
static struct axfrentry {
0142
2014-11-14
pjp
char name[INET6_ADDRSTRLEN];
0143
2014-11-14
pjp
int family;
0144
2014-11-14
pjp
struct sockaddr_storage hostmask;
0145
2014-11-14
pjp
struct sockaddr_storage netmask;
0146
2014-11-14
pjp
u_int8_t prefixlen;
0147
2014-11-14
pjp
SLIST_ENTRY(axfrentry) axfr_entry;
0148
2014-11-14
pjp
} *an2, *anp;
0149
2014-11-14
pjp
0150
2014-11-14
pjp
SLIST_HEAD(notifylisthead, notifyentry) notifyhead;
0151
2014-11-14
pjp
0152
2014-11-14
pjp
static struct notifyentry {
0153
2014-11-14
pjp
char domain[DNS_MAXNAME];
0154
2014-11-14
pjp
int domainlen;
0155
2014-11-14
pjp
u_int16_t *ids;
0156
2014-11-14
pjp
u_int16_t *attempts;
0157
2019-06-26
pjp
int usetsig;
0158
2019-06-26
pjp
int numadd;
0159
2019-06-26
pjp
struct mzone *mzone;
0160
2014-11-14
pjp
SLIST_ENTRY(notifyentry) notify_entry;
0161
2014-11-14
pjp
} *notn2, *notnp;
0162
2014-11-14
pjp
0163
2017-06-26
pjp
extern int domaincmp(struct node *e1, struct node *e2);
0164
2018-03-28
pjp
static int check_notifyreply(struct dns_header *, struct question *, struct sockaddr_storage *, int, struct notifyentry *, int);
0165
2014-11-14
pjp
0166
2019-06-26
pjp
SLIST_HEAD(mzones ,mzone) mzones;
0167
2019-02-26
pjp
0168
2014-11-14
pjp
/*
0169
2014-11-14
pjp
* INIT_AXFR - initialize the axfr singly linked list
0170
2014-11-14
pjp
*/
0171
2014-11-14
pjp
0172
2014-11-14
pjp
void
0173
2014-11-14
pjp
init_axfr(void)
0174
2014-11-14
pjp
{
0175
2014-11-14
pjp
SLIST_INIT(&axfrhead);
0176
2014-11-14
pjp
return;
0177
2014-11-14
pjp
}
0178
2014-11-14
pjp
0179
2014-11-14
pjp
/*
0180
2014-11-14
pjp
* INSERT_AXFR - insert an address and prefixlen into the axfr slist
0181
2014-11-14
pjp
*/
0182
2014-11-14
pjp
0183
2014-11-14
pjp
int
0184
2014-11-14
pjp
insert_axfr(char *address, char *prefixlen)
0185
2014-11-14
pjp
{
0186
2014-11-14
pjp
struct sockaddr_in *sin;
0187
2014-11-14
pjp
struct sockaddr_in6 *sin6;
0188
2014-11-14
pjp
int pnum;
0189
2014-11-14
pjp
int ret;
0190
2014-11-14
pjp
0191
2014-11-14
pjp
pnum = atoi(prefixlen);
0192
2014-11-14
pjp
an2 = malloc(sizeof(struct axfrentry)); /* Insert after. */
0193
2014-11-14
pjp
0194
2014-11-14
pjp
if (strchr(address, ':') != NULL) {
0195
2014-11-14
pjp
an2->family = AF_INET6;
0196
2014-11-14
pjp
sin6 = (struct sockaddr_in6 *)&an2->hostmask;
0197
2014-11-14
pjp
if ((ret = inet_pton(AF_INET6, address, &sin6->sin6_addr.s6_addr)) != 1)
0198
2014-11-14
pjp
return (-1);
0199
2014-11-14
pjp
sin6->sin6_family = AF_INET6;
0200
2014-11-14
pjp
sin6 = (struct sockaddr_in6 *)&an2->netmask;
0201
2014-11-14
pjp
sin6->sin6_family = AF_INET6;
0202
2014-11-14
pjp
if (getmask6(pnum, sin6) < 0)
0203
2014-11-14
pjp
return(-1);
0204
2014-11-14
pjp
an2->prefixlen = pnum;
0205
2014-11-14
pjp
} else {
0206
2014-11-14
pjp
0207
2014-11-14
pjp
an2->family = AF_INET;
0208
2014-11-14
pjp
sin = (struct sockaddr_in *)&an2->hostmask;
0209
2014-11-14
pjp
sin->sin_family = AF_INET;
0210
2014-11-14
pjp
sin->sin_addr.s_addr = inet_addr(address);
0211
2014-11-14
pjp
sin = (struct sockaddr_in *)&an2->netmask;
0212
2014-11-14
pjp
sin->sin_family = AF_INET;
0213
2014-11-14
pjp
sin->sin_addr.s_addr = getmask(pnum);
0214
2014-11-14
pjp
an2->prefixlen = pnum;
0215
2014-11-14
pjp
0216
2014-11-14
pjp
}
0217
2014-11-14
pjp
0218
2014-11-14
pjp
SLIST_INSERT_HEAD(&axfrhead, an2, axfr_entry);
0219
2014-11-14
pjp
0220
2014-11-14
pjp
return (0);
0221
2014-11-14
pjp
}
0222
2014-11-14
pjp
0223
2014-11-14
pjp
/*
0224
2014-11-14
pjp
* FIND_AXFR - walk the axfr list and find the correponding network
0225
2014-11-14
pjp
* if a network matches return 1, if no match is found return
0226
2014-11-14
pjp
* 0.
0227
2014-11-14
pjp
*/
0228
2014-11-14
pjp
0229
2014-11-14
pjp
int
0230
2014-11-14
pjp
find_axfr(struct sockaddr_storage *sst, int family)
0231
2014-11-14
pjp
{
0232
2014-11-14
pjp
struct sockaddr_in *sin, *sin0;
0233
2014-11-14
pjp
struct sockaddr_in6 *sin6, *sin60, *sin61;
0234
2014-11-14
pjp
u_int32_t hostmask, netmask;
0235
2014-11-14
pjp
u_int32_t a;
0236
2014-11-14
pjp
#ifdef __amd64
0237
2014-11-14
pjp
u_int64_t *hm[2], *nm[2], *a6[2];
0238
2014-11-14
pjp
#else
0239
2014-11-14
pjp
u_int32_t *hm[4], *nm[4], *a6[4];
0240
2014-11-14
pjp
#endif
0241
2014-11-14
pjp
0242
2014-11-14
pjp
SLIST_FOREACH(anp, &axfrhead, axfr_entry) {
0243
2014-11-14
pjp
if (anp->family == AF_INET) {
0244
2014-11-14
pjp
if (family != AF_INET)
0245
2014-11-14
pjp
continue;
0246
2014-11-14
pjp
sin = (struct sockaddr_in *)sst;
0247
2014-11-14
pjp
a = sin->sin_addr.s_addr;
0248
2014-11-14
pjp
sin = (struct sockaddr_in *)&anp->hostmask;
0249
2014-11-14
pjp
sin0 = (struct sockaddr_in *)&anp->netmask;
0250
2014-11-14
pjp
hostmask = sin->sin_addr.s_addr;
0251
2014-11-14
pjp
netmask = sin0->sin_addr.s_addr;
0252
2014-11-14
pjp
if ((hostmask & netmask) == (a & netmask)) {
0253
2014-11-14
pjp
return (1);
0254
2014-11-14
pjp
} /* if hostmask */
0255
2014-11-14
pjp
} else if (anp->family == AF_INET6) {
0256
2014-11-14
pjp
if (family != AF_INET6)
0257
2014-11-14
pjp
continue;
0258
2014-11-14
pjp
sin6 = (struct sockaddr_in6 *)sst;
0259
2014-11-14
pjp
sin60 = (struct sockaddr_in6 *)&anp->hostmask;
0260
2014-11-14
pjp
sin61 = (struct sockaddr_in6 *)&anp->netmask;
0261
2014-11-14
pjp
#ifdef __amd64
0262
2014-11-14
pjp
/*
0263
2014-11-14
pjp
* If this is on a 64 bit machine, we'll benefit
0264
2014-11-14
pjp
* by using 64 bit registers, this should make it
0265
2014-11-14
pjp
* a tad faster...
0266
2014-11-14
pjp
*/
0267
2014-11-14
pjp
hm[0] = (u_int64_t *)&sin60->sin6_addr.s6_addr;
0268
2014-11-14
pjp
hm[1] = (hm[0] + 1);
0269
2014-11-14
pjp
nm[0] = (u_int64_t *)&sin61->sin6_addr.s6_addr;
0270
2014-11-14
pjp
nm[1] = (nm[0] + 1);
0271
2014-11-14
pjp
a6[0] = (u_int64_t *)&sin6->sin6_addr.s6_addr;
0272
2014-11-14
pjp
a6[1] = (a6[0] + 1);
0273
2014-11-14
pjp
if ( ((*hm[0] & *nm[0]) == (*a6[0] & *nm[0]))&&
0274
2014-11-14
pjp
((*hm[1] & *nm[1]) == (*a6[1] & *nm[1]))) {
0275
2014-11-14
pjp
#else
0276
2014-11-14
pjp
hm[0] = (u_int32_t *)&sin60->sin6_addr.s6_addr;
0277
2014-11-14
pjp
hm[1] = (hm[0] + 1); hm[2] = (hm[1] + 1);
0278
2014-11-14
pjp
hm[3] = (hm[2] + 1);
0279
2014-11-14
pjp
nm[0] = (u_int32_t *)&sin61->sin6_addr.s6_addr;
0280
2014-11-14
pjp
nm[1] = (nm[0] + 1); nm[2] = (nm[1] + 1);
0281
2014-11-14
pjp
nm[3] = (nm[2] + 1);
0282
2014-11-14
pjp
a6[0] = (u_int32_t *)&sin6->sin6_addr.s6_addr;
0283
2014-11-14
pjp
a6[1] = (a6[0] + 1); a6[2] = (a6[1] + 1);
0284
2014-11-14
pjp
a6[3] = (a6[2] + 1);
0285
2014-11-14
pjp
0286
2014-11-14
pjp
if ( ((*hm[0] & *nm[0]) == (*a6[0] & *nm[0]))&&
0287
2014-11-14
pjp
((*hm[1] & *nm[1]) == (*a6[1] & *nm[1]))&&
0288
2014-11-14
pjp
((*hm[2] & *nm[2]) == (*a6[2] & *nm[2]))&&
0289
2014-11-14
pjp
((*hm[3] & *nm[3]) == (*a6[3] & *nm[3]))) {
0290
2014-11-14
pjp
#endif
0291
2014-11-14
pjp
0292
2014-11-14
pjp
return (1);
0293
2014-11-14
pjp
} /* if ip6 address */
0294
2014-11-14
pjp
0295
2014-11-14
pjp
} /* if AF_INET6 */
0296
2014-11-14
pjp
} /* SLIST */
0297
2014-11-14
pjp
0298
2014-11-14
pjp
return (0);
0299
2014-11-14
pjp
}
0300
2014-11-14
pjp
0301
2014-11-14
pjp
void
0302
2017-08-09
pjp
axfrloop(int *afd, int sockcount, char **ident, ddDB *db, struct imsgbuf *ibuf)
0303
2014-11-14
pjp
{
0304
2014-11-14
pjp
fd_set rset;
0305
2014-11-14
pjp
0306
2014-11-14
pjp
struct timeval tv;
0307
2014-11-14
pjp
struct sockaddr_storage from;
0308
2018-03-28
pjp
struct sockaddr_in6 *sin6;
0309
2018-03-28
pjp
struct sockaddr_in *sin;
0310
2014-11-14
pjp
struct dns_header *dh;
0311
2014-11-14
pjp
struct question *question;
0312
2017-08-09
pjp
struct imsg imsg;
0313
2019-06-26
pjp
struct mzone_dest *md;
0314
2014-11-14
pjp
0315
2014-11-14
pjp
int i, so, len;
0316
2019-06-26
pjp
int n, count;
0317
2014-11-14
pjp
int sel, maxso = 0;
0318
2014-11-14
pjp
int is_ipv6, axfr_acl;
0319
2014-11-14
pjp
int notifyfd[2];
0320
2017-08-09
pjp
int packetlen;
0321
2019-12-10
pjp
int tcpflags;
0322
2014-11-14
pjp
0323
2014-11-14
pjp
socklen_t fromlen;
0324
2014-11-14
pjp
char buf[512];
0325
2019-06-26
pjp
char buf0[512];
0326
2017-08-09
pjp
char *packet;
0327
2014-11-14
pjp
0328
2014-11-14
pjp
time_t now;
0329
2014-11-14
pjp
pid_t pid;
0330
2014-11-14
pjp
0331
2014-11-14
pjp
char address[INET6_ADDRSTRLEN];
0332
2014-11-14
pjp
0333
2017-07-11
pjp
#if __OpenBSD__
0334
2017-11-28
pjp
if (pledge("stdio inet proc recvfd", NULL) < 0)
0335
2017-07-11
pjp
{
0336
2017-11-28
pjp
dolog(LOG_ERR, "pledge %s", strerror(errno));
0337
2017-07-11
pjp
exit(1);
0338
2017-07-11
pjp
}
0339
2017-07-11
pjp
#endif
0340
2017-07-11
pjp
0341
2014-11-14
pjp
signal(SIGCHLD, reap);
0342
2014-11-14
pjp
0343
2014-11-14
pjp
for (i = 0; i < sockcount; i++) {
0344
2014-11-14
pjp
listen(afd[i], 5);
0345
2014-11-14
pjp
}
0346
2014-11-14
pjp
0347
2014-11-14
pjp
if (notify) {
0348
2014-11-14
pjp
/*
0349
2014-11-14
pjp
* If a zonefile has changed in the last half hour then
0350
2014-11-14
pjp
* gather all notifydomains and start the notify process
0351
2014-11-14
pjp
*/
0352
2014-11-14
pjp
0353
2014-11-14
pjp
notifyfd[0] = -1;
0354
2014-11-14
pjp
notifyfd[1] = -1;
0355
2014-11-14
pjp
0356
2014-11-14
pjp
now = time(NULL);
0357
2014-11-14
pjp
if (difftime(now, time_changed) <= 1800) {
0358
2014-11-14
pjp
gather_notifydomains(db);
0359
2014-11-14
pjp
notifyfd[0] = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
0360
2014-11-14
pjp
notifyfd[1] = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
0361
2014-11-14
pjp
0362
2014-11-14
pjp
memset((char *)&from, 0, sizeof(from));
0363
2014-11-14
pjp
sin = (struct sockaddr_in *)&from;
0364
2014-11-14
pjp
sin->sin_family = AF_INET;
0365
2014-11-14
pjp
sin->sin_port = htons(0);
0366
2014-11-14
pjp
0367
2014-11-14
pjp
if (bind(notifyfd[0], (struct sockaddr *)sin, sizeof(*sin)) < 0) {
0368
2014-11-14
pjp
dolog(LOG_INFO, "bind notify: %s\n", strerror(errno));
0369
2014-11-14
pjp
}
0370
2014-11-14
pjp
0371
2014-11-14
pjp
memset((char *)&from, 0, sizeof(from));
0372
2014-11-14
pjp
sin6 = (struct sockaddr_in6 *)&from;
0373
2019-10-26
pjp
sin6->sin6_family = AF_INET6;
0374
2019-10-26
pjp
sin6->sin6_port = htons(0);
0375
2019-11-19
pjp
#ifndef __linux__
0376
2019-10-26
pjp
sin6->sin6_len = sizeof(struct sockaddr_in6);
0377
2019-11-19
pjp
#endif
0378
2014-11-14
pjp
0379
2019-10-26
pjp
if (bind(notifyfd[1], (struct sockaddr *)sin6, sizeof(*sin6)) < 0) {
0380
2014-11-14
pjp
dolog(LOG_INFO, "bind notify6: %s\n", strerror(errno));
0381
2014-11-14
pjp
}
0382
2014-11-14
pjp
0383
2014-11-14
pjp
memset((char *)&from, 0, sizeof(from));
0384
2014-11-14
pjp
0385
2020-06-25
pjp
notifyddds((int *)&notifyfd);
0386
2014-11-14
pjp
}
0387
2014-11-14
pjp
}
0388
2014-11-14
pjp
0389
2019-02-28
pjp
0390
2014-11-14
pjp
for (;;) {
0391
2014-11-14
pjp
0392
2014-11-14
pjp
FD_ZERO(&rset);
0393
2014-11-14
pjp
maxso = 0;
0394
2014-11-14
pjp
0395
2014-11-14
pjp
for (i = 0; i < sockcount; i++) {
0396
2014-11-14
pjp
FD_SET(afd[i], &rset);
0397
2014-11-14
pjp
if (maxso < afd[i])
0398
2014-11-14
pjp
maxso = afd[i];
0399
2014-11-14
pjp
}
0400
2017-08-09
pjp
0401
2017-08-09
pjp
FD_SET(ibuf->fd, &rset);
0402
2017-08-09
pjp
if (ibuf->fd > maxso)
0403
2017-08-09
pjp
maxso = ibuf->fd;
0404
2014-11-14
pjp
0405
2014-11-14
pjp
if (notify) {
0406
2019-06-26
pjp
/*
0407
2019-06-26
pjp
* go through every zone, removing those with all
0408
2019-06-26
pjp
* IP's notified...
0409
2019-06-26
pjp
*/
0410
2019-06-26
pjp
SLIST_FOREACH_SAFE(notnp, &notifyhead, notify_entry, notn2) {
0411
2019-06-26
pjp
count = 0;
0412
2019-06-26
pjp
SLIST_FOREACH(md, &notnp->mzone->dest, entries) {
0413
2019-06-26
pjp
if (md->notified == 0)
0414
2019-06-26
pjp
count++;
0415
2019-06-26
pjp
}
0416
2019-06-26
pjp
0417
2019-06-26
pjp
if (count == notnp->numadd) {
0418
2019-06-26
pjp
#if DEBUG
0419
2019-06-26
pjp
dolog(LOG_INFO, "removed domain \"%s\"\n", notnp->mzone->humanname);
0420
2019-06-26
pjp
#endif
0421
2019-06-26
pjp
SLIST_REMOVE(&notifyhead, notnp, notifyentry, notify_entry);
0422
2019-06-26
pjp
}
0423
2019-06-26
pjp
0424
2019-06-26
pjp
}
0425
2019-06-26
pjp
0426
2019-06-26
pjp
if (SLIST_EMPTY(&notifyhead)) {
0427
2019-06-26
pjp
dolog(LOG_INFO, "notifys have been completed, closing notify descriptors!\n");
0428
2019-06-26
pjp
if (notifyfd[0] > -1)
0429
2019-06-26
pjp
close(notifyfd[0]);
0430
2019-06-26
pjp
0431
2019-06-26
pjp
if (notifyfd[1] > -1)
0432
2019-06-26
pjp
close(notifyfd[1]);
0433
2019-06-26
pjp
0434
2019-06-26
pjp
notifyfd[0] = -1;
0435
2019-06-26
pjp
notifyfd[1] = -1;
0436
2019-06-26
pjp
0437
2019-06-26
pjp
notify = 0;
0438
2019-06-26
pjp
}
0439
2019-06-26
pjp
0440
2014-11-14
pjp
if (notifyfd[0] > -1) {
0441
2014-11-14
pjp
FD_SET(notifyfd[0], &rset);
0442
2014-11-14
pjp
if (maxso < notifyfd[0])
0443
2014-11-14
pjp
maxso = notifyfd[0];
0444
2014-11-14
pjp
}
0445
2014-11-14
pjp
0446
2014-11-14
pjp
if (notifyfd[1] > -1) {
0447
2014-11-14
pjp
FD_SET(notifyfd[1], &rset);
0448
2014-11-14
pjp
if (maxso < notifyfd[1])
0449
2014-11-14
pjp
maxso = notifyfd[1];
0450
2014-11-14
pjp
}
0451
2014-11-14
pjp
}
0452
2014-11-14
pjp
0453
2014-11-14
pjp
tv.tv_sec = 10;
0454
2014-11-14
pjp
tv.tv_usec = 0;
0455
2014-11-14
pjp
0456
2014-11-14
pjp
sel = select(maxso + 1, &rset, NULL, NULL, &tv);
0457
2014-11-14
pjp
0458
2014-11-14
pjp
if (sel == 0) {
0459
2014-11-14
pjp
if (notify) {
0460
2019-06-26
pjp
if (notifyfd[0] > -1 || notifyfd[1] > -1) {
0461
2020-06-25
pjp
notifyddds((int *)&notifyfd);
0462
2019-06-26
pjp
}
0463
2019-06-26
pjp
0464
2014-11-14
pjp
}
0465
2014-11-14
pjp
0466
2014-11-14
pjp
continue;
0467
2014-11-14
pjp
}
0468
2014-11-14
pjp
if (sel < 0) {
0469
2015-12-19
pjp
if (errno != EINTR)
0470
2015-12-19
pjp
dolog(LOG_INFO, "select: %s\n", strerror(errno));
0471
2014-11-14
pjp
continue;
0472
2014-11-14
pjp
}
0473
2014-11-14
pjp
0474
2014-11-14
pjp
for (i = 0; i < sockcount; i++) {
0475
2014-11-14
pjp
if (FD_ISSET(afd[i], &rset)) {
0476
2014-11-14
pjp
fromlen = sizeof(struct sockaddr_storage);
0477
2014-11-14
pjp
0478
2014-11-14
pjp
so = accept(afd[i], (struct sockaddr*)&from, &fromlen);
0479
2014-11-14
pjp
if (so < 0) {
0480
2014-11-14
pjp
dolog(LOG_INFO, "afd accept: %s\n", strerror(errno));
0481
2014-11-14
pjp
continue;
0482
2014-11-14
pjp
}
0483
2014-11-14
pjp
0484
2014-11-14
pjp
if (from.ss_family == AF_INET6) {
0485
2014-11-14
pjp
is_ipv6 = 1;
0486
2014-11-14
pjp
0487
2014-11-14
pjp
fromlen = sizeof(struct sockaddr_in6);
0488
2014-11-14
pjp
sin6 = (struct sockaddr_in6 *)&from;
0489
2014-11-14
pjp
inet_ntop(AF_INET6, (void*)&sin6->sin6_addr, (char*)&address, sizeof(address));
0490
2014-11-14
pjp
axfr_acl = find_axfr((struct sockaddr_storage *)sin6, AF_INET6);
0491
2014-11-14
pjp
0492
2014-11-14
pjp
} else if (from.ss_family == AF_INET) {
0493
2014-11-14
pjp
is_ipv6 = 0;
0494
2014-11-14
pjp
0495
2014-11-14
pjp
fromlen = sizeof(struct sockaddr_in);
0496
2014-11-14
pjp
sin = (struct sockaddr_in *)&from;
0497
2014-11-14
pjp
inet_ntop(AF_INET, (void*)&sin->sin_addr, (char*)&address, sizeof(address));
0498
2014-11-14
pjp
0499
2014-11-14
pjp
axfr_acl = find_axfr((struct sockaddr_storage *)sin, AF_INET);
0500
2014-11-14
pjp
0501
2014-11-14
pjp
} else {
0502
2014-11-14
pjp
dolog(LOG_INFO, "afd accept unknown family %d, close\n", from.ss_family);
0503
2014-11-14
pjp
close(so);
0504
2014-11-14
pjp
continue;
0505
2014-11-14
pjp
}
0506
2014-11-14
pjp
0507
2014-11-14
pjp
if (! axfr_acl) {
0508
2014-11-14
pjp
dolog(LOG_INFO, "connection from %s was not in our axfr acl, drop\n", address);
0509
2014-11-14
pjp
close(so);
0510
2014-11-14
pjp
continue;
0511
2014-11-14
pjp
}
0512
2014-11-14
pjp
0513
2014-11-14
pjp
dolog(LOG_INFO, "AXFR connection from %s on interface \"%s\"\n", address, ident[i]);
0514
2014-11-14
pjp
0515
2014-11-14
pjp
switch (pid = fork()) {
0516
2014-11-14
pjp
case 0:
0517
2017-08-09
pjp
axfr_connection(so, address, is_ipv6, db, NULL, 0);
0518
2014-11-14
pjp
exit(0);
0519
2014-11-14
pjp
/*NOTREACHED*/
0520
2014-11-14
pjp
default:
0521
2014-11-14
pjp
close(so);
0522
2014-11-14
pjp
break;
0523
2014-11-14
pjp
}
0524
2014-11-14
pjp
0525
2014-11-14
pjp
} /* if(FD_ISSET..) */
0526
2014-11-14
pjp
0527
2014-11-14
pjp
} /* for (i.. */
0528
2017-08-09
pjp
0529
2017-08-09
pjp
if (FD_ISSET(ibuf->fd, &rset)) {
0530
2017-08-09
pjp
if ((n = imsg_read(ibuf)) < 0 && errno != EAGAIN) {
0531
2017-08-09
pjp
dolog(LOG_ERR, "imsg read failure %s\n", strerror(errno));
0532
2017-08-09
pjp
continue;
0533
2017-08-09
pjp
}
0534
2014-11-14
pjp
0535
2017-08-09
pjp
if (n == 0) {
0536
2017-08-09
pjp
/* child died? */
0537
2020-07-08
pjp
dolog(LOG_INFO, "sigpipe on child? AXFR process exiting.\n");
0538
2017-08-09
pjp
exit(1);
0539
2017-08-09
pjp
}
0540
2017-08-09
pjp
0541
2017-08-09
pjp
for(;;) {
0542
2017-08-09
pjp
if ((n = imsg_get(ibuf, &imsg)) < 0) {
0543
2017-08-09
pjp
dolog(LOG_ERR, "imsg read error: %s\n", strerror(errno));
0544
2017-08-09
pjp
break;
0545
2017-08-09
pjp
} else {
0546
2017-08-09
pjp
if (n == 0)
0547
2017-08-09
pjp
break;
0548
2017-08-09
pjp
packetlen = imsg.hdr.len - IMSG_HEADER_SIZE;
0549
2017-08-09
pjp
0550
2017-08-09
pjp
switch (imsg.hdr.type) {
0551
2017-08-09
pjp
case IMSG_XFR_MESSAGE:
0552
2017-08-09
pjp
dolog(LOG_INFO, "received xfr via message passing\n");
0553
2017-08-09
pjp
packet = calloc(1, packetlen);
0554
2017-08-09
pjp
if (packet == NULL) {
0555
2017-08-09
pjp
dolog(LOG_ERR, "calloc: %s\n", strerror(errno));
0556
2017-08-09
pjp
break;
0557
2017-08-09
pjp
}
0558
2017-08-09
pjp
0559
2017-08-09
pjp
memcpy(packet, imsg.data, packetlen);
0560
2017-08-09
pjp
so = imsg.fd;
0561
2017-08-09
pjp
0562
2019-12-10
pjp
if ((tcpflags = fcntl(so, F_GETFL, 0)) < 0) {
0563
2019-12-10
pjp
dolog(LOG_INFO, "can't query fcntl flags\n");
0564
2019-12-10
pjp
close(so);
0565
2019-12-10
pjp
free(packet);
0566
2019-12-10
pjp
break;
0567
2019-12-10
pjp
}
0568
2019-12-10
pjp
0569
2019-12-10
pjp
/* turn off nonblocking */
0570
2019-12-10
pjp
tcpflags &= ~O_NONBLOCK;
0571
2019-12-10
pjp
0572
2019-12-10
pjp
if (fcntl(so, F_SETFL, tcpflags) < 0) {
0573
2019-12-10
pjp
dolog(LOG_INFO, "can't turn off non-blocking\n");
0574
2019-12-10
pjp
close(so);
0575
2019-12-10
pjp
free(packet);
0576
2019-12-10
pjp
break;
0577
2019-12-10
pjp
}
0578
2019-12-10
pjp
0579
2017-08-09
pjp
memset((char *)&from, 0, sizeof(from));
0580
2017-08-09
pjp
fromlen = sizeof(struct sockaddr_storage);
0581
2017-08-09
pjp
if (getpeername(so, (struct sockaddr *)&from, &fromlen) < 0) {
0582
2017-08-09
pjp
dolog(LOG_ERR, "getpeername: %s\n", strerror(errno));
0583
2017-08-09
pjp
close(so);
0584
2017-08-09
pjp
free(packet);
0585
2017-08-09
pjp
break;
0586
2017-08-09
pjp
}
0587
2017-08-09
pjp
if (from.ss_family == AF_INET6) {
0588
2017-08-09
pjp
is_ipv6 = 1;
0589
2017-08-09
pjp
0590
2017-08-09
pjp
fromlen = sizeof(struct sockaddr_in6);
0591
2017-08-09
pjp
sin6 = (struct sockaddr_in6 *)&from;
0592
2017-08-09
pjp
inet_ntop(AF_INET6, (void*)&sin6->sin6_addr, (char*)&address, sizeof(address));
0593
2017-08-09
pjp
axfr_acl = find_axfr((struct sockaddr_storage *)sin6, AF_INET6);
0594
2017-08-09
pjp
0595
2017-08-09
pjp
} else if (from.ss_family == AF_INET) {
0596
2017-08-09
pjp
is_ipv6 = 0;
0597
2017-08-09
pjp
0598
2017-08-09
pjp
fromlen = sizeof(struct sockaddr_in);
0599
2017-08-09
pjp
sin = (struct sockaddr_in *)&from;
0600
2017-08-09
pjp
inet_ntop(AF_INET, (void*)&sin->sin_addr, (char*)&address, sizeof(address));
0601
2017-08-09
pjp
0602
2017-08-09
pjp
axfr_acl = find_axfr((struct sockaddr_storage *)sin, AF_INET);
0603
2017-08-09
pjp
0604
2017-08-09
pjp
} else {
0605
2017-08-09
pjp
dolog(LOG_INFO, "afd accept unknown family %d, close\n", from.ss_family);
0606
2017-08-09
pjp
close(so);
0607
2017-08-09
pjp
free(packet);
0608
2017-08-09
pjp
break;
0609
2017-08-09
pjp
}
0610
2017-08-09
pjp
0611
2017-08-09
pjp
if (! axfr_acl) {
0612
2017-08-09
pjp
dolog(LOG_INFO, "connection from %s was not in our axfr acl, drop\n", address);
0613
2017-08-09
pjp
close(so);
0614
2017-08-09
pjp
free(packet);
0615
2017-08-09
pjp
break;
0616
2017-08-09
pjp
}
0617
2017-08-09
pjp
0618
2017-08-09
pjp
dolog(LOG_INFO, "AXFR connection from %s passed via descriptor-passing\n", address);
0619
2017-08-09
pjp
0620
2017-08-09
pjp
switch (pid = fork()) {
0621
2017-08-09
pjp
case 0:
0622
2017-08-09
pjp
axfr_connection(so, address, is_ipv6, db, packet, packetlen);
0623
2017-08-09
pjp
exit(0);
0624
2017-08-09
pjp
/*NOTREACHED*/
0625
2017-08-09
pjp
default:
0626
2017-08-09
pjp
close(so);
0627
2017-08-09
pjp
free(packet);
0628
2017-08-09
pjp
break;
0629
2017-08-09
pjp
}
0630
2017-08-09
pjp
0631
2017-08-09
pjp
break;
0632
2017-08-09
pjp
default:
0633
2020-06-25
pjp
dolog(LOG_ERR, "received bad message %d on AXFR imsg\n", imsg.hdr.type);
0634
2017-08-09
pjp
break;
0635
2017-08-09
pjp
}
0636
2017-08-09
pjp
imsg_free(&imsg);
0637
2017-08-09
pjp
} /* else */
0638
2017-08-09
pjp
} /* for (;;) */
0639
2017-08-09
pjp
} /* if (FD_ISSET..) */
0640
2017-08-09
pjp
0641
2014-11-14
pjp
if (notify) {
0642
2014-11-14
pjp
if (notifyfd[0] > -1 && FD_ISSET(notifyfd[0], &rset)) {
0643
2014-11-14
pjp
fromlen = sizeof(struct sockaddr_storage);
0644
2014-11-14
pjp
len = recvfrom(notifyfd[0], buf, sizeof(buf), 0, (struct sockaddr *)&from, &fromlen);
0645
2014-11-14
pjp
if (len < 0) {
0646
2014-11-14
pjp
dolog(LOG_INFO, "recvfrom: %s\n", strerror(errno));
0647
2014-11-14
pjp
}
0648
2014-11-14
pjp
0649
2014-11-14
pjp
if (len < sizeof(struct dns_header)) {
0650
2014-11-14
pjp
dolog(LOG_INFO, "received bogus reply on notify port, drop\n");
0651
2014-11-14
pjp
continue;
0652
2014-11-14
pjp
}
0653
2014-11-14
pjp
0654
2014-11-14
pjp
dh = (struct dns_header *)&buf[0];
0655
2014-11-14
pjp
if (ntohs(dh->question) != 1) {
0656
2014-11-14
pjp
dolog(LOG_INFO, "question header on notify reply not 1, drop\n");
0657
2014-11-14
pjp
continue;
0658
2014-11-14
pjp
}
0659
2014-11-14
pjp
0660
2014-11-14
pjp
if (! (ntohs(dh->query) & DNS_REPLY)) {
0661
2014-11-14
pjp
dolog(LOG_INFO, "question header is not a reply, drop\n");
0662
2014-11-14
pjp
continue;
0663
2014-11-14
pjp
}
0664
2014-11-14
pjp
0665
2019-06-26
pjp
/* save buf */
0666
2019-06-26
pjp
memcpy(&buf0, buf, len);
0667
2019-06-26
pjp
question = build_question(buf0, len, ntohs(dh->additional), NULL);
0668
2019-06-26
pjp
if (question == NULL) {
0669
2019-06-26
pjp
dolog(LOG_INFO, "build_question failed on notify reply, drop\n");
0670
2019-06-26
pjp
continue;
0671
2019-06-26
pjp
}
0672
2019-06-26
pjp
0673
2019-06-26
pjp
/* now walk our notnp list and check the tsig */
0674
2019-06-26
pjp
SLIST_FOREACH(notnp, &notifyhead, notify_entry) {
0675
2019-06-26
pjp
if (memcmp(question->hdr->name, notnp->domain, notnp->domainlen) == 0) {
0676
2019-02-26
pjp
break;
0677
2019-02-26
pjp
}
0678
2019-02-26
pjp
}
0679
2014-11-14
pjp
0680
2019-06-26
pjp
if (notnp == NULL) {
0681
2019-06-26
pjp
dolog(LOG_INFO, "returned name not in list of notify domains\n");
0682
2019-02-26
pjp
continue;
0683
2019-02-26
pjp
}
0684
2019-02-26
pjp
0685
2019-06-26
pjp
0686
2014-11-14
pjp
sin = (struct sockaddr_in *)&from;
0687
2014-11-14
pjp
inet_ntop(AF_INET, (void*)&sin->sin_addr, (char*)&address, sizeof(address));
0688
2014-11-14
pjp
0689
2019-06-26
pjp
if (notnp->usetsig) {
0690
2019-06-26
pjp
free_question(question);
0691
2019-06-26
pjp
0692
2019-06-26
pjp
SLIST_FOREACH(md, &notnp->mzone->dest, entries) {
0693
2019-06-26
pjp
if (sin->sin_addr.s_addr == (((struct sockaddr_in *)md)->sin_addr.s_addr))
0694
2019-06-26
pjp
break;
0695
2019-06-26
pjp
}
0696
2019-06-26
pjp
0697
2019-06-26
pjp
if (md == NULL) {
0698
2019-06-26
pjp
dolog(LOG_INFO, "returned packet not from a source we notified, \"%s\"\n", address);
0699
2019-06-26
pjp
continue;
0700
2019-06-26
pjp
}
0701
2019-06-26
pjp
0702
2019-06-26
pjp
question = build_question(buf, len, ntohs(dh->additional), md->requestmac);
0703
2019-06-26
pjp
if (question == NULL) {
0704
2019-06-26
pjp
dolog(LOG_INFO, "build_question + tsig failed on notify reply, drop\n");
0705
2019-06-26
pjp
continue;
0706
2019-06-26
pjp
}
0707
2019-06-26
pjp
}
0708
2019-06-26
pjp
0709
2019-06-26
pjp
0710
2018-03-28
pjp
SLIST_FOREACH_SAFE(notnp, &notifyhead, notify_entry, notn2) {
0711
2018-03-28
pjp
for (i = 0; i < notify; i++) {
0712
2018-03-28
pjp
if (check_notifyreply(dh, question,
0713
2018-03-28
pjp
(struct sockaddr_storage *) sin, AF_INET, notnp, i) < 0) {
0714
2014-11-14
pjp
dolog(LOG_INFO, "got a reply from a notify host (%s) DNS->ID %u that says: %04x\n", address, ntohs(dh->id), ntohs(dh->query));
0715
2018-03-28
pjp
}
0716
2014-11-14
pjp
}
0717
2014-11-14
pjp
}
0718
2014-11-14
pjp
0719
2014-11-14
pjp
free_question(question);
0720
2014-11-14
pjp
0721
2019-06-26
pjp
if (SLIST_EMPTY(&notifyhead)) {
0722
2014-11-14
pjp
dolog(LOG_INFO, "notifys have been completed, closing notify descriptors!\n");
0723
2014-11-14
pjp
if (notifyfd[0] > -1)
0724
2014-11-14
pjp
close(notifyfd[0]);
0725
2014-11-14
pjp
0726
2014-11-14
pjp
if (notifyfd[1] > -1)
0727
2014-11-14
pjp
close(notifyfd[1]);
0728
2014-11-14
pjp
0729
2014-11-14
pjp
notifyfd[0] = -1;
0730
2014-11-14
pjp
notifyfd[1] = -1;
0731
2017-11-28
pjp
0732
2017-11-28
pjp
notify = 0;
0733
2014-11-14
pjp
}
0734
2014-11-14
pjp
}
0735
2014-11-14
pjp
0736
2014-11-14
pjp
if (notifyfd[1] > -1 && FD_ISSET(notifyfd[1], &rset)) {
0737
2014-11-14
pjp
fromlen = sizeof(struct sockaddr_storage);
0738
2014-11-14
pjp
len = recvfrom(notifyfd[1], buf, sizeof(buf), 0, (struct sockaddr *)&from, &fromlen);
0739
2014-11-14
pjp
if (len < 0) {
0740
2014-11-14
pjp
dolog(LOG_INFO, "recvfrom: %s\n", strerror(errno));
0741
2014-11-14
pjp
}
0742
2014-11-14
pjp
0743
2014-11-14
pjp
if (len < sizeof(struct dns_header)) {
0744
2014-11-14
pjp
dolog(LOG_INFO, "received bogus reply on notify port, drop\n");
0745
2014-11-14
pjp
continue;
0746
2014-11-14
pjp
}
0747
2014-11-14
pjp
0748
2014-11-14
pjp
dh = (struct dns_header *)&buf[0];
0749
2014-11-14
pjp
if (ntohs(dh->question) != 1) {
0750
2014-11-14
pjp
dolog(LOG_INFO, "question header on notify reply not 1, drop\n");
0751
2014-11-14
pjp
continue;
0752
2014-11-14
pjp
}
0753
2014-11-14
pjp
0754
2014-11-14
pjp
if (! (ntohs(dh->query) & DNS_REPLY)) {
0755
2014-11-14
pjp
dolog(LOG_INFO, "question header is not a reply, drop\n");
0756
2014-11-14
pjp
continue;
0757
2014-11-14
pjp
}
0758
2014-11-14
pjp
0759
2019-02-26
pjp
sin6 = (struct sockaddr_in6 *)&from;
0760
2019-02-26
pjp
inet_ntop(AF_INET6, (void*)&sin6->sin6_addr, (char*)&address, sizeof(address));
0761
2019-02-26
pjp
0762
2019-10-26
pjp
/* save buf */
0763
2019-10-26
pjp
memcpy(buf0, buf, len);
0764
2019-10-26
pjp
question = build_question(buf0, len, ntohs(dh->additional), NULL);
0765
2019-06-26
pjp
if (question == NULL) {
0766
2019-06-26
pjp
dolog(LOG_INFO, "build_question failed on notify reply, drop\n");
0767
2019-06-26
pjp
continue;
0768
2019-06-26
pjp
}
0769
2014-11-14
pjp
0770
2019-06-26
pjp
/* now walk our notnp list and check the tsig */
0771
2019-06-26
pjp
SLIST_FOREACH(notnp, &notifyhead, notify_entry) {
0772
2019-06-26
pjp
if (memcmp(question->hdr->name, notnp->domain, notnp->domainlen) == 0) {
0773
2019-02-26
pjp
break;
0774
2019-02-26
pjp
}
0775
2019-02-26
pjp
}
0776
2019-02-26
pjp
0777
2019-06-26
pjp
if (notnp == NULL) {
0778
2019-06-26
pjp
dolog(LOG_INFO, "returned name not in list of notify domains\n");
0779
2019-02-26
pjp
continue;
0780
2019-02-26
pjp
}
0781
2019-02-26
pjp
0782
2019-02-26
pjp
0783
2019-06-26
pjp
if (notnp->usetsig) {
0784
2019-06-26
pjp
free_question(question);
0785
2019-06-26
pjp
SLIST_FOREACH(md, &notnp->mzone->dest, entries) {
0786
2019-06-26
pjp
if (memcmp((void *)&sin6->sin6_addr, (void*)&((struct sockaddr_in6 *)md)->sin6_addr, sizeof(struct in6_addr)) == 0)
0787
2019-06-26
pjp
break;
0788
2019-06-26
pjp
}
0789
2019-06-26
pjp
0790
2019-06-26
pjp
if (md == NULL) {
0791
2019-06-26
pjp
dolog(LOG_INFO, "returned packet not from a source we notified, \"%s\"\n", address);
0792
2019-06-26
pjp
continue;
0793
2019-06-26
pjp
}
0794
2019-06-26
pjp
0795
2019-06-26
pjp
question = build_question(buf, len, ntohs(dh->additional), md->requestmac);
0796
2019-06-26
pjp
if (question == NULL) {
0797
2019-06-26
pjp
dolog(LOG_INFO, "build_question + tsig failed on notify reply, drop\n");
0798
2019-06-26
pjp
continue;
0799
2019-06-26
pjp
}
0800
2019-06-26
pjp
}
0801
2019-06-26
pjp
0802
2019-06-26
pjp
0803
2014-11-14
pjp
SLIST_FOREACH_SAFE(notnp, &notifyhead, notify_entry, notn2) {
0804
2014-11-14
pjp
for (i = 0; i < notify; i++) {
0805
2018-03-28
pjp
if (check_notifyreply(dh, question,
0806
2018-03-28
pjp
(struct sockaddr_storage *) sin6, AF_INET6, notnp, i) < 0) {
0807
2018-03-28
pjp
dolog(LOG_INFO, "got a reply from a notify host (%s) DNS->ID %u that says: %04x\n", address, ntohs(dh->id), ntohs(dh->query));
0808
2018-03-28
pjp
}
0809
2014-11-14
pjp
}
0810
2014-11-14
pjp
}
0811
2014-11-14
pjp
0812
2014-11-14
pjp
free_question(question);
0813
2014-11-14
pjp
0814
2019-06-26
pjp
if (SLIST_EMPTY(&notifyhead)) {
0815
2014-11-14
pjp
dolog(LOG_INFO, "notifys have been completed, closing notify descriptors!\n");
0816
2014-11-14
pjp
if (notifyfd[0] > -1)
0817
2014-11-14
pjp
close(notifyfd[0]);
0818
2014-11-14
pjp
0819
2014-11-14
pjp
if (notifyfd[1] > -1)
0820
2014-11-14
pjp
close(notifyfd[1]);
0821
2014-11-14
pjp
0822
2014-11-14
pjp
notifyfd[0] = -1;
0823
2014-11-14
pjp
notifyfd[1] = -1;
0824
2018-03-28
pjp
0825
2018-03-28
pjp
notify = 0;
0826
2014-11-14
pjp
}
0827
2014-11-14
pjp
}
0828
2014-11-14
pjp
0829
2014-11-14
pjp
}
0830
2014-11-14
pjp
0831
2014-11-14
pjp
} /* for (;;) */
0832
2014-11-14
pjp
0833
2014-11-14
pjp
}
0834
2014-11-14
pjp
0835
2014-11-14
pjp
/*
0836
2014-11-14
pjp
* AXFR_CONNECTION - this is the main core of AXFR engine, forked
0837
2014-11-14
pjp
*
0838
2014-11-14
pjp
*/
0839
2014-11-14
pjp
0840
2014-11-14
pjp
void
0841
2017-08-09
pjp
axfr_connection(int so, char *address, int is_ipv6, ddDB *db, char *packet, int packetlen)
0842
2014-11-14
pjp
{
0843
2014-11-14
pjp
0844
2020-06-29
pjp
char *buf;
0845
2019-02-27
pjp
char tsigkey[512];
0846
2020-08-26
pjp
char *p, *q;
0847
2020-06-29
pjp
char *reply, *replybuf;
0848
2014-11-14
pjp
0849
2020-06-29
pjp
int len, dnslen = 0;
0850
2014-11-14
pjp
int offset = 0;
0851
2014-11-14
pjp
int qlen;
0852
2019-02-15
pjp
int outlen;
0853
2014-11-14
pjp
int rrcount;
0854
2019-02-27
pjp
int envelopcount;
0855
2019-02-27
pjp
int tsigkeylen;
0856
2014-11-14
pjp
0857
2020-08-26
pjp
struct zoneentry find, *res;
0858
2014-11-14
pjp
struct dns_header *dh, *odh;
0859
2014-11-14
pjp
struct sreply sreply;
0860
2014-11-14
pjp
struct question *question, *fq;
0861
2020-08-26
pjp
struct rbtree *rbt = NULL, *rbt2 = NULL, *soa = NULL;
0862
2019-02-15
pjp
struct rrset *rrset = NULL;
0863
2014-11-14
pjp
0864
2017-06-26
pjp
ddDBT key, data;
0865
2019-02-28
pjp
HMAC_CTX *tsigctx = NULL;
0866
2020-06-29
pjp
0867
2014-11-14
pjp
0868
2020-06-29
pjp
#define DDD_AXFR_RECBUF (0xffff + 3)
0869
2020-06-29
pjp
0870
2020-06-29
pjp
if ((buf = calloc(1, DDD_AXFR_RECBUF)) == NULL) {
0871
2020-06-29
pjp
dolog(LOG_ERR, "calloc: %s\n", strerror(errno));
0872
2020-06-29
pjp
close(so);
0873
2020-06-29
pjp
exit(1);
0874
2020-06-29
pjp
}
0875
2020-06-29
pjp
0876
2020-06-29
pjp
p = &buf[0];
0877
2020-06-29
pjp
0878
2020-06-29
pjp
if ((replybuf = calloc(1, 0xffff + 3)) == NULL) {
0879
2020-06-29
pjp
dolog(LOG_ERR, "calloc: %s\n", strerror(errno));
0880
2020-06-29
pjp
close(so);
0881
2020-06-29
pjp
exit(1);
0882
2020-06-29
pjp
}
0883
2020-06-29
pjp
0884
2020-06-29
pjp
0885
2020-06-29
pjp
if (packetlen > DDD_AXFR_RECBUF) {
0886
2017-08-09
pjp
dolog(LOG_ERR, "buffer size of buf is smaller than given packet, drop\n");
0887
2017-08-09
pjp
close(so);
0888
2017-08-09
pjp
exit(1);
0889
2017-08-09
pjp
}
0890
2017-08-09
pjp
0891
2014-11-14
pjp
for (;;) {
0892
2017-08-09
pjp
if (packetlen == 0) {
0893
2020-06-29
pjp
len = recv(so, p + offset, DDD_AXFR_RECBUF - offset, 0);
0894
2017-08-09
pjp
if (len <= 0) {
0895
2017-08-09
pjp
close(so);
0896
2017-08-09
pjp
exit(1);
0897
2017-08-09
pjp
}
0898
2017-08-09
pjp
0899
2017-08-09
pjp
} else {
0900
2017-08-09
pjp
len = packetlen;
0901
2017-08-09
pjp
memcpy(p, packet, packetlen);
0902
2017-08-09
pjp
packetlen = 0;
0903
2014-11-14
pjp
}
0904
2014-11-14
pjp
0905
2014-11-14
pjp
/*
0906
2014-11-14
pjp
* do a little dance here because we don't know if the
0907
2014-11-14
pjp
* input is fragmented or not...
0908
2014-11-14
pjp
*/
0909
2014-11-14
pjp
if (offset + len >= 2) {
0910
2019-12-03
pjp
dnslen = unpack16(p);
0911
2019-12-03
pjp
NTOHS(dnslen);
0912
2014-11-14
pjp
} else {
0913
2014-11-14
pjp
offset += len;
0914
2014-11-14
pjp
continue;
0915
2014-11-14
pjp
}
0916
2020-06-29
pjp
0917
2020-06-29
pjp
/* sanity check around dnslen */
0918
2020-06-29
pjp
if (dnslen > 0 && (dnslen + 2) != (offset + len)) {
0919
2014-11-14
pjp
continue;
0920
2014-11-14
pjp
}
0921
2014-11-14
pjp
0922
2014-11-14
pjp
0923
2014-11-14
pjp
/* by now the packet should be normalized */
0924
2014-11-14
pjp
0925
2014-11-14
pjp
dh = (struct dns_header *)(p + 2);
0926
2014-11-14
pjp
0927
2014-11-14
pjp
if ((ntohs(dh->query) & DNS_REPLY)) {
0928
2014-11-14
pjp
dolog(LOG_INFO, "AXFR dns packet is not a question, drop\n");
0929
2014-11-14
pjp
goto drop;
0930
2014-11-14
pjp
}
0931
2014-11-14
pjp
0932
2014-11-14
pjp
if (ntohs(dh->question) != 1) {
0933
2014-11-14
pjp
dolog(LOG_INFO, "AXFR dns packet does not have a question count of 1 (RFC 5936, page 9), reply fmterror\n");
0934
2014-11-14
pjp
0935
2020-06-29
pjp
build_reply(&sreply, so, (p + 2), dnslen, NULL, NULL, 0, NULL, NULL, 0xff, 1, 0, replybuf);
0936
2014-11-14
pjp
0937
2019-01-25
pjp
reply_fmterror(&sreply, NULL);
0938
2014-11-14
pjp
goto drop;
0939
2014-11-14
pjp
}
0940
2014-11-14
pjp
0941
2019-02-27
pjp
if ((question = build_question((p + 2), dnslen, ntohs(dh->additional), NULL)) == NULL) {
0942
2014-11-14
pjp
dolog(LOG_INFO, "AXFR malformed question, drop\n");
0943
2014-11-14
pjp
goto drop;
0944
2014-11-14
pjp
}
0945
2014-11-14
pjp
0946
2020-08-26
pjp
question->aa = 1;
0947
2020-08-26
pjp
0948
2014-11-14
pjp
if (ntohs(question->hdr->qclass) != DNS_CLASS_IN) {
0949
2014-11-14
pjp
dolog(LOG_INFO, "AXFR question wasn't for class DNS_CLASS_IN, drop\n");
0950
2014-11-14
pjp
goto drop;
0951
2014-11-14
pjp
}
0952
2014-11-14
pjp
0953
2014-11-14
pjp
switch (ntohs(question->hdr->qtype)) {
0954
2014-11-14
pjp
case DNS_TYPE_AXFR:
0955
2014-11-14
pjp
case DNS_TYPE_IXFR:
0956
2014-11-14
pjp
case DNS_TYPE_SOA:
0957
2014-11-14
pjp
break;
0958
2014-11-14
pjp
default:
0959
2014-11-14
pjp
dolog(LOG_INFO, "AXFR question wasn't for valid types (ixfr, axfr, soa) with requested type %d, drop\n", ntohs(question->hdr->qtype));
0960
2014-11-14
pjp
goto drop;
0961
2014-11-14
pjp
0962
2014-11-14
pjp
}
0963
2014-11-14
pjp
0964
2019-02-27
pjp
if (question->tsig.have_tsig && question->tsig.tsigerrorcode != 0) {
0965
2019-12-09
pjp
dolog(LOG_INFO, "AXFR question had TSIG errors, code 0x%02x, drop\n", question->tsig.tsigerrorcode);
0966
2019-02-27
pjp
goto drop;
0967
2019-02-27
pjp
}
0968
2019-02-27
pjp
0969
2014-11-14
pjp
/* now we can be reasonably sure that it's an AXFR for us */
0970
2014-11-14
pjp
0971
2019-11-05
pjp
reply = calloc(1, 0xffff + 2);
0972
2014-11-14
pjp
if (reply == NULL) {
0973
2014-11-14
pjp
dolog(LOG_INFO, "internal error: %s\n", strerror(errno));
0974
2014-11-14
pjp
goto drop;
0975
2014-11-14
pjp
}
0976
2014-11-14
pjp
0977
2014-11-14
pjp
odh = (struct dns_header *)(reply + 2);
0978
2014-11-14
pjp
0979
2014-11-14
pjp
q = question->hdr->name;
0980
2014-11-14
pjp
qlen = question->hdr->namelen;
0981
2014-11-14
pjp
0982
2020-08-26
pjp
if (have_zone(q, qlen) != 1) {
0983
2020-08-26
pjp
dolog(LOG_INFO, "not in our list of zones, drop\n");
0984
2020-08-26
pjp
goto drop;
0985
2020-08-26
pjp
}
0986
2020-08-26
pjp
0987
2019-02-15
pjp
rbt = find_rrset(db, q, qlen);
0988
2019-02-15
pjp
if (rbt == NULL) {
0989
2019-02-15
pjp
rbt2 = get_soa(db, question);
0990
2019-02-15
pjp
if (rbt2 == NULL) {
0991
2015-06-17
pjp
dolog(LOG_INFO, "internal error: %s\n", strerror(errno));
0992
2015-06-17
pjp
goto drop;
0993
2015-06-17
pjp
}
0994
2020-06-29
pjp
build_reply(&sreply, so, (p + 2), dnslen, question, NULL, 0, rbt2, NULL, 0xff, 1, 0, replybuf);
0995
2019-01-25
pjp
reply_nxdomain(&sreply, NULL);
0996
2014-11-14
pjp
dolog(LOG_INFO, "AXFR request for zone %s, no db entry, nxdomain -> drop\n", question->converted_name);
0997
2014-11-14
pjp
goto drop;
0998
2014-11-14
pjp
}
0999
2014-11-14
pjp
1000
2014-11-14
pjp
/*
1001
2014-11-14
pjp
* check if we have an SOA record
1002
2014-11-14
pjp
*/
1003
2014-11-14
pjp
1004
2019-02-15
pjp
if ((rrset = find_rr(rbt, DNS_TYPE_SOA)) == NULL) {
1005
2019-02-15
pjp
rbt2 = get_soa(db, question);
1006
2019-02-15
pjp
if (rbt2 == NULL) {
1007
2015-06-17
pjp
dolog(LOG_INFO, "internal error: %s\n", strerror(errno));
1008
2015-06-17
pjp
goto drop;
1009
2015-06-17
pjp
}
1010
2020-06-29
pjp
build_reply(&sreply, so, (p + 2), dnslen, question, NULL, 0, rbt2, NULL, 0xff, 1, 0, replybuf);
1011
2019-01-25
pjp
reply_nxdomain(&sreply, NULL);
1012
2014-11-14
pjp
1013
2014-11-14
pjp
dolog(LOG_INFO, "AXFR request for zone %s, which has no SOA for the zone, nxdomain -> drop\n", question->converted_name);
1014
2014-11-14
pjp
goto drop;
1015
2019-02-15
pjp
} else {
1016
2019-02-15
pjp
soa = rbt;
1017
2014-11-14
pjp
}
1018
2014-11-14
pjp
1019
2014-11-14
pjp
if (ntohs(question->hdr->qtype) == DNS_TYPE_SOA) {
1020
2014-11-14
pjp
dolog(LOG_INFO, "TCP SOA request for zone \"%s\", replying...\n", question->converted_name);
1021
2014-11-14
pjp
outlen = 0;
1022
2014-11-14
pjp
outlen = build_header(db, (reply + 2), (p + 2), question, 1);
1023
2015-06-17
pjp
outlen = build_soa(db, (reply + 2), outlen, soa, question);
1024
2019-11-05
pjp
if (question->tsig.tsigverified == 1) {
1025
2019-11-05
pjp
struct dns_header *odh;
1026
2019-11-05
pjp
1027
2019-11-05
pjp
odh = (struct dns_header *)&reply[2];
1028
2019-11-05
pjp
outlen = additional_tsig(question, (reply + 2), 0xffff, outlen, 0, 0, NULL);
1029
2019-11-05
pjp
NTOHS(odh->additional);
1030
2019-11-05
pjp
odh->additional++;
1031
2019-11-05
pjp
HTONS(odh->additional);
1032
2019-11-05
pjp
}
1033
2019-11-05
pjp
1034
2019-12-03
pjp
pack16(reply, htons(outlen));
1035
2014-11-14
pjp
len = send(so, reply, outlen + 2, 0);
1036
2014-11-14
pjp
if (len <= 0) {
1037
2014-11-14
pjp
goto drop;
1038
2014-11-14
pjp
}
1039
2014-11-14
pjp
1040
2014-11-14
pjp
outlen = 0;
1041
2014-11-14
pjp
offset = 0;
1042
2014-11-14
pjp
p = &buf[0];
1043
2014-11-14
pjp
1044
2014-11-14
pjp
free (reply);
1045
2014-11-14
pjp
1046
2014-11-14
pjp
continue;
1047
2014-11-14
pjp
}
1048
2014-11-14
pjp
1049
2019-02-27
pjp
/* initialize tsig */
1050
2019-02-27
pjp
1051
2019-02-27
pjp
if (question->tsig.tsigverified) {
1052
2019-02-27
pjp
if ((tsigkeylen = find_tsig_key(question->tsig.tsigkey,
1053
2019-02-27
pjp
question->tsig.tsigkeylen, (char *)&tsigkey, sizeof(tsigkey))) < 0) {
1054
2019-02-27
pjp
dolog(LOG_ERR, "AXFR could not get tsigkey..odd, drop\n");
1055
2019-02-27
pjp
goto drop;
1056
2019-02-27
pjp
1057
2019-02-27
pjp
}
1058
2019-02-27
pjp
1059
2019-02-27
pjp
tsigctx = HMAC_CTX_new();
1060
2019-04-25
pjp
if (HMAC_Init_ex(tsigctx, (const void *)&tsigkey, tsigkeylen, EVP_sha256(), NULL) == 0) {
1061
2019-02-27
pjp
dolog(LOG_ERR, "AXFR tsig initialization error, drop\n");
1062
2019-02-27
pjp
goto drop;
1063
2019-02-27
pjp
}
1064
2019-02-27
pjp
}
1065
2019-02-27
pjp
1066
2019-02-15
pjp
dolog(LOG_INFO, "%s request for zone \"%s\", replying...\n",
1067
2019-02-15
pjp
(ntohs(question->hdr->qtype) == DNS_TYPE_AXFR ? "AXFR"
1068
2019-02-15
pjp
: "IXFR"), question->converted_name);
1069
2014-11-14
pjp
1070
2019-02-27
pjp
1071
2019-02-15
pjp
outlen = build_header(db, (reply + 2), (p + 2), question, 0);
1072
2019-02-15
pjp
outlen = build_soa(db, (reply + 2), outlen, soa, question);
1073
2019-02-15
pjp
rrcount = 1;
1074
2019-02-27
pjp
envelopcount = 1;
1075
2017-06-26
pjp
1076
2020-08-26
pjp
memcpy(find.name, q, qlen);
1077
2020-08-26
pjp
find.namelen = qlen;
1078
2017-06-26
pjp
1079
2020-08-26
pjp
if ((res = RB_FIND(zonetree, &zonehead, &find)) == NULL) {
1080
2020-08-26
pjp
dolog(LOG_INFO, "internal error getting zonename\n");
1081
2020-08-26
pjp
goto drop;
1082
2020-08-26
pjp
}
1083
2020-08-26
pjp
1084
2020-08-26
pjp
TAILQ_FOREACH(wep, &res->walkhead, walk_entry) {
1085
2020-08-26
pjp
rbt = wep->rbt;
1086
2020-08-26
pjp
1087
2019-02-15
pjp
if (checklabel(db, rbt, soa, question)) {
1088
2019-02-26
pjp
fq = build_fake_question(rbt->zone, rbt->zonelen, 0, NULL, 0);
1089
2020-08-26
pjp
fq->aa = 1;
1090
2020-06-29
pjp
build_reply(&sreply, so, (p + 2), dnslen, fq, NULL, 0, rbt, NULL, 0xff, 1, 0, replybuf);
1091
2020-08-26
pjp
1092
2019-02-15
pjp
outlen = create_anyreply(&sreply, (reply + 2), 65535, outlen, 0);
1093
2019-02-15
pjp
free_question(fq);
1094
2019-02-15
pjp
} /* if checklabel */
1095
2014-11-14
pjp
1096
2014-11-14
pjp
/*
1097
2014-11-14
pjp
* if we accumulate 60000 bytes out of the maximum
1098
2014-11-14
pjp
* 65535 bytes then we fragment.
1099
2014-11-14
pjp
*/
1100
2014-11-14
pjp
/* XXX */
1101
2014-11-14
pjp
if (outlen > 60000) {
1102
2019-12-03
pjp
pack16(reply, htons(outlen));
1103
2014-11-14
pjp
1104
2014-11-14
pjp
/* set the rrcount in there */
1105
2014-11-14
pjp
1106
2014-11-14
pjp
NTOHS(odh->answer);
1107
2014-11-14
pjp
odh->answer += rrcount;
1108
2014-11-14
pjp
HTONS(odh->answer);
1109
2014-11-14
pjp
1110
2019-02-27
pjp
if (question->tsig.have_tsig && question->tsig.tsigverified) {
1111
2019-02-28
pjp
int tmplen = outlen;
1112
2019-02-27
pjp
1113
2019-02-28
pjp
outlen = additional_tsig(question, (reply + 2), 65000, outlen, 0, envelopcount, tsigctx);
1114
2019-02-28
pjp
if (tmplen != outlen) {
1115
2019-02-28
pjp
odh->additional = htons(1);
1116
2019-02-28
pjp
1117
2019-02-28
pjp
HMAC_CTX_reset(tsigctx);
1118
2019-04-25
pjp
if (HMAC_Init_ex(tsigctx, (const void *)&tsigkey, tsigkeylen, EVP_sha256(), NULL) == 0) {
1119
2019-02-28
pjp
dolog(LOG_ERR, "AXFR tsig initialization error, drop\n");
1120
2019-02-28
pjp
goto drop;
1121
2019-02-28
pjp
}
1122
2019-02-28
pjp
}
1123
2019-02-28
pjp
1124
2019-02-28
pjp
envelopcount++;
1125
2019-02-28
pjp
1126
2019-12-03
pjp
pack16(reply, htons(outlen));
1127
2019-02-27
pjp
}
1128
2019-02-27
pjp
1129
2014-11-14
pjp
len = send(so, reply, outlen + 2, 0);
1130
2014-11-14
pjp
if (len <= 0) {
1131
2014-11-14
pjp
goto drop;
1132
2014-11-14
pjp
}
1133
2014-11-14
pjp
1134
2014-11-14
pjp
rrcount = 0;
1135
2014-11-14
pjp
outlen = build_header(db, (reply + 2), (p + 2), question, 0);
1136
2014-11-14
pjp
}
1137
2014-11-14
pjp
1138
2014-11-14
pjp
memset(&key, 0, sizeof(key));
1139
2014-11-14
pjp
memset(&data, 0, sizeof(data));
1140
2019-02-15
pjp
if (rbt) {
1141
2019-02-15
pjp
rbt = NULL;
1142
2015-06-17
pjp
}
1143
2019-02-15
pjp
if (rbt2) {
1144
2019-02-15
pjp
rbt2 = NULL;
1145
2015-06-17
pjp
}
1146
2017-06-26
pjp
} /* RB_FOREACH */
1147
2014-11-14
pjp
1148
2015-06-17
pjp
outlen = build_soa(db, (reply + 2), outlen, soa, question);
1149
2014-11-14
pjp
rrcount++;
1150
2014-11-14
pjp
1151
2019-12-03
pjp
pack16(reply, htons(outlen));
1152
2014-11-14
pjp
1153
2014-11-14
pjp
/* set the rrcount in there */
1154
2014-11-14
pjp
1155
2014-11-14
pjp
NTOHS(odh->answer);
1156
2014-11-14
pjp
odh->answer += rrcount;
1157
2014-11-14
pjp
HTONS(odh->answer);
1158
2014-11-14
pjp
1159
2019-02-27
pjp
if (question->tsig.have_tsig && question->tsig.tsigverified) {
1160
2019-02-28
pjp
if (envelopcount == 1)
1161
2019-02-28
pjp
envelopcount = -1;
1162
2019-02-28
pjp
else
1163
2019-02-28
pjp
envelopcount = -2;
1164
2019-02-28
pjp
1165
2019-02-28
pjp
outlen = additional_tsig(question, (reply + 2), 65000, outlen, 0, envelopcount, tsigctx);
1166
2019-02-27
pjp
odh->additional = htons(1);
1167
2019-02-27
pjp
1168
2019-12-03
pjp
pack16(reply, htons(outlen));
1169
2019-02-28
pjp
1170
2019-02-28
pjp
HMAC_CTX_free(tsigctx);
1171
2019-02-27
pjp
}
1172
2019-02-27
pjp
1173
2014-11-14
pjp
len = send(so, reply, outlen + 2, 0);
1174
2014-11-14
pjp
if (len <= 0)
1175
2014-11-14
pjp
goto drop;
1176
2014-11-14
pjp
1177
2014-11-14
pjp
goto drop;
1178
2014-11-14
pjp
1179
2014-11-14
pjp
} /* for(;;) */
1180
2014-11-14
pjp
1181
2014-11-14
pjp
1182
2014-11-14
pjp
1183
2014-11-14
pjp
drop:
1184
2015-06-17
pjp
if (soa) {
1185
2015-06-17
pjp
free (soa);
1186
2015-06-17
pjp
soa = NULL;
1187
2015-06-17
pjp
}
1188
2015-06-17
pjp
1189
2019-02-15
pjp
if (rbt) {
1190
2019-02-15
pjp
rbt = NULL;
1191
2015-06-17
pjp
}
1192
2015-06-17
pjp
1193
2019-02-15
pjp
if (rbt2) {
1194
2019-02-15
pjp
rbt2 = NULL;
1195
2015-06-17
pjp
}
1196
2015-06-17
pjp
1197
2014-11-14
pjp
close(so);
1198
2014-11-14
pjp
exit(0);
1199
2014-11-14
pjp
}
1200
2014-11-14
pjp
1201
2014-11-14
pjp
/*
1202
2014-11-14
pjp
* REAP - reap the child that is zombied by now, this is a sighandler for
1203
2014-11-14
pjp
* SIGCHLD
1204
2014-11-14
pjp
*/
1205
2014-11-14
pjp
1206
2014-11-14
pjp
void
1207
2014-11-14
pjp
reap(int sig)
1208
2014-11-14
pjp
{
1209
2014-11-14
pjp
int status;
1210
2014-11-14
pjp
pid_t pid;
1211
2014-11-14
pjp
1212
2014-11-14
pjp
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
1213
2014-11-14
pjp
}
1214
2014-11-14
pjp
}
1215
2014-11-14
pjp
1216
2014-11-14
pjp
1217
2014-11-14
pjp
/*
1218
2014-11-14
pjp
* build_header - build a header reply
1219
2014-11-14
pjp
*
1220
2014-11-14
pjp
*/
1221
2014-11-14
pjp
1222
2014-11-14
pjp
int
1223
2017-06-26
pjp
build_header(ddDB *db, char *reply, char *buf, struct question *q, int answercount)
1224
2014-11-14
pjp
{
1225
2014-11-14
pjp
struct dns_header *odh;
1226
2014-11-14
pjp
u_int16_t outlen;
1227
2014-11-14
pjp
1228
2014-11-14
pjp
odh = (struct dns_header *)reply;
1229
2014-11-14
pjp
outlen = sizeof(struct dns_header);
1230
2014-11-14
pjp
1231
2014-11-14
pjp
/* copy question to reply */
1232
2014-11-14
pjp
memcpy(reply, buf, sizeof(struct dns_header) + q->hdr->namelen + 4);
1233
2014-11-14
pjp
/* blank query */
1234
2014-11-14
pjp
memset((char *)&odh->query, 0, sizeof(u_int16_t));
1235
2014-11-14
pjp
1236
2014-11-14
pjp
outlen += (q->hdr->namelen + 4);
1237
2014-11-14
pjp
1238
2014-11-14
pjp
SET_DNS_REPLY(odh);
1239
2014-11-14
pjp
SET_DNS_AUTHORITATIVE(odh);
1240
2014-11-14
pjp
1241
2019-12-03
pjp
/* XXX */
1242
2019-12-03
pjp
HTONS(odh->query);
1243
2014-11-14
pjp
1244
2014-11-14
pjp
odh->question = htons(1);
1245
2014-11-14
pjp
odh->answer = htons(answercount);
1246
2014-11-14
pjp
odh->nsrr = 0;
1247
2014-11-14
pjp
odh->additional = 0;
1248
2014-11-14
pjp
1249
2014-11-14
pjp
return (outlen);
1250
2014-11-14
pjp
}
1251
2014-11-14
pjp
1252
2014-11-14
pjp
1253
2014-11-14
pjp
1254
2014-11-14
pjp
/*
1255
2014-11-14
pjp
* BUILD_SOA - build an SOA answer
1256
2014-11-14
pjp
*/
1257
2014-11-14
pjp
1258
2014-11-14
pjp
int
1259
2019-02-15
pjp
build_soa(ddDB *db, char *reply, int offset, struct rbtree *rbt, struct question *q)
1260
2014-11-14
pjp
{
1261
2014-11-14
pjp
char *label;
1262
2014-11-14
pjp
char *plabel;
1263
2014-11-14
pjp
1264
2014-11-14
pjp
int labellen;
1265
2014-11-14
pjp
int tmplen;
1266
2014-11-14
pjp
1267
2014-11-14
pjp
struct answer {
1268
2014-11-14
pjp
char name[2];
1269
2014-11-14
pjp
u_int16_t type;
1270
2014-11-14
pjp
u_int16_t class;
1271
2014-11-14
pjp
u_int32_t ttl;
1272
2014-11-14
pjp
u_int16_t rdlength; /* 12 */
1273
2014-11-14
pjp
char rdata;
1274
2014-11-14
pjp
} __attribute__((packed));
1275
2014-11-14
pjp
1276
2014-11-14
pjp
struct answer *answer;
1277
2019-02-15
pjp
struct rrset *rrset = NULL;
1278
2019-02-15
pjp
struct rr *rrp = NULL;
1279
2015-06-17
pjp
1280
2019-02-15
pjp
if ((rrset = find_rr(rbt, DNS_TYPE_SOA)) == NULL) {
1281
2019-02-15
pjp
return 0;
1282
2019-02-15
pjp
}
1283
2019-02-15
pjp
if ((rrp = TAILQ_FIRST(&rrset->rr_head)) == NULL) {
1284
2019-02-15
pjp
return 0;
1285
2019-02-15
pjp
}
1286
2019-02-15
pjp
1287
2014-11-14
pjp
answer = (struct answer *)(&reply[offset]);
1288
2014-11-14
pjp
1289
2014-11-14
pjp
answer->name[0] = 0xc0;
1290
2014-11-14
pjp
answer->name[1] = 0x0c;
1291
2014-11-14
pjp
answer->type = htons(DNS_TYPE_SOA);
1292
2014-11-14
pjp
answer->class = htons(DNS_CLASS_IN);
1293
2020-05-07
pjp
answer->ttl = htonl(rrset->ttl);
1294
2014-11-14
pjp
1295
2014-11-14
pjp
offset += 12; /* up to rdata length */
1296
2014-11-14
pjp
1297
2019-02-15
pjp
label = ((struct soa *)rrp->rdata)->nsserver;
1298
2019-02-15
pjp
labellen = ((struct soa *)rrp->rdata)->nsserver_len;
1299
2014-11-14
pjp
1300
2014-11-14
pjp
plabel = label;
1301
2014-11-14
pjp
1302
2014-11-14
pjp
if (offset + labellen <= 65535)
1303
2014-11-14
pjp
memcpy(&reply[offset], (char *)plabel, labellen);
1304
2014-11-14
pjp
else
1305
2014-11-14
pjp
return (offset); /* XXX */
1306
2014-11-14
pjp
1307
2014-11-14
pjp
offset += labellen;
1308
2014-11-14
pjp
1309
2014-11-14
pjp
/* compress the label if possible */
1310
2014-11-14
pjp
if ((tmplen = compress_label((u_char*)reply, offset, labellen)) > 0) {
1311
2014-11-14
pjp
offset = tmplen;
1312
2014-11-14
pjp
}
1313
2014-11-14
pjp
1314
2019-02-15
pjp
label = ((struct soa *)rrp->rdata)->responsible_person;
1315
2019-02-15
pjp
labellen = ((struct soa *)rrp->rdata)->rp_len;
1316
2014-11-14
pjp
plabel = label;
1317
2014-11-14
pjp
1318
2014-11-14
pjp
if (offset + labellen <= 65535)
1319
2014-11-14
pjp
memcpy(&reply[offset], (char *)plabel, labellen);
1320
2014-11-14
pjp
else
1321
2014-11-14
pjp
return (offset); /* XXX */
1322
2014-11-14
pjp
1323
2014-11-14
pjp
offset += labellen;
1324
2014-11-14
pjp
1325
2014-11-14
pjp
/* 2 compress the label if possible */
1326
2014-11-14
pjp
1327
2014-11-14
pjp
if ((tmplen = compress_label((u_char*)reply, offset, labellen)) > 0) {
1328
2014-11-14
pjp
offset = tmplen;
1329
2014-11-14
pjp
}
1330
2014-11-14
pjp
1331
2014-11-14
pjp
1332
2014-11-14
pjp
/* XXX */
1333
2019-02-15
pjp
if ((offset + sizeof(u_int32_t)) >= 65535 ) {
1334
2014-11-14
pjp
/* XXX server error reply? */
1335
2014-11-14
pjp
return (offset);
1336
2014-11-14
pjp
}
1337
2019-12-03
pjp
pack32(&reply[offset], htonl(((struct soa *)rrp->rdata)->serial));
1338
2019-02-15
pjp
offset += sizeof(u_int32_t);
1339
2014-11-14
pjp
1340
2019-02-15
pjp
if ((offset + sizeof(u_int32_t)) >= 65535 ) {
1341
2014-11-14
pjp
return (offset);
1342
2014-11-14
pjp
}
1343
2019-12-03
pjp
pack32(&reply[offset], htonl(((struct soa *)rrp->rdata)->refresh));
1344
2019-02-15
pjp
offset += sizeof(u_int32_t);
1345
2014-11-14
pjp
1346
2019-02-15
pjp
if ((offset + sizeof(u_int32_t)) >= 65535 ) {
1347
2014-11-14
pjp
return (offset);
1348
2014-11-14
pjp
}
1349
2019-12-03
pjp
pack32(&reply[offset], htonl(((struct soa *)rrp->rdata)->retry));
1350
2019-02-15
pjp
offset += sizeof(u_int32_t);
1351
2014-11-14
pjp
1352
2019-02-15
pjp
if ((offset + sizeof(u_int32_t)) >= 65535 ) {
1353
2014-11-14
pjp
return (offset);
1354
2014-11-14
pjp
}
1355
2019-12-03
pjp
pack32(&reply[offset], htonl(((struct soa *)rrp->rdata)->expire));
1356
2019-02-15
pjp
offset += sizeof(u_int32_t);
1357
2014-11-14
pjp
1358
2019-02-15
pjp
if ((offset + sizeof(u_int32_t)) > 65535 ) {
1359
2014-11-14
pjp
return (offset);
1360
2014-11-14
pjp
}
1361
2019-12-03
pjp
pack32(&reply[offset], htonl(((struct soa *)rrp->rdata)->minttl));
1362
2019-02-15
pjp
offset += sizeof(u_int32_t);
1363
2014-11-14
pjp
1364
2014-11-14
pjp
answer->rdlength = htons(&reply[offset] - &answer->rdata);
1365
2014-11-14
pjp
1366
2014-11-14
pjp
return (offset);
1367
2014-11-14
pjp
}
1368
2014-11-14
pjp
1369
2014-11-14
pjp
int
1370
2019-02-15
pjp
checklabel(ddDB *db, struct rbtree *rbt, struct rbtree *soa, struct question *q)
1371
2014-11-14
pjp
{
1372
2014-11-14
pjp
return (1);
1373
2014-11-14
pjp
}
1374
2014-11-14
pjp
1375
2014-11-14
pjp
void
1376
2017-06-26
pjp
gather_notifydomains(ddDB *db)
1377
2014-11-14
pjp
{
1378
2017-06-26
pjp
ddDBT key, data;
1379
2014-11-14
pjp
1380
2014-11-14
pjp
time_t now, soatime;
1381
2014-11-14
pjp
struct tm *tm;
1382
2014-11-14
pjp
1383
2014-11-14
pjp
char timestring[128];
1384
2014-11-14
pjp
char buf[128];
1385
2014-11-14
pjp
1386
2017-06-26
pjp
struct node *n, *nx;
1387
2019-02-15
pjp
struct rbtree *rbt;
1388
2019-02-15
pjp
struct rrset *rrset = NULL;
1389
2019-02-15
pjp
struct rr *rrp = NULL;
1390
2019-06-26
pjp
struct mzone *mz;
1391
2019-06-26
pjp
struct mzone_dest *md;
1392
2019-06-26
pjp
int i;
1393
2014-11-14
pjp
1394
2014-11-14
pjp
SLIST_INIT(&notifyhead);
1395
2014-11-14
pjp
1396
2014-11-14
pjp
now = time(NULL);
1397
2014-11-14
pjp
tm = localtime(&now);
1398
2020-03-10
pjp
1399
2020-03-10
pjp
/* adjust for offset taken before chroot */
1400
2020-03-10
pjp
tm->tm_gmtoff = glob_time_offset;
1401
2020-03-10
pjp
1402
2014-11-14
pjp
if (tm != NULL)
1403
2014-11-14
pjp
strftime(timestring, sizeof(timestring), "%Y%m%d", tm);
1404
2014-11-14
pjp
else
1405
2014-11-14
pjp
snprintf(timestring, sizeof(timestring), "19700101");
1406
2014-11-14
pjp
1407
2014-11-14
pjp
now = time(NULL);
1408
2014-11-14
pjp
1409
2014-11-14
pjp
memset(&key, 0, sizeof(key));
1410
2014-11-14
pjp
memset(&data, 0, sizeof(data));
1411
2014-11-14
pjp
1412
2019-02-19
pjp
RB_FOREACH_SAFE(n, domaintree, &db->head, nx) {
1413
2019-02-15
pjp
rbt = (struct rbtree *)n->data;
1414
2014-11-14
pjp
1415
2019-02-15
pjp
if ((rrset = find_rr(rbt, DNS_TYPE_SOA)) != NULL) {
1416
2019-02-15
pjp
rrp = TAILQ_FIRST(&rrset->rr_head);
1417
2014-11-14
pjp
notn2 = malloc(sizeof(struct notifyentry));
1418
2014-11-14
pjp
if (notn2 == NULL) {
1419
2014-11-14
pjp
continue;
1420
2014-11-14
pjp
}
1421
2014-11-14
pjp
1422
2014-11-14
pjp
notn2->ids = calloc(notify, sizeof(u_int16_t));
1423
2014-11-14
pjp
if (notn2->ids == NULL) {
1424
2014-11-14
pjp
free(notn2);
1425
2014-11-14
pjp
continue;
1426
2014-11-14
pjp
}
1427
2014-11-14
pjp
1428
2014-11-14
pjp
notn2->attempts = calloc(notify, sizeof(u_int16_t));
1429
2014-11-14
pjp
if (notn2->attempts == NULL) {
1430
2014-11-14
pjp
free(notn2);
1431
2014-11-14
pjp
continue;
1432
2014-11-14
pjp
}
1433
2014-11-14
pjp
1434
2019-02-15
pjp
memcpy(notn2->domain, rbt->zone, rbt->zonelen);
1435
2019-02-15
pjp
notn2->domainlen = rbt->zonelen;
1436
2014-11-14
pjp
1437
2019-06-26
pjp
1438
2019-06-26
pjp
SLIST_FOREACH(mz, &mzones, mzone_entry) {
1439
2019-06-26
pjp
if (notn2->domainlen == mz->zonenamelen &&
1440
2019-06-26
pjp
memcmp(notn2->domain, mz->zonename, notn2->domainlen) == 0) {
1441
2019-06-26
pjp
break;
1442
2019-06-26
pjp
}
1443
2019-06-26
pjp
}
1444
2019-06-26
pjp
1445
2019-06-26
pjp
if (mz == NULL) {
1446
2019-06-26
pjp
dolog(LOG_INFO, "skipping zone \"%s\" due to no mzone entry for it!\n", rbt->humanname);
1447
2019-06-26
pjp
free(notn2->attempts);
1448
2019-06-26
pjp
free(notn2);
1449
2019-06-26
pjp
continue;
1450
2019-06-26
pjp
}
1451
2019-06-26
pjp
1452
2019-06-26
pjp
notn2->mzone = mz;
1453
2019-06-26
pjp
1454
2019-06-26
pjp
i = 0;
1455
2019-06-26
pjp
/* initialize notifications to 1 */
1456
2019-06-26
pjp
SLIST_FOREACH(md, &mz->dest, entries) {
1457
2019-06-26
pjp
md->notified = 1;
1458
2019-06-26
pjp
i++;
1459
2019-06-26
pjp
}
1460
2019-06-26
pjp
1461
2019-06-26
pjp
notn2->numadd = i;
1462
2019-06-26
pjp
1463
2019-02-15
pjp
soatime = (time_t)((struct soa *)rrp->rdata)->serial;
1464
2019-02-15
pjp
snprintf(buf, sizeof(buf), "%u", ((struct soa *)rrp->rdata)->serial);
1465
2019-02-15
pjp
1466
2014-11-14
pjp
if (strncmp(buf, timestring, strlen(timestring)) == 0) {
1467
2019-02-15
pjp
dolog(LOG_INFO, "inserting zone \"%s\" for notification...\n", rbt->humanname);
1468
2014-11-14
pjp
SLIST_INSERT_HEAD(&notifyhead, notn2, notify_entry);
1469
2014-11-14
pjp
} else if (difftime(now, soatime) < 1800 && difftime(now, soatime) > 0) {
1470
2019-02-15
pjp
dolog(LOG_INFO, "2 inserting zone \"%s\" for notification...\n", rbt->humanname);
1471
2014-11-14
pjp
SLIST_INSERT_HEAD(&notifyhead, notn2, notify_entry);
1472
2014-11-14
pjp
} else {
1473
2014-11-14
pjp
#if 0
1474
2019-02-15
pjp
dolog(LOG_INFO, "SOA serial for zone \"%s\" did not make sense (%s), not notifying\n", rbt->humanname, buf);
1475
2014-11-14
pjp
#endif
1476
2019-06-26
pjp
free(notn2->attempts);
1477
2014-11-14
pjp
free(notn2);
1478
2014-11-14
pjp
}
1479
2014-11-14
pjp
}
1480
2014-11-14
pjp
1481
2014-11-14
pjp
memset(&key, 0, sizeof(key));
1482
2014-11-14
pjp
memset(&data, 0, sizeof(data));
1483
2017-06-26
pjp
}
1484
2014-11-14
pjp
1485
2014-11-14
pjp
return;
1486
2014-11-14
pjp
}
1487
2014-11-14
pjp
1488
2019-06-26
pjp
void
1489
2020-06-25
pjp
notifyddds(int *notifyfd)
1490
2014-11-14
pjp
{
1491
2019-06-26
pjp
struct mzone_dest *md;
1492
2014-11-14
pjp
int so;
1493
2019-06-26
pjp
int i, remove;
1494
2014-11-14
pjp
1495
2014-11-14
pjp
i = 0;
1496
2014-11-14
pjp
1497
2019-06-26
pjp
SLIST_FOREACH_SAFE(notnp, &notifyhead, notify_entry, notn2) {
1498
2019-06-26
pjp
remove = 0;
1499
2019-06-26
pjp
SLIST_FOREACH(md, &notnp->mzone->dest, entries) {
1500
2019-06-26
pjp
if (md->notifydest.ss_family == AF_INET)
1501
2019-06-26
pjp
so = notifyfd[0];
1502
2019-06-26
pjp
else
1503
2019-06-26
pjp
so = notifyfd[1];
1504
2019-06-26
pjp
1505
2014-11-14
pjp
notnp->ids[i] = arc4random() & 0xffff;
1506
2014-11-14
pjp
notnp->attempts[i]++;
1507
2014-11-14
pjp
if (notnp->attempts[i] > 10) {
1508
2014-11-14
pjp
dolog(LOG_INFO, "notify entry removed due to timeout\n");
1509
2019-06-26
pjp
remove = 1;
1510
2019-06-26
pjp
break;
1511
2014-11-14
pjp
}
1512
2014-11-14
pjp
1513
2019-06-26
pjp
if (md->notified == 1)
1514
2019-06-26
pjp
notifypacket(so, notnp, md, i);
1515
2019-06-26
pjp
1516
2019-06-26
pjp
i++;
1517
2014-11-14
pjp
}
1518
2014-11-14
pjp
1519
2019-06-26
pjp
if (remove) {
1520
2019-06-26
pjp
dolog(LOG_INFO, "removed domain \"%s\"\n", notnp->mzone->humanname);
1521
2019-06-26
pjp
SLIST_REMOVE(&notifyhead, notnp, notifyentry, notify_entry);
1522
2019-06-26
pjp
}
1523
2014-11-14
pjp
}
1524
2014-11-14
pjp
1525
2014-11-14
pjp
return;
1526
2014-11-14
pjp
}
1527
2014-11-14
pjp
1528
2014-11-14
pjp
void
1529
2019-06-26
pjp
notifypacket(int so, void *vnotnp, void *vmd, int packetcount)
1530
2014-11-14
pjp
{
1531
2014-11-14
pjp
struct notifyentry *notnp = (struct notifyentry *)vnotnp;
1532
2019-06-26
pjp
struct mzone *mz = (struct mzone *)notnp->mzone;
1533
2019-06-26
pjp
struct mzone_dest *md = (struct mzone_dest *)vmd;
1534
2020-08-08
pjp
struct sockaddr_in bsin;
1535
2020-08-08
pjp
struct sockaddr_in6 bsin6;
1536
2019-06-26
pjp
struct sockaddr_storage savesin, newsin;
1537
2014-11-14
pjp
char packet[512];
1538
2014-11-14
pjp
char *questionname;
1539
2014-11-14
pjp
u_int16_t *classtype;
1540
2014-11-14
pjp
struct dns_header *dnh;
1541
2019-02-26
pjp
struct question *fq = NULL;
1542
2014-11-14
pjp
int outlen = 0, slen, ret;
1543
2019-06-26
pjp
int sinlen;
1544
2014-11-14
pjp
1545
2019-06-26
pjp
1546
2019-06-26
pjp
memcpy(&newsin, (char *)&mz->notifybind, sizeof(struct sockaddr_storage));
1547
2019-06-26
pjp
sinlen = sizeof(struct sockaddr_storage);
1548
2019-06-26
pjp
if (getsockname(so, (struct sockaddr *)&savesin, &sinlen) < 0) {
1549
2019-06-26
pjp
dolog(LOG_INFO, "getsockname error\n");
1550
2019-06-26
pjp
return;
1551
2019-06-26
pjp
}
1552
2019-06-26
pjp
1553
2019-06-26
pjp
if (mz->notifybind.ss_family == AF_INET) {
1554
2019-06-26
pjp
struct sockaddr_in *tmpsin = (struct sockaddr_in *)&newsin;
1555
2019-06-26
pjp
1556
2019-06-26
pjp
1557
2019-06-26
pjp
tmpsin->sin_port = ((struct sockaddr_in *)&savesin)->sin_port;
1558
2019-06-26
pjp
1559
2019-06-26
pjp
if (bind(so, (struct sockaddr *)tmpsin, sizeof(struct sockaddr_in)) < 0) {
1560
2019-06-26
pjp
dolog(LOG_INFO, "can't bind to bind address found in mzone for zone \"%s\"", mz->humanname);
1561
2019-06-26
pjp
return;
1562
2019-06-26
pjp
}
1563
2019-06-26
pjp
} else if (mz->notifybind.ss_family == AF_INET6) {
1564
2019-06-26
pjp
struct sockaddr_in6 *tmpsin = (struct sockaddr_in6 *)&newsin;
1565
2019-06-26
pjp
1566
2019-06-26
pjp
tmpsin->sin6_port = ((struct sockaddr_in6 *)&savesin)->sin6_port;
1567
2019-11-19
pjp
#ifndef __linux__
1568
2019-10-26
pjp
tmpsin->sin6_len = sizeof(struct sockaddr_in6);
1569
2019-11-19
pjp
#endif
1570
2019-06-26
pjp
1571
2019-06-26
pjp
if (bind(so, (struct sockaddr *)tmpsin, sizeof(struct sockaddr_in6)) < 0) {
1572
2019-06-26
pjp
dolog(LOG_INFO, "can't bind to v6 bind address found in mzone for zone \"%s\"", mz->humanname);
1573
2019-06-26
pjp
return;
1574
2019-06-26
pjp
}
1575
2019-06-26
pjp
}
1576
2019-06-26
pjp
1577
2014-11-14
pjp
memset(&packet, 0, sizeof(packet));
1578
2014-11-14
pjp
dnh = (struct dns_header *)&packet[0];
1579
2014-11-14
pjp
1580
2014-11-14
pjp
dnh->id = htons(notnp->ids[packetcount]);
1581
2014-11-14
pjp
SET_DNS_NOTIFY(dnh);
1582
2014-11-14
pjp
SET_DNS_AUTHORITATIVE(dnh);
1583
2014-11-14
pjp
SET_DNS_QUERY(dnh);
1584
2014-11-14
pjp
HTONS(dnh->query);
1585
2014-11-14
pjp
1586
2014-11-14
pjp
dnh->question = htons(1);
1587
2014-11-14
pjp
1588
2014-11-14
pjp
outlen += sizeof(struct dns_header);
1589
2014-11-14
pjp
questionname = (char *)&packet[outlen];
1590
2014-11-14
pjp
1591
2014-11-14
pjp
memcpy(questionname, notnp->domain, notnp->domainlen);
1592
2014-11-14
pjp
outlen += notnp->domainlen;
1593
2014-11-14
pjp
1594
2014-11-14
pjp
classtype = (u_int16_t *)&packet[outlen];
1595
2014-11-14
pjp
classtype[0] = htons(DNS_TYPE_SOA);
1596
2014-11-14
pjp
classtype[1] = htons(DNS_CLASS_IN);
1597
2014-11-14
pjp
1598
2014-11-14
pjp
outlen += (2 * sizeof(u_int16_t));
1599
2019-02-26
pjp
1600
2019-02-26
pjp
/* work out the tsig stuff */
1601
2019-06-26
pjp
if (md->tsigkey != NULL) {
1602
2019-06-26
pjp
char *tsigname;
1603
2019-06-26
pjp
int tsignamelen;
1604
2019-06-26
pjp
1605
2019-06-26
pjp
tsigname = dns_label(md->tsigkey, &tsignamelen);
1606
2019-06-26
pjp
if (tsigname == NULL) {
1607
2019-06-26
pjp
dolog(LOG_INFO, "dns_label()");
1608
2019-02-26
pjp
return;
1609
2019-02-26
pjp
}
1610
2019-02-26
pjp
1611
2019-06-26
pjp
if ((fq = build_fake_question(notnp->domain, notnp->domainlen, 0, tsigname, tsignamelen)) == NULL) {
1612
2019-06-26
pjp
return;
1613
2019-06-26
pjp
}
1614
2019-06-26
pjp
1615
2019-02-28
pjp
outlen = additional_tsig(fq, packet, sizeof(packet), outlen, 1, 0, NULL);
1616
2019-02-26
pjp
1617
2019-02-26
pjp
dnh->additional = htons(1);
1618
2019-02-26
pjp
1619
2019-06-26
pjp
memcpy(&md->requestmac, fq->tsig.tsigmac, 32);
1620
2019-06-26
pjp
notnp->usetsig = 1;
1621
2019-06-26
pjp
1622
2019-06-26
pjp
free(tsigname);
1623
2019-02-26
pjp
free_question(fq);
1624
2019-06-26
pjp
} else {
1625
2019-06-26
pjp
notnp->usetsig = 0;
1626
2019-02-26
pjp
}
1627
2019-06-26
pjp
1628
2019-06-26
pjp
if (savesin.ss_family == AF_INET) {
1629
2019-06-26
pjp
struct sockaddr_in *tmpsin = (struct sockaddr_in *)&md->notifydest;
1630
2019-06-26
pjp
1631
2014-11-14
pjp
slen = sizeof(struct sockaddr_in);
1632
2014-11-14
pjp
memset(&bsin, 0, sizeof(bsin));
1633
2014-11-14
pjp
bsin.sin_family = AF_INET;
1634
2019-07-09
pjp
bsin.sin_port = htons(md->port);
1635
2019-06-26
pjp
bsin.sin_addr.s_addr = tmpsin->sin_addr.s_addr;
1636
2014-11-14
pjp
1637
2014-11-14
pjp
ret = sendto(so, packet, outlen, 0, (struct sockaddr *)&bsin, slen);
1638
2014-11-14
pjp
} else {
1639
2019-06-26
pjp
struct sockaddr_in6 *tmpsin = (struct sockaddr_in6 *)&md->notifydest;
1640
2019-06-26
pjp
1641
2014-11-14
pjp
slen = sizeof(struct sockaddr_in6);
1642
2014-11-14
pjp
memset(&bsin6, 0, sizeof(bsin6));
1643
2014-11-14
pjp
bsin6.sin6_family = AF_INET6;
1644
2019-07-09
pjp
bsin6.sin6_port = htons(md->port);
1645
2019-11-19
pjp
#ifndef __linux__
1646
2019-10-26
pjp
bsin6.sin6_len = sizeof(struct sockaddr_in6);
1647
2019-11-19
pjp
#endif
1648
2019-06-26
pjp
memcpy(&bsin6.sin6_addr, &tmpsin->sin6_addr, 16);
1649
2014-11-14
pjp
1650
2019-10-26
pjp
ret = sendto(so, packet, outlen, 0, (struct sockaddr *)&bsin6, slen);
1651
2014-11-14
pjp
}
1652
2014-11-14
pjp
1653
2014-11-14
pjp
if (ret < 0) {
1654
2014-11-14
pjp
dolog(LOG_INFO, "sendto: %s\n", strerror(errno));
1655
2014-11-14
pjp
}
1656
2019-06-26
pjp
1657
2019-06-26
pjp
/* as soon as the sendto is done we want to bind back to 0.0.0.0 */
1658
2019-06-26
pjp
if (mz->notifybind.ss_family == AF_INET) {
1659
2019-06-26
pjp
struct sockaddr_in *tmpsin = (struct sockaddr_in *)&savesin;
1660
2019-06-26
pjp
1661
2019-06-26
pjp
if (bind(so, (struct sockaddr *)tmpsin, sizeof(struct sockaddr_in)) < 0) {
1662
2019-06-26
pjp
dolog(LOG_INFO, "can't unbind from bind address found in mzone for zone \"%s\"", mz->humanname);
1663
2019-06-26
pjp
return;
1664
2019-06-26
pjp
}
1665
2019-06-26
pjp
} else if (mz->notifybind.ss_family == AF_INET6) {
1666
2019-06-26
pjp
struct sockaddr_in6 *tmpsin = (struct sockaddr_in6 *)&savesin;
1667
2019-06-26
pjp
1668
2019-06-26
pjp
if (bind(so, (struct sockaddr *)tmpsin, sizeof(struct sockaddr_in6)) < 0) {
1669
2019-06-26
pjp
dolog(LOG_INFO, "can't unbind from bind address found in mzone for zone \"%s\"", mz->humanname);
1670
2019-06-26
pjp
return;
1671
2019-06-26
pjp
}
1672
2019-06-26
pjp
}
1673
2014-11-14
pjp
1674
2014-11-14
pjp
return;
1675
2018-03-28
pjp
}
1676
2018-03-28
pjp
1677
2018-03-28
pjp
int
1678
2018-03-28
pjp
check_notifyreply(struct dns_header *dh, struct question *question, struct sockaddr_storage *ss, int af, struct notifyentry *notnp, int count)
1679
2018-03-28
pjp
{
1680
2019-06-26
pjp
struct mzone_dest *md, *md2;
1681
2018-03-28
pjp
struct sockaddr_in6 *sin6, *sin62 = NULL;
1682
2018-03-28
pjp
struct sockaddr_in *sin, *sin2 = NULL;
1683
2018-03-28
pjp
char address[INET6_ADDRSTRLEN];
1684
2018-03-28
pjp
u_int16_t ntohsquery;
1685
2018-03-28
pjp
1686
2018-03-28
pjp
switch (af) {
1687
2018-03-28
pjp
case AF_INET6:
1688
2018-03-28
pjp
sin6 = (struct sockaddr_in6 *)ss;
1689
2018-03-28
pjp
inet_ntop(AF_INET6, (void*)&sin6->sin6_addr, (char*)&address, sizeof(address));
1690
2018-03-28
pjp
break;
1691
2018-03-28
pjp
case AF_INET:
1692
2018-03-28
pjp
sin = (struct sockaddr_in *)ss;
1693
2018-03-28
pjp
inet_ntop(AF_INET, (void*)&sin->sin_addr, (char*)&address, sizeof(address));
1694
2018-03-28
pjp
break;
1695
2018-03-28
pjp
default:
1696
2018-03-28
pjp
return -1;
1697
2018-03-28
pjp
break;
1698
2018-03-28
pjp
}
1699
2018-03-28
pjp
1700
2018-03-28
pjp
ntohsquery = ntohs(dh->query);
1701
2018-03-28
pjp
1702
2018-03-28
pjp
if (ntohs(dh->id) == notnp->ids[count] &&
1703
2018-03-28
pjp
(((ntohsquery & DNS_NOTIFY) && (ntohsquery & DNS_AUTH)) ||
1704
2018-03-28
pjp
(ntohsquery & (DNS_AUTH | DNS_REPLY)) ||
1705
2018-03-28
pjp
(ntohsquery & (DNS_AUTH | DNS_REPLY | DNS_NOTIFY))) &&
1706
2018-03-28
pjp
ntohs(question->hdr->qtype) == DNS_TYPE_SOA &&
1707
2018-03-28
pjp
ntohs(question->hdr->qclass) == DNS_CLASS_IN &&
1708
2018-03-28
pjp
question->hdr->namelen == notnp->domainlen &&
1709
2018-03-28
pjp
memcmp(question->hdr->name, notnp->domain, notnp->domainlen) == 0) {
1710
2018-03-28
pjp
1711
2019-06-27
pjp
if (notnp->usetsig && question->tsig.tsigverified != 1) {
1712
2019-06-26
pjp
dolog(LOG_ERR, "tsig'ed notify answer was not validated from \"%s\", errorcode = 0x%02x\n", address, question->tsig.tsigerrorcode);
1713
2019-06-26
pjp
return -1;
1714
2019-06-26
pjp
}
1715
2019-02-26
pjp
1716
2019-06-26
pjp
SLIST_FOREACH_SAFE(md, &notnp->mzone->dest, entries, md2) {
1717
2019-06-26
pjp
1718
2019-06-26
pjp
if (md->notifydest.ss_family != af)
1719
2019-06-26
pjp
continue;
1720
2019-06-26
pjp
1721
2019-06-26
pjp
if (af == AF_INET6) {
1722
2019-06-26
pjp
sin62 = (struct sockaddr_in6 *)&md->notifydest;
1723
2019-06-26
pjp
if (memcmp(&sin6->sin6_addr, &sin62->sin6_addr, 16) == 0 && md->notified == 1) {
1724
2019-06-26
pjp
dolog(LOG_INFO, "notify success! removing address \"%s\" for zone \"%s\" from notify contact list\n", address, question->converted_name);
1725
2019-06-26
pjp
md->notified = 0;
1726
2019-06-26
pjp
}
1727
2019-06-26
pjp
} else {
1728
2019-06-26
pjp
sin2 = (struct sockaddr_in *)&md->notifydest;
1729
2019-06-26
pjp
if (sin->sin_addr.s_addr == sin2->sin_addr.s_addr && md->notified == 1) {
1730
2019-06-26
pjp
dolog(LOG_INFO, "notify success! removing address \"%s\" for zone \"%s\" from notify contact list\n", address, question->converted_name);
1731
2019-06-26
pjp
md->notified = 0;
1732
2019-06-26
pjp
}
1733
2018-03-28
pjp
} /* if af==AF_INET6 */
1734
2018-03-28
pjp
} /* SLIST_FOREACH */
1735
2018-03-28
pjp
}
1736
2018-03-28
pjp
1737
2018-03-28
pjp
return 0;
1738
2014-11-14
pjp
}
repomaster@centroid.eu