소스 검색

dns_server: fix DOH Get issue.

Nick Peng 1 년 전
부모
커밋
53f57b74ea
3개의 변경된 파일39개의 추가작업 그리고 8개의 파일을 삭제
  1. 21 2
      src/dns_server.c
  2. 17 5
      src/util.c
  3. 1 1
      src/util.h

+ 21 - 2
src/dns_server.c

@@ -7759,6 +7759,7 @@ static int _dns_server_tcp_process_one_request(struct dns_server_conn_tcp_client
 	int len = 0;
 	struct http_head *http_head = NULL;
 	uint8_t *http_decode_data = NULL;
+	char *base64_query = NULL;
 
 	/* Handling multiple requests */
 	for (;;) {
@@ -7806,12 +7807,26 @@ static int _dns_server_tcp_process_one_request(struct dns_server_conn_tcp_client
 					goto errout;
 				}
 
-				const char *base64_query = http_head_get_params_value(http_head, "dns");
-				if (base64_query == NULL) {
+				const char *dns_query = http_head_get_params_value(http_head, "dns");
+				if (dns_query == NULL) {
 					tlog(TLOG_DEBUG, "query is null.");
 					goto errout;
 				}
 
+				if (base64_query == NULL) {
+					base64_query = malloc(DNS_IN_PACKSIZE);
+					if (base64_query == NULL) {
+						tlog(TLOG_DEBUG, "malloc failed.");
+						goto errout;
+					}
+				}
+
+				if (urldecode(base64_query, DNS_IN_PACKSIZE, dns_query) < 0) {
+					tlog(TLOG_DEBUG, "urldecode query failed.");
+					goto errout;
+				}
+
+
 				if (http_decode_data == NULL) {
 					http_decode_data = malloc(DNS_IN_PACKSIZE);
 					if (http_decode_data == NULL) {
@@ -7887,6 +7902,10 @@ errout:
 		free(http_decode_data);
 	}
 
+	if (base64_query) {
+		free(base64_query);
+	}
+
 	if ((ret == RECV_ERROR_FAIL || ret == RECV_ERROR_INVALID_PACKET) &&
 		tcpclient->head.type == DNS_CONN_TYPE_HTTPS_CLIENT) {
 		_dns_server_reply_http_error(tcpclient, 400, "Bad Request", "Bad Request");

+ 17 - 5
src/util.c

@@ -336,14 +336,14 @@ int getsocket_inet(int fd, struct sockaddr *addr, socklen_t *addr_len)
 	switch (addr_store.ss_family) {
 	case AF_INET: {
 		struct sockaddr_in *addr_in = NULL;
-		addr_in = (struct sockaddr_in *)addr;
+		addr_in = (struct sockaddr_in *)&addr_store;
 		addr_in->sin_family = AF_INET;
 		*addr_len = sizeof(struct sockaddr_in);
 		memcpy(addr, addr_in, sizeof(struct sockaddr_in));
 	} break;
 	case AF_INET6: {
 		struct sockaddr_in6 *addr_in6 = NULL;
-		addr_in6 = (struct sockaddr_in6 *)addr;
+		addr_in6 = (struct sockaddr_in6 *)&addr_store;
 		if (IN6_IS_ADDR_V4MAPPED(&addr_in6->sin6_addr)) {
 			struct sockaddr_in addr_in4;
 			memset(&addr_in4, 0, sizeof(addr_in4));
@@ -552,9 +552,10 @@ int parse_uri(const char *value, char *scheme, char *host, int *port, char *path
 	return parse_uri_ext(value, scheme, NULL, NULL, host, port, path);
 }
 
-void urldecode(char *dst, const char *src)
+int urldecode(char *dst, int dst_maxlen, const char *src)
 {
 	char a, b;
+	int len = 0;
 	while (*src) {
 		if ((*src == '%') && ((a = src[1]) && (b = src[2])) && (isxdigit(a) && isxdigit(b))) {
 			if (a >= 'a') {
@@ -584,8 +585,15 @@ void urldecode(char *dst, const char *src)
 		} else {
 			*dst++ = *src++;
 		}
+
+		len++;
+		if (len >= dst_maxlen - 1) {
+			return -1;
+		}
 	}
 	*dst++ = '\0';
+
+	return len;
 }
 
 int parse_uri_ext(const char *value, char *scheme, char *user, char *password, char *host, int *port, char *path)
@@ -635,11 +643,15 @@ int parse_uri_ext(const char *value, char *scheme, char *user, char *password, c
 			*sep = '\0';
 			sep = sep + 1;
 			if (password) {
-				urldecode(password, sep);
+				if (urldecode(password, 128, sep) < 0) {
+					return -1;
+				}
 			}
 		}
 		if (user) {
-			urldecode(user, user_password);
+			if (urldecode(user, 128, user_password) < 0) {
+				return -1;
+			}
 		}
 	} else {
 		host_part = user_pass_host_part;

+ 1 - 1
src/util.h

@@ -88,7 +88,7 @@ int parse_uri(const char *value, char *scheme, char *host, int *port, char *path
 
 int parse_uri_ext(const char *value, char *scheme, char *user, char *password, char *host, int *port, char *path);
 
-void urldecode(char *dst, const char *src);
+int urldecode(char *dst, int dst_maxlen, const char *src);
 
 int set_fd_nonblock(int fd, int nonblock);