PostgreSQL Source Code: src/interfaces/libpq/fe-secure-common.c Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
21
23
25
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44static bool
46{
47 int lenpat = strlen(pattern);
48 int lenstr = strlen(string);
49
50
51 if (lenpat < 3 ||
52 pattern[0] != '*' ||
53 pattern[1] != '.')
54 return false;
55
56
57 if (lenpat > lenstr)
58 return false;
59
60
61
62
63 if (pg_strcasecmp(pattern + 1, string + lenstr - lenpat + 1) != 0)
64 return false;
65
66
67
68
69
70 if (strchr(string, '.') < string + lenstr - lenpat)
71 return false;
72
73
74 return true;
75}
76
77
78
79
80
81
82
83
84
85
86int
88 const char *namedata, size_t namelen,
89 char **store_name)
90{
92 int result;
94
95 *store_name = NULL;
96
97 if (!(host && host[0] != '\0'))
98 {
100 return -1;
101 }
102
103
104
105
106
108 if (name == NULL)
109 {
111 return -1;
112 }
113 memcpy(name, namedata, namelen);
114 name[namelen] = '\0';
115
116
117
118
119
120 if (namelen != strlen(name))
121 {
124 return -1;
125 }
126
128 {
129
130 result = 1;
131 }
133 {
134
135 result = 1;
136 }
137 else
138 {
139 result = 0;
140 }
141
142 *store_name = name;
143 return result;
144}
145
146
147
148
149
150
151
152
153
154
155
156int
158 const unsigned char *ipdata,
159 size_t iplen,
160 char **store_name)
161{
162 char *addrstr;
163 int match = 0;
165 int family;
166 char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"];
168
169 *store_name = NULL;
170
171 if (!(host && host[0] != '\0'))
172 {
174 return -1;
175 }
176
177
178
179
180
181
182
183
184 if (iplen == 4)
185 {
186
187 struct in_addr addr;
188
189 family = AF_INET;
190
191
192
193
194
195
197 {
198 if (memcmp(ipdata, &addr.s_addr, iplen) == 0)
199 match = 1;
200 }
201 }
202
203
204
205
206
207#ifdef HAVE_INET_PTON
208 else if (iplen == 16)
209 {
210
211 struct in6_addr addr;
212
213 family = AF_INET6;
214
215 if (inet_pton(AF_INET6, host, &addr) == 1)
216 {
217 if (memcmp(ipdata, &addr.s6_addr, iplen) == 0)
218 match = 1;
219 }
220 }
221#endif
222 else
223 {
224
225
226
227
229 iplen);
230 return -1;
231 }
232
233
234 addrstr = pg_inet_net_ntop(family, ipdata, 8 * iplen, tmp, sizeof(tmp));
235 if (!addrstr)
236 {
238 strerror_r(errno, sebuf, sizeof(sebuf)));
239 return -1;
240 }
241
242 *store_name = strdup(addrstr);
243 return match;
244}
245
246
247
248
249
250
251bool
253{
255 int rc;
256 int names_examined = 0;
257 char *first_name = NULL;
258
259
260
261
262
263 if (strcmp(conn->sslmode, "verify-full") != 0)
264 return true;
265
266
267 if (!(host && host[0] != '\0'))
268 {
270 return false;
271 }
272
274
275 if (rc == 0)
276 {
277
278
279
280
281
282
283 if (names_examined > 1)
284 {
286 libpq_ngettext("server certificate for \"%s\" (and %d other name) does not match host name \"%s\"",
287 "server certificate for \"%s\" (and %d other names) does not match host name \"%s\"",
288 names_examined - 1),
289 first_name, names_examined - 1, host);
291 }
292 else if (names_examined == 1)
293 {
295 first_name, host);
296 }
297 else
298 {
300 }
301 }
302
303
304 free(first_name);
305
306 return (rc == 1);
307}
int pq_verify_peer_name_matches_certificate_name(PGconn *conn, const char *namedata, size_t namelen, char **store_name)
static bool wildcard_certificate_match(const char *pattern, const char *string)
int pq_verify_peer_name_matches_certificate_ip(PGconn *conn, const unsigned char *ipdata, size_t iplen, char **store_name)
bool pq_verify_peer_name_matches_certificate(PGconn *conn)
int pgtls_verify_peer_name_matches_certificate_guts(PGconn *conn, int *names_examined, char **first_name)
#define libpq_ngettext(s, p, n)
void libpq_append_conn_error(PGconn *conn, const char *fmt,...)
#define PG_STRERROR_R_BUFLEN
int pg_strcasecmp(const char *s1, const char *s2)
char * pg_inet_net_ntop(int af, const void *src, int bits, char *dst, size_t size)
int inet_aton(const char *cp, struct in_addr *addr)
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
void appendPQExpBufferChar(PQExpBuffer str, char ch)
PQExpBufferData errorMessage