1 #include <openssl/opensslconf.h>
5 #include <sys/socket.h>
6 #include <openssl/bio.h>
7 #include <openssl/dso.h>
11 #ifndef OPENSSL_NO_LIBUNBOUND
14 static struct ub_ctx *ctx = NULL;
15 static DSO *unbound_dso = NULL;
18 void *p; struct ub_ctx *(*f)(); }
19 p_ub_ctx_create = {NULL};
22 void *p; int (*f)(struct ub_ctx *,const char *); }
23 p_ub_ctx_resolvconf = {NULL};
26 void *p; int (*f)(struct ub_ctx *,const char *); }
27 p_ub_ctx_add_ta_file = {NULL};
30 void *p; void (*f)(struct ub_ctx *); }
31 p_ub_ctx_delete = {NULL};
34 void *p; int (*f)(struct ub_ctx *,const char *,int,int,struct ub_result**); }
35 p_ub_resolve = {NULL};
38 void *p; void (*f)(struct ub_result*); }
39 p_ub_resolve_free = {NULL};
41 #if defined(__GNUC__) && __GNUC__>=2
42 static void unbound_init(void) __attribute__((constructor));
43 static void unbound_fini(void) __attribute__((destructor));
46 static void unbound_init(void)
50 if ((dso = DSO_load(NULL, "unbound", NULL, 0)) == NULL) return;
52 if ((p_ub_ctx_create.p = DSO_bind_func(dso,"ub_ctx_create")) == NULL ||
53 (p_ub_ctx_resolvconf.p = DSO_bind_func(dso,"ub_ctx_resolvconf")) == NULL ||
54 (p_ub_ctx_add_ta_file.p = DSO_bind_func(dso,"ub_ctx_add_ta_file")) == NULL ||
55 (p_ub_ctx_delete.p = DSO_bind_func(dso,"ub_ctx_delete")) == NULL ||
56 (p_ub_resolve.p = DSO_bind_func(dso,"ub_resolve")) == NULL ||
57 (p_ub_resolve_free.p = DSO_bind_func(dso,"ub_resolve_free")) == NULL ||
58 (ctx = p_ub_ctx_create.f()) == NULL) {
65 /* FIXME: parameterize these through CONF */
66 p_ub_ctx_resolvconf.f(ctx,"/etc/resolv.conf");
67 p_ub_ctx_add_ta_file.f(ctx,"/var/lib/unbound/root.key");
70 static void unbound_fini(void)
72 if (ctx != NULL) p_ub_ctx_delete.f(ctx);
73 if (unbound_dso != NULL) DSO_free(unbound_dso);
78 * Output is array packed as [len][data][len][data][0]
80 unsigned char *SSL_get_tlsa_record_byname (const char *name,int port,int type)
82 unsigned char *ret=NULL;
86 #ifndef OPENSSL_NO_LIBUNBOUND
87 if (ctx == NULL) return NULL;
88 #elif defined(RRSET_VALIDATED)
90 void *p; int (*f)(const char*,unsigned int,unsigned int,unsigned int,struct rrsetinfo **); }
91 p_getrrsetbyname = {NULL};
93 void *p; void (*f)(struct rrsetinfo *); }
96 if (p_getrrsetbyname.p==NULL) {
97 if ((p_getrrsetbyname.p = DSO_global_lookup("getrrsetbyname")) == NULL ||
98 (p_freerrset.p = DSO_global_lookup("freerrset")) == NULL)
99 p_getrrsetbyname.p = (void*)-1;
102 if (p_getrrsetbyname.p == (void *)-1) return NULL;
105 qlen = 7+5+strlen(name)+1;
106 if ((query = OPENSSL_malloc(qlen)) == NULL)
109 BIO_snprintf(query,qlen,"_%u._%s.%s",port&0xffff,type==SOCK_STREAM?"tcp":"udp",name);
111 #ifndef OPENSSL_NO_LIBUNBOUND
113 struct ub_result *tlsa=NULL;
115 if (p_ub_resolve.f(ctx,query,52,1,&tlsa)==0 &&
116 tlsa->havedata && tlsa->data[0]!=NULL) {
117 ret=(void*)-1; /* -1 means insecure */
118 if (tlsa->secure) do {
120 unsigned int dlen, i;
122 for (dlen=0, i=0; tlsa->data[i]; i++)
123 dlen += sizeof(int)+(unsigned int)tlsa->len[i];
126 if ((ret = OPENSSL_malloc(dlen)) == NULL) break;
128 for (data=ret, i=0; tlsa->data[i]; i++) {
129 *(unsigned int *)data = dlen = (unsigned int)tlsa->len[i];
130 data += sizeof(unsigned int);
131 memcpy(data,tlsa->data[i],dlen);
134 *(unsigned int *)data = 0; /* trailing zero */
136 p_ub_resolve_free.f(tlsa);
139 #elif defined(RRSET_VALIDATED)
141 struct rrsetinfo *rrset=NULL;
143 if (p_getrrsetbyname.f(query,1,52,RRSET_VALIDATED,&rrset) == 0 && rrset->rri_nrdatas) {
144 ret=(void*)-1; /* -1 means insecure */
145 if ((rrset->rri_flags&RRSET_VALIDATED)) do {
147 unsigned int dlen, i;
149 for (dlen=0, i=0; i<rrset->rri_nrdatas; i++)
150 dlen += sizeof(int)+rrset->rri_rdatas[i].rdi_length;
153 if ((ret = OPENSSL_malloc(sizeof(int)+dlen)) == NULL) break;
155 for (data=ret, i=0; i<rrset->rri_rdatas[i].rdi_length; i++) {
156 *(unsigned int *)data = dlen = rrset->rri_rdatas[i].rdi_length;
157 data += sizeof(unsigned int);
158 memcpy(data,rrset->rri_rdatas[i].rdi_data,dlen);
161 *(unsigned int *)data = 0; /* trailing zero */
163 p_freerrset.f(rrset);
166 #elif defined(_WIN32_NOT_YET)
170 DnsQuery_A(query,52,DNS_QUERY_STANDARD,NULL,&rrset,NULL);
171 DnsRecordListFree(rrset,DnsFreeRecordList);