Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit3c9bb88

Browse files
committed
Allow IPv4-format entries in pg_hba.conf to match IPv6 connections
that have IPv4-embedded-in-IPv6 addresses. Per idea of Andreas Pflug.
1 parent23d07fa commit3c9bb88

File tree

5 files changed

+151
-46
lines changed

5 files changed

+151
-46
lines changed

‎doc/src/sgml/client-auth.sgml

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$Header: /cvsroot/pgsql/doc/src/sgml/client-auth.sgml,v 1.56 2003/08/31 17:32:18 petere Exp $
2+
$Header: /cvsroot/pgsql/doc/src/sgml/client-auth.sgml,v 1.57 2003/09/05 20:31:35 tgl Exp $
33
-->
44

55
<chapter id="client-authentication">
@@ -199,13 +199,17 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
199199
<programlisting>
200200
(<replaceable>actual-IP-address</replaceable> xor <replaceable>IP-address-field</replaceable>) and <replaceable>IP-mask-field</replaceable>
201201
</programlisting>
202-
must be zero for the record to match. (Of course IP addresses
203-
can be spoofed but this consideration is beyond the scope of
204-
<productname>PostgreSQL</productname>.) If you machine supports
205-
IPv6, the default <filename>pg_hba.conf</> file will have an
206-
IPv6 entry for <literal>localhost</>. You can add your own IPv6
207-
entries to the file. IPv6 entries are used only for IPv6
208-
connections.
202+
must be zero for the record to match.
203+
</para>
204+
205+
<para>
206+
An IP address given in IPv4 format will match IPv6 connections that
207+
have the corresponding address, for example <literal>127.0.0.1</>
208+
will match the IPv6 address <literal>::ffff:127.0.0.1</>. An entry
209+
given in IPv6 format will match only IPv6 connections, even if the
210+
represented address is in the IPv4-in-IPv6 range. Note that entries
211+
in IPv6 format will be rejected if the system's C library does not have
212+
support for IPv6 addresses.
209213
</para>
210214

211215
<para>
@@ -219,9 +223,10 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
219223
<term><replaceable>CIDR-mask</replaceable></term>
220224
<listitem>
221225
<para>
222-
This is an integer specifying the number of significant bits
223-
to set in the mask, and is an alternative to using the
224-
<replaceable>IP-mask</replaceable> notation. The number must
226+
This field may be used as an alternative to the
227+
<replaceable>IP-mask</replaceable> notation. It is an
228+
integer specifying the number of high-order bits
229+
to set in the mask. The number must
225230
be between 0 and 32 (in the case of an IPv4 address) or 128
226231
(in the case of an IPv6 address) inclusive. 0 will match any
227232
address, while 32/128 will match only the exact host specified.

‎src/backend/libpq/hba.c

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*
1111
*
1212
* IDENTIFICATION
13-
* $Header: /cvsroot/pgsql/src/backend/libpq/hba.c,v 1.112 2003/09/0503:57:13 momjian Exp $
13+
* $Header: /cvsroot/pgsql/src/backend/libpq/hba.c,v 1.113 2003/09/0520:31:35 tgl Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -673,13 +673,6 @@ parse_hba(List *line, hbaPort *port, bool *found_p, bool *error_p)
673673
if (cidr_slash)
674674
*cidr_slash='/';
675675

676-
if (file_ip_addr->ai_family!=port->raddr.addr.ss_family)
677-
{
678-
/* Wrong address family. */
679-
freeaddrinfo_all(hints.ai_family,file_ip_addr);
680-
return;
681-
}
682-
683676
/* Get the netmask */
684677
if (cidr_slash)
685678
{
@@ -705,6 +698,28 @@ parse_hba(List *line, hbaPort *port, bool *found_p, bool *error_p)
705698
gotohba_syntax;
706699
}
707700

701+
if (file_ip_addr->ai_family!=port->raddr.addr.ss_family)
702+
{
703+
/*
704+
* Wrong address family. We allow only one case: if the
705+
* file has IPv4 and the port is IPv6, promote the file
706+
* address to IPv6 and try to match that way.
707+
*/
708+
#ifdefHAVE_IPV6
709+
if (file_ip_addr->ai_family==AF_INET&&
710+
port->raddr.addr.ss_family==AF_INET6)
711+
{
712+
promote_v4_to_v6_addr((structsockaddr_storage*)file_ip_addr->ai_addr);
713+
promote_v4_to_v6_mask(mask);
714+
}
715+
else
716+
#endif/* HAVE_IPV6 */
717+
{
718+
freeaddrinfo_all(hints.ai_family,file_ip_addr);
719+
return;
720+
}
721+
}
722+
708723
/* Read the rest of the line. */
709724
line=lnext(line);
710725
if (!line)

