Forráskód Böngészése

DOH: fix DOH Get query issue.

Nick Peng 1 éve
szülő
commit
cb5c9b82a9
3 módosított fájl, 60 hozzáadás és 7 törlés
  1. 1 1
      src/dns_server.c
  2. 57 6
      src/util.c
  3. 2 0
      src/util.h

+ 1 - 1
src/dns_server.c

@@ -7835,7 +7835,7 @@ static int _dns_server_tcp_process_one_request(struct dns_server_conn_tcp_client
 					}
 				}
 
-				int decode_len = SSL_base64_decode(base64_query, http_decode_data, DNS_IN_PACKSIZE);
+				int decode_len = SSL_base64_decode_ext(base64_query, http_decode_data, DNS_IN_PACKSIZE, 1, 1);
 				if (decode_len <= 0) {
 					tlog(TLOG_DEBUG, "decode query failed.");
 					goto errout;

+ 57 - 6
src/util.c

@@ -988,20 +988,55 @@ unsigned char *SSL_SHA256(const unsigned char *d, size_t n, unsigned char *md)
 	return (md);
 }
 
-int SSL_base64_decode(const char *in, unsigned char *out, int max_outlen)
+int SSL_base64_decode_ext(const char *in, unsigned char *out, int max_outlen, int url_safe, int auto_padding)
 {
 	size_t inlen = strlen(in);
+	char *in_padding_data = NULL;
+	int padding_len = 0;
+	const char *in_data = in;
 	int outlen = 0;
 
-	if (max_outlen < (int)inlen / 4 * 3) {
-		goto errout;
-	}
-
 	if (inlen == 0) {
 		return 0;
 	}
 
-	outlen = EVP_DecodeBlock(out, (unsigned char *)in, inlen);
+	if ((auto_padding == 1 && inlen % 4 != 0) || url_safe == 1) {
+		padding_len = 4 - inlen % 4;
+		in_padding_data = (char *)malloc(inlen + padding_len + 1);
+		if (in_padding_data == NULL) {
+			goto errout;
+		}
+
+		if (url_safe) {
+			for (size_t i = 0; i < inlen; i++) {
+				if (in[i] == '-') {
+					in_padding_data[i] = '+';
+				} else if (in[i] == '_') {
+					in_padding_data[i] = '/';
+				} else {
+					in_padding_data[i] = in[i];
+				}
+			}
+		} else {
+			memcpy(in_padding_data, in, inlen);
+		}
+
+		if (auto_padding) {
+			memset(in_padding_data + inlen, '=', padding_len);
+		} else {
+			padding_len = 0;
+		}
+
+		in_padding_data[inlen + padding_len] = '\0';
+		in_data = in_padding_data;
+		inlen += padding_len;
+	}
+
+	if (max_outlen < (int)inlen / 4 * 3) {
+		goto errout;
+	}
+
+	outlen = EVP_DecodeBlock(out, (unsigned char *)in_data, inlen);
 	if (outlen < 0) {
 		goto errout;
 	}
@@ -1011,11 +1046,27 @@ int SSL_base64_decode(const char *in, unsigned char *out, int max_outlen)
 		--outlen;
 	}
 
+	if (in_padding_data) {
+		free(in_padding_data);
+	}
+
+	outlen -= padding_len;
+
 	return outlen;
 errout:
+
+	if (in_padding_data) {
+		free(in_padding_data);
+	}
+
 	return -1;
 }
 
+int SSL_base64_decode(const char *in, unsigned char *out, int max_outlen)
+{
+	return SSL_base64_decode_ext(in, out, max_outlen, 0, 0);
+}
+
 int SSL_base64_encode(const void *in, int in_len, char *out)
 {
 	int outlen = 0;

+ 2 - 0
src/util.h

@@ -114,6 +114,8 @@ unsigned char *SSL_SHA256(const unsigned char *d, size_t n, unsigned char *md);
 
 int SSL_base64_decode(const char *in, unsigned char *out, int max_outlen);
 
+int SSL_base64_decode_ext(const char *in, unsigned char *out, int max_outlen, int url_safe, int auto_padding);
+
 int SSL_base64_encode(const void *in, int in_len, char *out);
 
 int generate_cert_key(const char *key_path, const char *cert_path, const char *san, int days);