1 #ifndef DNSCRYPT_H
2 #define DNSCRYPT_H
3 
4 #include "compat.h"
5 #include "tree.h"
6 #include "debug.h"
7 #include <event2/event.h>
8 #include <event2/listener.h>
9 #include <event2/bufferevent.h>
10 #include <event2/buffer.h>
11 #include <event2/util.h>
12 #include <sodium.h>
13 
14 #if SODIUM_LIBRARY_VERSION_MAJOR < 7
15 # define sodium_allocarray(C, S) calloc(C, S)
16 # define sodium_malloc(S) malloc(S)
17 # define sodium_free(P) free(P)
18 #endif
19 
20 #define DNS_QUERY_TIMEOUT 10
21 
22 #define DNS_MAX_PACKET_SIZE_UDP_RECV (65536U - 20U - 8U)
23 #define DNS_MAX_PACKET_SIZE_UDP_SEND 512U
24 
25 #if DNS_MAX_PACKET_SIZE_UDP_RECV > DNS_MAX_PACKET_SIZE_UDP_SEND
26 # define DNS_MAX_PACKET_SIZE_UDP DNS_MAX_PACKET_SIZE_UDP_RECV
27 #else
28 # define DNS_MAX_PACKET_SIZE_UDP DNS_MAX_PACKET_SIZE_UDP_SEND
29 #endif
30 
31 #ifndef DNS_DEFAULT_STANDARD_DNS_PORT
32 # define DNS_DEFAULT_STANDARD_DNS_PORT "53"
33 #endif
34 #ifndef DNS_DEFAULT_LOCAL_PORT
35 # define DNS_DEFAULT_LOCAL_PORT DNS_DEFAULT_STANDARD_DNS_PORT
36 #endif
37 #ifndef DNS_DEFAULT_RESOLVER_PORT
38 # define DNS_DEFAULT_RESOLVER_PORT "443"
39 #endif
40 
41 #define DNS_HEADER_SIZE  12U
42 #define DNS_FLAGS_TC      2U
43 #define DNS_FLAGS_QR    128U
44 #define DNS_FLAGS2_RA   128U
45 
46 #define DNS_CLASS_IN      1U
47 #define DNS_TYPE_TXT     16U
48 #define DNS_TYPE_OPT     41U
49 
50 #define DNS_OFFSET_QUESTION DNS_HEADER_SIZE
51 #define DNS_OFFSET_FLAGS    2U
52 #define DNS_OFFSET_FLAGS2   3U
53 #define DNS_OFFSET_QDCOUNT  4U
54 #define DNS_OFFSET_ANCOUNT  6U
55 #define DNS_OFFSET_NSCOUNT  8U
56 #define DNS_OFFSET_ARCOUNT 10U
57 
58 #define DNS_OFFSET_EDNS_TYPE         0U
59 #define DNS_OFFSET_EDNS_PAYLOAD_SIZE 2U
60 
61 #define DNS_DEFAULT_EDNS_PAYLOAD_SIZE 1252U
62 
63 #define DNSCRYPT_MAGIC_HEADER_LEN 8U
64 #define DNSCRYPT_MAGIC_RESPONSE  "r6fnvWj8"
65 
66 #ifndef DNSCRYPT_MAX_PADDING
67 # define DNSCRYPT_MAX_PADDING 256U
68 #endif
69 #ifndef DNSCRYPT_BLOCK_SIZE
70 # define DNSCRYPT_BLOCK_SIZE 64U
71 #endif
72 #ifndef DNSCRYPT_MIN_PAD_LEN
73 # define DNSCRYPT_MIN_PAD_LEN 8U
74 #endif
75 
76 #define crypto_box_HALF_NONCEBYTES (crypto_box_NONCEBYTES / 2U)
77 
78 #include "edns.h"
79 #include "udp_request.h"
80 #include "tcp_request.h"
81 #include "rfc1035.h"
82 #include "logger.h"
83 #include "safe_rw.h"
84 #include "cert.h"
85 
86 #define DNSCRYPT_QUERY_HEADER_SIZE \
87     (DNSCRYPT_MAGIC_HEADER_LEN + crypto_box_PUBLICKEYBYTES + crypto_box_HALF_NONCEBYTES + crypto_box_MACBYTES)
88 #define DNSCRYPT_RESPONSE_HEADER_SIZE \
89     (DNSCRYPT_MAGIC_HEADER_LEN + crypto_box_NONCEBYTES + crypto_box_MACBYTES)
90 
91 #define DNSCRYPT_REPLY_HEADER_SIZE \
92     (DNSCRYPT_MAGIC_HEADER_LEN + crypto_box_HALF_NONCEBYTES * 2 + crypto_box_MACBYTES)
93 
94 #define XSALSA20_CERT(cert) (cert->es_version[0] == 0 && \
95     cert->es_version[1] == 1)
96 #define XCHACHA20_CERT(cert) (cert->es_version[0] == 0 && \
97     cert->es_version[1] == 2)
98 
99 typedef struct KeyPair_ {
100     uint8_t crypt_publickey[crypto_box_PUBLICKEYBYTES];
101     uint8_t crypt_secretkey[crypto_box_SECRETKEYBYTES];
102 } KeyPair;
103 
104 typedef struct cert_ {
105     uint8_t magic_query[DNSCRYPT_MAGIC_HEADER_LEN];
106     uint8_t es_version[2];
107     KeyPair *keypair;
108 } dnsccert;
109 
110 struct context {
111     struct sockaddr_storage local_sockaddr;
112     struct sockaddr_storage resolver_sockaddr;
113     struct sockaddr_storage outgoing_sockaddr;
114     ev_socklen_t local_sockaddr_len;
115     ev_socklen_t resolver_sockaddr_len;
116     ev_socklen_t outgoing_sockaddr_len;
117     const char *ext_address;
118     const char *resolver_address;
119     const char *listen_address;
120     const char *outgoing_address;
121     struct evconnlistener *tcp_conn_listener;
122     struct event *tcp_accept_timer;
123     struct event *udp_listener_event;
124     struct event *udp_resolver_event;
125     evutil_socket_t udp_listener_handle;
126     evutil_socket_t udp_resolver_handle;
127     TCPRequestQueue tcp_request_queue;
128     UDPRequestQueue udp_request_queue;
129     struct event_base *event_loop;
130     unsigned int connections;
131     size_t edns_payload_size;
132 
133     /* Domain name shared buffer. */
134     char namebuff[MAXDNAME];
135 
136     /* Process stuff. */
137     bool daemonize;
138     bool allow_not_dnscrypted;
139     char *pidfile;
140     char *user;
141     uid_t user_id;
142     gid_t user_group;
143     char *user_dir;
144     char *logfile;
145     char *provider_name;
146     char *provider_publickey_file;
147     char *provider_secretkey_file;
148     char *provider_cert_file;
149     struct SignedCert *signed_certs;
150     size_t signed_certs_count;
151     dnsccert *certs;
152     size_t certs_count;
153     uint8_t provider_publickey[crypto_sign_ed25519_PUBLICKEYBYTES];
154     uint8_t provider_secretkey[crypto_sign_ed25519_SECRETKEYBYTES];
155     char *crypt_secretkey_file;
156     KeyPair *keypairs;
157     size_t keypairs_count;
158     uint64_t nonce_ts_last;
159     unsigned char hash_key[crypto_shorthash_KEYBYTES];
160 
161     /* blocking */
162     struct Blocking_ *blocking;
163 };
164 
165 const dnsccert * find_cert(const struct context *c,
166                            const unsigned char magic_query[DNSCRYPT_MAGIC_HEADER_LEN],
167                            const size_t dns_query_len);
168 int dnscrypt_cmp_client_nonce(const uint8_t
169                               client_nonce[crypto_box_HALF_NONCEBYTES],
170                               const uint8_t *const buf, const size_t len);
171 void dnscrypt_memzero(void *const pnt, const size_t size);
172 uint64_t dnscrypt_hrtime(void);
173 void dnscrypt_key_to_fingerprint(char fingerprint[80U],
174                                  const uint8_t *const key);
175 int dnscrypt_fingerprint_to_key(const char *const fingerprint,
176                                 uint8_t key[crypto_box_PUBLICKEYBYTES]);
177 
178 // vim-like binary display
179 static inline void
print_binary_string(uint8_t * s,size_t count)180 print_binary_string(uint8_t *s, size_t count)
181 {
182     for (size_t i = 1; i <= count; i++) {
183         uint8_t x = *((uint8_t *)s + i - 1);
184         if (x >= (uint8_t)'0' && x <= (uint8_t)'9') {
185             printf("%d", x);
186         } else if (x >= (uint8_t)'a' && x <= (uint8_t)'z') {
187             printf("%c", x);
188         } else if (x >= (uint8_t)'A' && x <= (uint8_t)'Z') {
189             printf("%c", x);
190         } else {
191             printf("\\%03d", x);
192         }
193         if (i % 16 == 0) {
194             printf("\n");
195         }
196     }
197     printf("\n");
198 }
199 
200 // binary in hex
201 static inline void
print_binary_string_hex(uint8_t * s,size_t count)202 print_binary_string_hex(uint8_t *s, size_t count)
203 {
204     for (size_t i = 1; i <= count; i++) {
205         if ((i - 1) % 16 == 0) {
206             printf("%04zx: ", (i - 1));
207         }
208         uint8_t x = *((uint8_t *)s + i - 1);
209         printf("%02x ", x);
210         if (i % 16 == 0) {
211             printf("\n");
212         }
213     }
214     printf("\n");
215 }
216 
217 struct dnscrypt_query_header {
218     uint8_t magic_query[DNSCRYPT_MAGIC_HEADER_LEN];
219     uint8_t publickey[crypto_box_PUBLICKEYBYTES];
220     uint8_t nonce[crypto_box_HALF_NONCEBYTES];
221     uint8_t mac[crypto_box_MACBYTES];
222 };
223 
224 int dnscrypt_server_uncurve(struct context *c, const dnsccert *cert,
225                             uint8_t client_nonce[crypto_box_HALF_NONCEBYTES],
226                             uint8_t nmkey[crypto_box_BEFORENMBYTES],
227                             uint8_t *const buf, size_t * const lenp);
228 int dnscrypt_server_curve(struct context *c, const dnsccert *cert,
229                           uint8_t client_nonce[crypto_box_HALF_NONCEBYTES],
230                           uint8_t nmkey[crypto_box_BEFORENMBYTES],
231                           uint8_t *const buf, size_t * const lenp,
232                           const size_t max_len);
233 /**
234  * Given a DNS request,iterate over the question sections.
235  * If a TXT request for provider name is made, adds the certs as TXT records
236  * and return 0. dns_query_len is updated to reflect the size of the DNS packet.
237  * return non-zero in case of failure.
238  * */
239 int dnscrypt_self_serve_cert_file(struct context *c,
240                                   struct dns_header *header,
241                                   size_t *dns_query_len, size_t max_len);
242 
243 #endif
244