‎src/backend/libpq/ip.c

Lines changed: 105 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/libpq/ip.c,v 1.19 2003/08/04 02:39:59 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/libpq/ip.c,v 1.20 2003/09/05 20:31:36 tgl Exp $
1212
*
1313
* This file and the IPV6 implementation were initially provided by
1414
* Nigel Kukard <nkukard@lbsd.net>, Linux Based Systems Design
@@ -34,7 +34,8 @@
3434
#endif
3535
#include<arpa/inet.h>
3636
#include<sys/file.h>
37-
#endif
37+
38+
#endif/* !defined(_MSC_VER) && !defined(__BORLANDC__) */
3839

3940
#include"libpq/ip.h"
4041

@@ -265,9 +266,16 @@ getnameinfo_unix(const struct sockaddr_un * sa, int salen,
265266

266267
return0;
267268
}
269+
268270
#endif/* HAVE_UNIX_SOCKETS */
269271

270272

273+
/*
274+
* rangeSockAddr - is addr within the subnet specified by netaddr/netmask ?
275+
*
276+
* Note: caller must already have verified that all three addresses are
277+
* in the same address family; and AF_UNIX addresses are not supported.
278+
*/
271279
int
272280
rangeSockAddr(conststructsockaddr_storage*addr,
273281
conststructsockaddr_storage*netaddr,
@@ -287,6 +295,39 @@ rangeSockAddr(const struct sockaddr_storage * addr,
287295
return0;
288296
}
289297

298+
staticint
299+
rangeSockAddrAF_INET(conststructsockaddr_in*addr,
300+
conststructsockaddr_in*netaddr,
301+
conststructsockaddr_in*netmask)
302+
{
303+
if (((addr->sin_addr.s_addr ^netaddr->sin_addr.s_addr)&
304+
netmask->sin_addr.s_addr)==0)
305+
return1;
306+
else
307+
return0;
308+
}
309+
310+
311+
#ifdefHAVE_IPV6
312+
staticint
313+
rangeSockAddrAF_INET6(conststructsockaddr_in6*addr,
314+
conststructsockaddr_in6*netaddr,
315+
conststructsockaddr_in6*netmask)
316+
{
317+
inti;
318+
319+
for (i=0;i<16;i++)
320+
{
321+
if (((addr->sin6_addr.s6_addr[i] ^netaddr->sin6_addr.s6_addr[i])&
322+
netmask->sin6_addr.s6_addr[i])!=0)
323+
return0;
324+
}
325+
326+
return1;
327+
}
328+
329+
#endif
330+
290331
/*
291332
*SockAddr_cidr_mask - make a network mask of the appropriate family
292333
* and required number of significant bits
@@ -358,34 +399,74 @@ SockAddr_cidr_mask(struct sockaddr_storage ** mask, char *numbits, int family)
358399
return0;
359400
}
360401

361-
staticint
362-
rangeSockAddrAF_INET(conststructsockaddr_in*addr,conststructsockaddr_in*netaddr,
363-
conststructsockaddr_in*netmask)
402+
403+
#ifdefHAVE_IPV6
404+
405+
/*
406+
* promote_v4_to_v6_addr --- convert an AF_INET addr to AF_INET6, using
407+
*the standard convention for IPv4 addresses mapped into IPv6 world
408+
*
409+
* The passed addr is modified in place. Note that we only worry about
410+
* setting the fields that rangeSockAddr will look at.
411+
*/
412+
void
413+
promote_v4_to_v6_addr(structsockaddr_storage*addr)
364414
{
365-
if (((addr->sin_addr.s_addr ^netaddr->sin_addr.s_addr)&
366-
netmask->sin_addr.s_addr)==0)
367-
return1;
368-
else
369-
return0;
370-
}
415+
structsockaddr_inaddr4;
416+
structsockaddr_in6addr6;
417+
uint32s_addr;
371418

419+
memcpy(&addr4,addr,sizeof(addr4));
420+
s_addr=ntohl(addr4.sin_addr.s_addr);
372421

373-
#ifdefHAVE_IPV6
374-
staticint
375-
rangeSockAddrAF_INET6(conststructsockaddr_in6*addr,
376-
conststructsockaddr_in6*netaddr,
377-
conststructsockaddr_in6*netmask)
422+
memset(&addr6,0,sizeof(addr6));
423+
424+
addr6.sin6_family=AF_INET6;
425+
426+
addr6.sin6_addr.s6_addr[10]=0xff;
427+
addr6.sin6_addr.s6_addr[11]=0xff;
428+
addr6.sin6_addr.s6_addr[12]= (s_addr >>24)&0xFF;
429+
addr6.sin6_addr.s6_addr[13]= (s_addr >>16)&0xFF;
430+
addr6.sin6_addr.s6_addr[14]= (s_addr >>8)&0xFF;
431+
addr6.sin6_addr.s6_addr[15]= (s_addr)&0xFF;
432+
433+
memcpy(addr,&addr6,sizeof(addr6));
434+
}
435+
436+
/*
437+
* promote_v4_to_v6_mask --- convert an AF_INET netmask to AF_INET6, using
438+
*the standard convention for IPv4 addresses mapped into IPv6 world
439+
*
440+
* This must be different from promote_v4_to_v6_addr because we want to
441+
* set the high-order bits to 1's not 0's.
442+
*
443+
* The passed addr is modified in place. Note that we only worry about
444+
* setting the fields that rangeSockAddr will look at.
445+
*/
446+
void
447+
promote_v4_to_v6_mask(structsockaddr_storage*addr)
378448
{
449+
structsockaddr_inaddr4;
450+
structsockaddr_in6addr6;
451+
uint32s_addr;
379452
inti;
380453

381-
for (i=0;i<16;i++)
382-
{
383-
if (((addr->sin6_addr.s6_addr[i] ^netaddr->sin6_addr.s6_addr[i])&
384-
netmask->sin6_addr.s6_addr[i])!=0)
385-
return0;
386-
}
454+
memcpy(&addr4,addr,sizeof(addr4));
455+
s_addr=ntohl(addr4.sin_addr.s_addr);
387456

388-
return1;
457+
memset(&addr6,0,sizeof(addr6));
458+
459+
addr6.sin6_family=AF_INET6;
460+
461+
for (i=0;i<12;i++)
462+
addr6.sin6_addr.s6_addr[i]=0xff;
463+
464+
addr6.sin6_addr.s6_addr[12]= (s_addr >>24)&0xFF;
465+
addr6.sin6_addr.s6_addr[13]= (s_addr >>16)&0xFF;
466+
addr6.sin6_addr.s6_addr[14]= (s_addr >>8)&0xFF;
467+
addr6.sin6_addr.s6_addr[15]= (s_addr)&0xFF;
468+
469+
memcpy(addr,&addr6,sizeof(addr6));
389470
}
390471

