Navigation Menu

Skip to content

Commit

Permalink
Add client support for multiple domain names.
Browse files Browse the repository at this point in the history
For fun, support multiple domain names:

    sdt sshdns.a.example.com sshdns.b.example.com \
        sshdns.a.example1.com sshdns.b.example1.com

Update server to check a list of domain names. The server checks domain
names to prevent responding to random queries/scans. This can be disabled
by using the keyword "any" as a domain name, i.e.:

    sods any
  • Loading branch information
msantos committed Jan 4, 2010
1 parent 6508a9d commit 7284634
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 18 deletions.
26 changes: 22 additions & 4 deletions sdt/sdt.c
Expand Up @@ -40,6 +40,7 @@ main(int argc, char *argv[])
pid_t pid = 0;
int nd = 0;
int ch = 0;
int di = 0;

IS_NULL(ss = (SDT_STATE *)calloc(1, sizeof(SDT_STATE)));

Expand All @@ -57,7 +58,9 @@ main(int argc, char *argv[])
ss->type = ns_t_txt;
ss->verbose_lines = 100;

while ( (ch = getopt(argc, argv, "A:B:b:dF:hM:m:R:r:S:s:T:t:vx:")) != -1) {
ss->dname_next = &sdt_dns_dn_roundrobin;

while ( (ch = getopt(argc, argv, "A:B:b:dF:hM:m:n:R:r:S:s:T:t:vx:")) != -1) {
switch (ch) {
case 'A': /* alarm, delay buf */
ss->delay = (u_int32_t)atoi(optarg);
Expand All @@ -80,6 +83,14 @@ main(int argc, char *argv[])
case 'm':
ss->sleep = (u_int32_t)atoi(optarg);
break;
case 'n': /* strategy for shuffling domain name list */
if (strcasecmp(optarg, "roundrobin") == 0)
ss->dname_next = &sdt_dns_dn_roundrobin;
else if (strcasecmp(optarg, "random") == 0)
ss->dname_next = &sdt_dns_dn_random;
else
usage(ss);
break;
case 'R': /* Retry lookup */
sdt_dns_setopt(SDT_RES_RETRY, (u_int32_t)atoi(optarg));
break;
Expand Down Expand Up @@ -129,10 +140,16 @@ main(int argc, char *argv[])
argc -= optind;
argv += optind;

if ( (argc != 1) || (strlen(argv[0]) > NS_MAXCDNAME - 1))
if ( (argc == 0) || (argc >= MAXDNAMELIST))
usage(ss);

IS_NULL(ss->dname = strdup(argv[0]));
ss->dname_max = argc;
IS_NULL(ss->dname = (char **)calloc(argc, 1));
for ( di = 0; di < argc; di++) {
if (strlen(argv[di]) > NS_MAXCDNAME - 1)
usage(ss);
IS_NULL(ss->dname[di] = strdup(argv[di]));
}

IS_ERR(nd = open("/dev/null", O_RDWR, 0));

Expand Down Expand Up @@ -390,8 +407,9 @@ usage(SDT_STATE *ss)
(void)fprintf(stderr, "-F <num>\tFast start, number of small packets to pass w/out buffering (0 to disable) [default: %d]\n", ss->faststart);
(void)fprintf(stderr, "-M\tMaximum number of polling query failures [default: %d]\n", ss->maxpollfail);
(void)fprintf(stderr, "-m\tMinimum time to sleep between nameserver queries [default: %d us]\n", ss->sleep);
(void)fprintf(stderr, "-n <roundrobin|random>\tStrategy for shuffling domain names [default: roundrobin]\n");
(void)fprintf(stderr, "-R <number>\tNumber of retries for lookup\n");
(void)fprintf(stderr, "-r\tNameserver (or keyword: random, opendns, verizon, speakeasy)\n");
(void)fprintf(stderr, "-r\tNameserver (or keyword: random, opendns, verizon, speakeasy, google)\n");
(void)fprintf(stderr, "-S [rotate|blast]\tResolver strategy\n");
(void)fprintf(stderr, "-T <number>\tUse TCP [0 = new connection for each request, 1 = pipeline requests]\n");
(void)fprintf(stderr, "-t <DNS type>\tTXT, CNAME [Default = TXT]\n");
Expand Down
17 changes: 13 additions & 4 deletions sdt/sdt.h
Expand Up @@ -98,6 +98,8 @@
#define MAXBACKOFF 3000 /* 3000 * 20000 = 60,000,000 (1/minute) */
#define MAXPOLLFAIL 10 /* Number of TXT record failures before giving up */

#define MAXDNAMELIST 256 /* arbitrary cutoff for number of domains */


typedef union _SDT_ID {
struct {
Expand All @@ -109,7 +111,9 @@ typedef union _SDT_ID {
} SDT_ID;

typedef struct _SDT_STATE {
char *dname;
char **dname;
int dname_max;
int dname_iterator;
SDT_ID sess;
size_t sum;
size_t sum_up;
Expand All @@ -125,6 +129,8 @@ typedef struct _SDT_STATE {
pid_t child;
int verbose;
int verbose_lines;

char *(*dname_next)(void *state);
} SDT_STATE;

/* Resolver options */
Expand All @@ -151,10 +157,13 @@ int sdt_dns_parsens(SDT_STATE *ss, char *buf);
int sdt_dns_A(SDT_STATE *ss, char *buf, ssize_t n);
char *sdt_dns_poll(SDT_STATE *ss, size_t *len);
char *sdt_dns_parse(SDT_STATE *ss, char *pkt, int *pktlen);
char * sdt_dns_dec_CNAME(SDT_STATE *ss, u_char *data, u_int16_t *n);
char * sdt_dns_dec_TXT(SDT_STATE *ss, u_char *data, u_int16_t *n);
char * sdt_dns_dec_NULL(SDT_STATE *ss, u_char *data, u_int16_t *n);
char *sdt_dns_dec_CNAME(SDT_STATE *ss, u_char *data, u_int16_t *n);
char *sdt_dns_dec_TXT(SDT_STATE *ss, u_char *data, u_int16_t *n);
char *sdt_dns_dec_NULL(SDT_STATE *ss, u_char *data, u_int16_t *n);
void sdt_dns_print_servers(SDT_STATE *ss);
char *sdt_dns_dn_roundrobin(void *state);
char *sdt_dns_dn_random(void *state);


void sdt_rand_init(void);
#ifndef HAVE_ARC4RANDOM
Expand Down
22 changes: 20 additions & 2 deletions sdt/sdt_dns.c
Expand Up @@ -136,7 +136,7 @@ sdt_dns_A(SDT_STATE *ss, char *buf, ssize_t n)
* $temp_payload.$nonce-$sum_up.id-$id.up.$extension
*/
(void)snprintf(query, sizeof(query), "%s.%u-%u.id-%u.up.%s",
dn, nonce, (u_int32_t)ss->sum_up, htonl(ss->sess.id), ss->dname);
dn, nonce, (u_int32_t)ss->sum_up, htonl(ss->sess.id), ss->dname_next(ss));

VERBOSE(2, "A:%s\n", query);
if (res_search(query, ns_c_in, ns_t_a, (u_char *)&pkt, sizeof(pkt)) < 0) {
Expand Down Expand Up @@ -166,7 +166,7 @@ sdt_dns_poll(SDT_STATE *ss, size_t *len)
* $sum-$nonce.id-$id.down.$extension
*/
(void)snprintf(query, sizeof(query), "%u-%u.id-%u.down.%s",
(u_int32_t)ss->sum, nonce, htonl(ss->sess.id), ss->dname);
(u_int32_t)ss->sum, nonce, htonl(ss->sess.id), ss->dname_next(ss));

VERBOSE(2, "POLL:%s\n", query);

Expand Down Expand Up @@ -415,3 +415,21 @@ sdt_dns_print_servers(SDT_STATE *ss)
}
}


/* Strategies for iterating through multiple
* domain names */
char *
sdt_dns_dn_roundrobin(void *state)
{
SDT_STATE *ss = state;
return (ss->dname[ss->dname_iterator++ % ss->dname_max]);
}

char *
sdt_dns_dn_random(void *state)
{
SDT_STATE *ss = state;
return (ss->dname[sdt_rand() % ss->dname_max]);
}


11 changes: 9 additions & 2 deletions sods/sods.c
Expand Up @@ -39,6 +39,7 @@ main (int argc, char *argv[])
SDS_STATE *ss = NULL;

int ch = 0;
int di = 0;

IS_NULL(ss = (SDS_STATE *)calloc(1, sizeof(SDS_STATE)));

Expand Down Expand Up @@ -102,10 +103,16 @@ main (int argc, char *argv[])
argc -= optind;
argv += optind;

if ( (argc != 1) || (strlen(argv[0]) > NS_MAXDNAME - 1))
if ( (argc == 0) || (argc >= MAXDNAMELIST))
usage(ss);

IS_NULL(ss->dn = strdup(argv[0]));
ss->dn_max = argc;
IS_NULL(ss->dn = (char **)calloc(argc, 1));
for ( di = 0; di < argc; di++) {
if (strlen(argv[di]) > NS_MAXCDNAME - 1)
usage(ss);
IS_NULL(ss->dn[di] = strdup(argv[di]));
}

if (ss->fwd == NULL)
(void)sds_parse_forward(ss, "127.0.0.1:22");
Expand Down
6 changes: 4 additions & 2 deletions sods/sods.h
Expand Up @@ -80,7 +80,8 @@
#define BUFLEN 110
#define NS_TXTREC 65535 /* see http://www.zeroconf.org/Rendezvous/txtrecords.html */

#define MAXFWDS 32 /* Maximum number of allowed forwarders */
#define MAXFWDS 32 /* Maximum number of allowed forwarders */
#define MAXDNAMELIST 256 /* Maximum number of domain names */

typedef struct _SDS_FWD {
u_int8_t sess; /* Unused */
Expand All @@ -89,7 +90,8 @@ typedef struct _SDS_FWD {

typedef struct _SDS_STATE {
int s;
char *dn;
char **dn;
int dn_max;
char *func; /* sshdns, socket ... */
SDS_FWD *fwd;
size_t fwds; /* number of forwarded sessions */
Expand Down
13 changes: 9 additions & 4 deletions sods/sods_dns.c
Expand Up @@ -408,6 +408,7 @@ sds_dns_packet(SDS_PKT *pkt, void *data, size_t len)
sds_dns_checkdn(SDS_STATE *ss, char *domain)
{
char *p = NULL;
int i = 0;

p = strchr(domain, '.');
*p++ = '\0';
Expand All @@ -417,11 +418,15 @@ sds_dns_checkdn(SDS_STATE *ss, char *domain)
return (-1);
#endif

if (strncmp(ss->dn, p, strlen(ss->dn)+1) != 0) {
VERBOSE(1, "rejecting request for domain: %s\n", p);
return (-1);
if (strcmp(ss->dn[0], "any") == 0)
return (0);

for ( i = 0; i < ss->dn_max; i++) {
if (strncmp(ss->dn[i], p, strlen(ss->dn[i])+1) == 0)
return (0);
}

return (0);
VERBOSE(1, "rejecting request for domain: %s\n", p);
return (-1);
}

0 comments on commit 7284634

Please sign in to comment.