Check-in Number:
|
1206 | |
Date: |
2001-Oct-24 14:11:31 (local)
2001-Oct-24 12:11:31 (UTC) |
User: | rse |
Branch: | |
Comment: |
Add support for ACLs with "IPv4-mapped IPv6 addresses" (e.g.
"::ffff:1.2.3.4") as defined by RFC 2373. This is important for security
reasons because these are IPv6 addresses but which have to match
incoming IPv4 addresses in ACLs. |
Tickets: |
|
Inspections: |
|
Files: |
|
ossp-pkg/sa/sa.c 1.35 -> 1.36
--- sa.c 2001/10/24 11:43:28 1.35
+++ sa.c 2001/10/24 12:11:31 1.36
@@ -697,9 +697,12 @@
const unsigned char *ucp1, *ucp2;
unsigned int uc1, uc2, mask;
size_t l1, l2;
- int nFamily;
int nBytes;
int nBits;
+#ifdef AF_INET6
+ int i;
+ const unsigned char *ucp0;
+#endif
/* argument sanity check(s) */
if (saa1 == NULL || saa2 == NULL || prefixlen < -1)
@@ -709,13 +712,8 @@
if (prefixlen == 0)
return SA_OK;
- /* short circuiting handling different families */
- if (saa1->nFamily != saa2->nFamily)
- return SA_ERR_MTC;
-
/* determine address representation pointer and size */
- nFamily = saa1->nFamily;
- if (nFamily == AF_LOCAL) {
+ if (saa1->nFamily == AF_LOCAL) {
ucp1 = (const unsigned char *)(((struct sockaddr_un *)saa1->saBuf)->sun_path);
ucp2 = (const unsigned char *)(((struct sockaddr_un *)saa2->saBuf)->sun_path);
l1 = strlen(((struct sockaddr_un *)saa1->saBuf)->sun_path) * 8;
@@ -731,13 +729,38 @@
nBits = prefixlen;
}
}
- else if (nFamily == AF_INET) {
+#ifdef AF_INET6
+ else if ( (saa1->nFamily == AF_INET && saa2->nFamily == AF_INET6)
+ || (saa1->nFamily == AF_INET6 && saa2->nFamily == AF_INET )) {
+ /* special case of comparing a regular IPv4 address (1.2.3.4) with an
+ "IPv4-mapped IPv6 address" (::ffff:1.2.3.4). For details see RFC 2373. */
+ if (saa1->nFamily == AF_INET6) {
+ ucp1 = (const unsigned char *)&(((struct sockaddr_in6 *)saa1->saBuf)->sin6_addr);
+ ucp2 = (const unsigned char *)&(((struct sockaddr_in *)saa2->saBuf)->sin_addr);
+ ucp0 = ucp1;
+ ucp1 += 12;
+ }
+ else {
+ ucp1 = (const unsigned char *)&(((struct sockaddr_in *)saa1->saBuf)->sin_addr);
+ ucp2 = (const unsigned char *)&(((struct sockaddr_in6 *)saa2->saBuf)->sin6_addr);
+ ucp0 = ucp2;
+ ucp2 += 12;
+ }
+ for (i = 0; i < 10; i++)
+ if (ucp0[i] != 0x00)
+ return SA_ERR_MTC;
+ if (!(ucp0[10] == 0xFF && ucp0[11] == 0xFF))
+ return SA_ERR_MTC;
+ nBits = 32;
+ }
+#endif
+ else if (saa1->nFamily == AF_INET) {
ucp1 = (const unsigned char *)&(((struct sockaddr_in *)saa1->saBuf)->sin_addr);
ucp2 = (const unsigned char *)&(((struct sockaddr_in *)saa2->saBuf)->sin_addr);
nBits = 32;
}
#ifdef AF_INET6
- else if (nFamily == AF_INET6) {
+ else if (saa1->nFamily == AF_INET6) {
ucp1 = (const unsigned char *)&(((struct sockaddr_in6 *)saa1->saBuf)->sin6_addr);
ucp2 = (const unsigned char *)&(((struct sockaddr_in6 *)saa2->saBuf)->sin6_addr);
nBits = 128;
|
|