391-
#endif
472+
#endif/* HAVE_IPV6 */

‎src/backend/libpq/pg_hba.conf.sample

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,5 @@
5353
local all all trust
5454
host all all 127.0.0.1 255.255.255.255 trust
5555

56-
# uncommentthese to support IPv6localhost connections
56+
# uncommentthis to support IPv6loopback connections
5757
# host all all ::1 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff trust
58-
# host all all ::ffff:127.0.0.1/128 trust

‎src/include/libpq/ip.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
*
66
* Copyright (c) 2003, PostgreSQL Global Development Group
77
*
8-
* $Id: ip.h,v 1.10 2003/08/04 00:43:31 momjian Exp $
8+
* $Id: ip.h,v 1.11 2003/09/05 20:31:36 tgl Exp $
99
*
1010
*-------------------------------------------------------------------------
1111
*/
@@ -33,6 +33,11 @@ extern int rangeSockAddr(const struct sockaddr_storage * addr,
3333
externintSockAddr_cidr_mask(structsockaddr_storage**mask,
3434
char*numbits,intfamily);
3535

36+
#ifdefHAVE_IPV6
37+
externvoidpromote_v4_to_v6_addr(structsockaddr_storage*addr);
38+
externvoidpromote_v4_to_v6_mask(structsockaddr_storage*addr);
39+
#endif
40+
3641
#ifdefHAVE_UNIX_SOCKETS
3742
#defineIS_AF_UNIX(fam) ((fam) == AF_UNIX)
3843
#else

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp