Added fake resolving of TXT records
authorCarson Reinke <carson@reinke.co>
Sun, 30 Dec 2018 00:03:43 +0000 (19:03 -0500)
committerAndreas Schneider <asn@cryptomilk.org>
Sun, 20 Oct 2019 12:59:54 +0000 (14:59 +0200)
Signed-off-by: Carson Reinke <carson@reinke.co>
Reviewed-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
doc/resolv_wrapper.1.txt
src/resolv_wrapper.c
tests/fake_hosts.in
tests/test_dns_fake.c

index cf6c62b691c0850c33abbbafd5906d61b6e878a5..dcd161d9168f44a348f9509fe70c23384067a820 100644 (file)
@@ -48,6 +48,7 @@ For example:
     CNAME   kerberos.cwrap.org dc.cwrap.org
     SRV     _kerberos._tcp.cwrap.org kerberos.cwrap.org 88
     URI     _vpn.cwrap.org https://vpn.cwrap.org/VPN
+    TXT     cwrap.org v=spf1 mx
 
 *RESOLV_WRAPPER_DEBUGLEVEL*::
 
index 5e9abc2749e4e8a7510ffa194373dde732c094e2..08e30201e8d448eb79946ebea69da8035ad5857f 100644 (file)
@@ -194,6 +194,7 @@ struct rwrap_fake_rr {
                struct rwrap_soa_rrdata soa_rec;
                char cname_rec[MAXDNAME];
                char ptr_rec[MAXDNAME];
+               char txt_rec[MAXDNAME];
        } rrdata;
 
        char key[MAXDNAME];
@@ -329,6 +330,17 @@ static int rwrap_create_fake_uri_rr(const char *key,
        return 0;
 }
 
+static int rwrap_create_fake_txt_rr(const char *key,
+                                   const char *value,
+                                   struct rwrap_fake_rr *rr)
+{
+       memcpy(rr->rrdata.txt_rec, value, strlen(value) + 1);
+
+       memcpy(rr->key, key, strlen(key) + 1);
+       rr->type = ns_t_txt;
+       return 0;
+}
+
 static int rwrap_create_fake_soa_rr(const char *key,
                                    const char *value,
                                    struct rwrap_fake_rr *rr)
@@ -651,6 +663,34 @@ static ssize_t rwrap_fake_uri(struct rwrap_fake_rr *rr,
        return resp_size;
 }
 
+static ssize_t rwrap_fake_txt(struct rwrap_fake_rr *rr,
+                             uint8_t *answer,
+                             size_t anslen)
+{
+       uint8_t *a = answer;
+       ssize_t resp_size;
+       size_t rdata_size;
+       size_t txt_len;
+
+       if (rr->type != ns_t_txt) {
+               RWRAP_LOG(RWRAP_LOG_ERROR, "Wrong type!\n");
+               return -1;
+       }
+       RWRAP_LOG(RWRAP_LOG_TRACE, "Adding TXT RR");
+       txt_len = strlen(rr->rrdata.txt_rec) + 1;
+       rdata_size = txt_len;
+
+       resp_size = rwrap_fake_rdata_common(ns_t_txt, rdata_size,
+                                           rr->key, anslen, &a);
+       if (resp_size < 0) {
+               return -1;
+       }
+
+       memcpy(a, rr->rrdata.txt_rec, txt_len);
+
+       return resp_size;
+}
+
 static ssize_t rwrap_fake_soa(struct rwrap_fake_rr *rr,
                              uint8_t *answer,
                              size_t anslen)
@@ -947,6 +987,11 @@ static int rwrap_get_record(const char *hostfile, unsigned recursion,
                        rc = rwrap_create_fake_ptr_rr(key, value, rr);
                        break;
                }
+               else if (TYPE_MATCH(type, ns_t_txt,
+                                     rec_type, "TXT", key, query)) {
+                       rc = rwrap_create_fake_txt_rr(key, value, rr);
+                       break;
+               }
        }
 
        if (rc == ENOENT && recursion == 0 && key != NULL) {
@@ -998,6 +1043,7 @@ static inline bool rwrap_known_type(int type)
        case ns_t_soa:
        case ns_t_cname:
        case ns_t_ptr:
+       case ns_t_txt:
                return true;
        }
 
@@ -1088,6 +1134,9 @@ static ssize_t rwrap_add_rr(struct rwrap_fake_rr *rr,
        case ns_t_ptr:
                resp_data = rwrap_fake_ptr(rr, answer, anslen);
                break;
+       case ns_t_txt:
+               resp_data = rwrap_fake_txt(rr, answer, anslen);
+               break;
        default:
                return -1;
        }
index 824af57eeaa21fae0d6aa01cb61e46389aa22284..931f004b8480a10c23c182c5adabd3744a9bdc59 100644 (file)
@@ -17,3 +17,4 @@ URI _vpn.cwrap.org https://vpn2.cwrap.org/VPN 2 10
 URI _vpn.cwrap.org https://vpn3.cwrap.org/VPN 2 20
 URI _ftp.cwrap.org ftp://ftp.cwrap.org/public
 PTR 22.0.0.127.in-addr.arpa www.cwrap.org
+TXT cwrap.org v=spf1 mx
index 28ee57a363b782e412ce2af9a6c6264b37a4cf9e..420d32b63d378b0ab9c63cbe48ad07ce4abeaabf 100644 (file)
@@ -714,6 +714,40 @@ static void test_res_fake_ptr_query(void **state)
        assert_string_equal(ptrname, "www.cwrap.org");
 }
 
+static void test_res_fake_txt_query(void **state)
+{
+       int rv;
+       struct __res_state dnsstate;
+       unsigned char answer[ANSIZE];
+       ns_msg handle;
+       ns_rr rr;   /* expanded resource record */
+       const uint8_t *rrdata;
+
+       (void) state; /* unused */
+
+       memset(&dnsstate, 0, sizeof(struct __res_state));
+       rv = res_ninit(&dnsstate);
+       assert_int_equal(rv, 0);
+
+       rv = res_nquery(&dnsstate, "cwrap.org", ns_c_in, ns_t_txt,
+                       answer, sizeof(answer));
+       assert_in_range(rv, 1, 256);
+
+       ns_initparse(answer, sizeof(answer), &handle);
+
+       /*
+        * The query must finish w/o an error, have one answer and the answer
+        * must be a parseable RR of type TXT
+        */
+       assert_int_equal(ns_msg_getflag(handle, ns_f_rcode), ns_r_noerror);
+       assert_int_equal(ns_msg_count(handle, ns_s_an), 1);
+       assert_int_equal(ns_parserr(&handle, ns_s_an, 0, &rr), 0);
+       assert_int_equal(ns_rr_type(rr), ns_t_txt);
+
+       rrdata = ns_rr_rdata(rr);
+       assert_string_equal(rrdata, "v=spf1 mx");
+}
+
 int main(void)
 {
        int rc;
@@ -733,6 +767,7 @@ int main(void)
                cmocka_unit_test(test_res_fake_cname_query),
                cmocka_unit_test(test_res_fake_a_via_cname),
                cmocka_unit_test(test_res_fake_ptr_query),
+               cmocka_unit_test(test_res_fake_txt_query),
        };
 
        rc = cmocka_run_group_tests(fake_tests, NULL, NULL);