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