Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDanny Sonnenschein <my.card.god@web.de>2020-10-02 18:52:47 +0300
committerAntoine du Hamel <duhamelantoine1995@gmail.com>2020-10-16 11:21:32 +0300
commit6f34498148612e8aa3537a9c865d2940cb9e8c7a (patch)
tree1f93a3db3eada776a79f58741a4d831f8d002376 /src/cares_wrap.cc
parentcfbbeea4a1de41f026b6459d7a680a367addbbb0 (diff)
net: add support for resolving DNS CAA records
This adds support for DNS Certification Authority Authorization (RFC 8659) to Node.js. PR-URL: https://github.com/nodejs/node/pull/35466 Fixes: https://github.com/nodejs/node/issues/19239 Refs: https://github.com/nodejs/node/issues/14713 Reviewed-By: Anna Henningsen <anna@addaleax.net>
Diffstat (limited to 'src/cares_wrap.cc')
-rw-r--r--src/cares_wrap.cc79
1 files changed, 79 insertions, 0 deletions
diff --git a/src/cares_wrap.cc b/src/cares_wrap.cc
index cc7ad316d2b..fcffc2bec67 100644
--- a/src/cares_wrap.cc
+++ b/src/cares_wrap.cc
@@ -50,6 +50,10 @@
# include <arpa/nameser.h>
#endif
+#ifndef T_CAA
+# define T_CAA 257 /* Certification Authority Authorization */
+#endif
+
#if defined(__OpenBSD__)
# define AI_V4MAPPED 0
#endif
@@ -882,6 +886,43 @@ int ParseMxReply(Environment* env,
return ARES_SUCCESS;
}
+int ParseCaaReply(Environment* env,
+ const unsigned char* buf,
+ int len,
+ Local<Array> ret,
+ bool need_type = false) {
+ HandleScope handle_scope(env->isolate());
+ auto context = env->context();
+
+ struct ares_caa_reply* caa_start;
+ int status = ares_parse_caa_reply(buf, len, &caa_start);
+ if (status != ARES_SUCCESS) {
+ return status;
+ }
+
+ uint32_t offset = ret->Length();
+ ares_caa_reply* current = caa_start;
+ for (uint32_t i = 0; current != nullptr; ++i, current = current->next) {
+ Local<Object> caa_record = Object::New(env->isolate());
+
+ caa_record->Set(context,
+ env->dns_critical_string(),
+ Integer::New(env->isolate(), current->critical)).Check();
+ caa_record->Set(context,
+ OneByteString(env->isolate(), current->property),
+ OneByteString(env->isolate(), current->value)).Check();
+ if (need_type)
+ caa_record->Set(context,
+ env->type_string(),
+ env->dns_caa_string()).Check();
+
+ ret->Set(context, i + offset, caa_record).Check();
+ }
+
+ ares_free_data(caa_start);
+ return ARES_SUCCESS;
+}
+
int ParseTxtReply(Environment* env,
const unsigned char* buf,
int len,
@@ -1345,6 +1386,13 @@ class QueryAnyWrap: public QueryWrap {
if (!soa_record.IsEmpty())
ret->Set(context, ret->Length(), soa_record).Check();
+ /* Parse CAA records */
+ status = ParseCaaReply(env(), buf, len, ret, true);
+ if (status != ARES_SUCCESS && status != ARES_ENODATA) {
+ ParseError(status);
+ return;
+ }
+
CallOnComplete(ret);
}
};
@@ -1441,6 +1489,36 @@ class QueryAaaaWrap: public QueryWrap {
}
};
+class QueryCaaWrap: public QueryWrap {
+ public:
+ QueryCaaWrap(ChannelWrap* channel, Local<Object> req_wrap_obj)
+ : QueryWrap(channel, req_wrap_obj, "resolve6") {
+ }
+
+ int Send(const char* name) override {
+ AresQuery(name, ns_c_in, T_CAA);
+ return 0;
+ }
+
+ SET_NO_MEMORY_INFO()
+ SET_MEMORY_INFO_NAME(QueryAaaaWrap)
+ SET_SELF_SIZE(QueryAaaaWrap)
+
+ protected:
+ void Parse(unsigned char* buf, int len) override {
+ HandleScope handle_scope(env()->isolate());
+ Context::Scope context_scope(env()->context());
+
+ Local<Array> ret = Array::New(env()->isolate());
+ int status = ParseCaaReply(env(), buf, len, ret);
+ if (status != ARES_SUCCESS) {
+ ParseError(status);
+ return;
+ }
+
+ this->CallOnComplete(ret);
+ }
+};
class QueryCnameWrap: public QueryWrap {
public:
@@ -2238,6 +2316,7 @@ void Initialize(Local<Object> target,
env->SetProtoMethod(channel_wrap, "queryAny", Query<QueryAnyWrap>);
env->SetProtoMethod(channel_wrap, "queryA", Query<QueryAWrap>);
env->SetProtoMethod(channel_wrap, "queryAaaa", Query<QueryAaaaWrap>);
+ env->SetProtoMethod(channel_wrap, "queryCaa", Query<QueryCaaWrap>);
env->SetProtoMethod(channel_wrap, "queryCname", Query<QueryCnameWrap>);
env->SetProtoMethod(channel_wrap, "queryMx", Query<QueryMxWrap>);
env->SetProtoMethod(channel_wrap, "queryNs", Query<QueryNsWrap>);