2
2
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
3
* SPDX-License-Identifier: Apache-2.0.
4
4
*/
5
+ #include <aws/common/byte_order.h>
5
6
#include <aws/common/environment.h>
6
7
#include <aws/http/private/no_proxy.h>
7
-
8
- #ifdef _WIN32
9
- # include <ws2tcpip.h>
10
- #else
11
- # include <arpa/inet.h>
12
- #endif
8
+ #include <aws/io/socket.h>
13
9
14
10
enum hostname_type {
15
11
HOSTNAME_TYPE_IPV4 ,
@@ -38,15 +34,15 @@ static bool s_cidr4_match(uint64_t bits, struct aws_string *network_part, uint32
38
34
}
39
35
40
36
/* Convert network pattern to binary */
41
- if (inet_pton ( AF_INET , aws_string_c_str ( network_part ) , & check ) != 1 ) {
37
+ if (aws_parse_ipv4_address ( network_part , & check ) != AWS_OP_SUCCESS ) {
42
38
return false;
43
39
}
44
40
45
41
if (bits > 0 && bits < 32 ) {
46
42
/* Apply the network mask for CIDR comparison */
47
43
uint32_t mask = 0xffffffff << (32 - bits );
48
- uint32_t host_network = ntohl (address );
49
- uint32_t check_network = ntohl (check );
44
+ uint32_t host_network = aws_ntoh32 (address );
45
+ uint32_t check_network = aws_ntoh32 (check );
50
46
51
47
/* Compare the masked addresses */
52
48
return (host_network & mask ) == (check_network & mask );
@@ -66,45 +62,62 @@ static bool s_cidr4_match(uint64_t bits, struct aws_string *network_part, uint32
66
62
* @param host_addr Pre-parsed binary representation of the host IP, or NULL to parse from host
67
63
* @return true if the IP address matches the CIDR pattern, false otherwise
68
64
*/
69
- static bool s_cidr6_match (uint64_t bits , struct aws_string * network_part , uint8_t * address ) {
70
- uint8_t check [16 ] = {0 };
71
-
65
+ static bool s_cidr6_match (
66
+ struct aws_allocator * allocator ,
67
+ uint64_t bits ,
68
+ struct aws_string * network_part ,
69
+ struct aws_byte_cursor address ) {
70
+ bool result = false;
71
+ struct aws_byte_buf check_buf ;
72
+ aws_byte_buf_init (& check_buf , allocator , 16 );
72
73
/* If no bits specified, use full 128 bits for IPv6 */
73
74
if (!bits ) {
74
75
bits = 128 ;
75
76
}
76
77
77
78
/* Check for valid bits parameter */
78
79
if (bits > 128 ) {
79
- return false ;
80
+ goto cleanup ;
80
81
}
81
82
/* Convert network pattern to binary */
82
- if (inet_pton ( AF_INET6 , aws_string_c_str ( network_part ), check ) != 1 ) {
83
- return false ;
83
+ if (aws_parse_ipv6_address ( network_part , & check_buf ) != AWS_OP_SUCCESS ) {
84
+ goto cleanup ;
84
85
}
86
+ struct aws_byte_cursor check = aws_byte_cursor_from_buf (& check_buf );
85
87
86
88
/* Calculate full bytes and remaining bits in the netmask */
87
89
uint64_t bytes = bits / 8 ;
88
90
uint64_t rest = bits % 8 ;
89
-
90
- /* Compare full bytes of the network part */
91
- if (bytes > 0 && memcmp (address , check , (size_t )bytes ) != 0 ) {
92
- return false;
91
+ if (bytes > address .len || address .len != check_buf .len || check_buf .len != 16 ) {
92
+ goto cleanup ;
93
+ }
94
+ if (bytes > 0 && !aws_array_eq (address .ptr , (size_t )bytes , check .ptr , (size_t )bytes )) {
95
+ goto cleanup ;
93
96
}
94
97
95
98
/* If we have remaining bits, compare the partial byte */
96
- if (rest > 0 && bytes < 16 ) {
99
+ if (rest > 0 ) {
97
100
/* Create a mask for the remaining bits */
98
101
unsigned char mask = (unsigned char )(0xff << (8 - rest ));
99
-
102
+ aws_byte_cursor_advance (& check , (size_t )bytes );
103
+ aws_byte_cursor_advance (& address , (size_t )bytes );
104
+ uint8_t address_byte = 0 ;
105
+ uint8_t check_byte = 0 ;
106
+ if (aws_byte_cursor_read_u8 (& address , & address_byte ) == false ||
107
+ aws_byte_cursor_read_u8 (& check , & check_byte ) == false) {
108
+ goto cleanup ;
109
+ }
100
110
/* Check if the masked bits match */
101
- if ((address [ bytes ] & mask ) != (check [ bytes ] & mask )) {
102
- return false ;
111
+ if ((address_byte & mask ) != (check_byte & mask )) {
112
+ goto cleanup ;
103
113
}
104
114
}
105
115
106
116
/* All checks passed, addresses match within the CIDR range */
107
- return true;
117
+ result = true;
118
+ cleanup :
119
+ aws_byte_buf_clean_up (& check_buf );
120
+ return result ;
108
121
}
109
122
110
123
static bool s_is_dot (uint8_t c ) {
@@ -128,6 +141,7 @@ bool aws_http_host_matches_no_proxy(
128
141
struct aws_byte_cursor no_proxy_cur = aws_byte_cursor_from_string (no_proxy_str );
129
142
struct aws_array_list no_proxy_list ;
130
143
struct aws_string * host_str = aws_string_new_from_cursor (allocator , & host );
144
+ struct aws_byte_buf ipv6_addr = {0 };
131
145
132
146
if (aws_array_list_init_dynamic (& no_proxy_list , allocator , 10 , sizeof (struct aws_byte_cursor ))) {
133
147
goto cleanup ;
@@ -139,11 +153,10 @@ bool aws_http_host_matches_no_proxy(
139
153
140
154
/* Store parsed binary addresses for reuse */
141
155
uint32_t ipv4_addr = 0 ;
142
- uint8_t ipv6_addr [16 ] = {0 };
143
156
144
157
/* Determine host type and parse address if applicable */
145
158
enum hostname_type type = HOSTNAME_TYPE_REGULAR ;
146
- if (inet_pton ( AF_INET , aws_string_c_str ( host_str ) , & ipv4_addr ) == 1 ) {
159
+ if (aws_parse_ipv4_address ( host_str , & ipv4_addr ) == AWS_OP_SUCCESS ) {
147
160
type = HOSTNAME_TYPE_IPV4 ;
148
161
} else {
149
162
struct aws_string * host_str_copy = host_str ;
@@ -155,7 +168,8 @@ bool aws_http_host_matches_no_proxy(
155
168
host_str_copy = aws_string_new_from_cursor (allocator , & host_copy );
156
169
}
157
170
158
- if (inet_pton (AF_INET6 , aws_string_c_str (host_str_copy ), ipv6_addr ) == 1 ) {
171
+ aws_byte_buf_init (& ipv6_addr , allocator , 16 );
172
+ if (aws_parse_ipv6_address (host_str_copy , & ipv6_addr ) == AWS_OP_SUCCESS ) {
159
173
/* Update the host str */
160
174
if (host_str != host_str_copy ) {
161
175
aws_string_destroy (host_str );
@@ -254,7 +268,8 @@ bool aws_http_host_matches_no_proxy(
254
268
goto cleanup ;
255
269
}
256
270
} else {
257
- if (s_cidr6_match (network_bits , network_part_str , ipv6_addr )) {
271
+ if (s_cidr6_match (
272
+ allocator , network_bits , network_part_str , aws_byte_cursor_from_buf (& ipv6_addr ))) {
258
273
bypass = true;
259
274
aws_string_destroy (network_part_str );
260
275
goto cleanup ;
@@ -271,6 +286,7 @@ bool aws_http_host_matches_no_proxy(
271
286
}
272
287
273
288
cleanup :
289
+ aws_byte_buf_clean_up (& ipv6_addr );
274
290
aws_string_destroy (host_str );
275
291
aws_array_list_clean_up (& no_proxy_list );
276
292
return bypass ;
0 commit comments