]>
code.delx.au - pulseaudio/blob - src/pulsecore/ipacl.c
a240d2a0adc1bfe317fcbaa56ee2d3481c52018d
4 This file is part of PulseAudio.
6 Copyright 2004-2006 Lennart Poettering
7 Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
9 PulseAudio is free software; you can redistribute it and/or modify
10 it under the terms of the GNU Lesser General Public License as
11 published by the Free Software Foundation; either version 2.1 of the
12 License, or (at your option) any later version.
14 PulseAudio is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
19 You should have received a copy of the GNU Lesser General Public
20 License along with PulseAudio; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
29 #include <sys/types.h>
30 #include <sys/types.h>
33 #ifdef HAVE_SYS_SOCKET_H
34 #include <sys/socket.h>
36 #ifdef HAVE_NETINET_IN_H
37 #include <netinet/in.h>
39 #ifdef HAVE_NETINET_IN_SYSTM_H
40 #include <netinet/in_systm.h>
42 #ifdef HAVE_NETINET_IP_H
43 #include <netinet/ip.h>
45 #ifdef HAVE_ARPA_INET_H
46 #include <arpa/inet.h>
51 #include <pulse/xmalloc.h>
53 #include <pulsecore/core-util.h>
54 #include <pulsecore/llist.h>
55 #include <pulsecore/log.h>
57 #ifndef HAVE_INET_PTON
58 #include "inet_pton.h"
64 PA_LLIST_FIELDS(struct acl_entry
);
66 struct in_addr address_ipv4
;
67 struct in6_addr address_ipv6
;
72 PA_LLIST_HEAD(struct acl_entry
, entries
);
75 pa_ip_acl
* pa_ip_acl_new(const char *s
) {
76 const char *state
= NULL
;
82 acl
= pa_xnew(pa_ip_acl
, 1);
83 PA_LLIST_HEAD_INIT(struct acl_entry
, acl
->entries
);
85 while ((a
= pa_split(s
, ";", &state
))) {
87 struct acl_entry e
, *n
;
90 if ((slash
= strchr(a
, '/'))) {
93 if (pa_atou(slash
, &bits
) < 0) {
94 pa_log("failed to parse number of bits: %s", slash
);
100 if (inet_pton(AF_INET
, a
, &e
.address_ipv4
) > 0) {
102 e
.bits
= bits
== (uint32_t) -1 ? 32 : (int) bits
;
105 pa_log("number of bits out of range: %i", e
.bits
);
111 if (e
.bits
< 32 && (uint32_t) (ntohl(e
.address_ipv4
.s_addr
) << e
.bits
) != 0)
112 pa_log_warn("WARNING: Host part of ACL entry '%s/%u' is not zero!", a
, e
.bits
);
114 } else if (inet_pton(AF_INET6
, a
, &e
.address_ipv6
) > 0) {
116 e
.bits
= bits
== (uint32_t) -1 ? 128 : (int) bits
;
119 pa_log("number of bits out of range: %i", e
.bits
);
127 for (i
= 0, bits
= e
.bits
; i
< 16; i
++) {
132 if ((uint8_t) ((e
.address_ipv6
.s6_addr
[i
]) << bits
) != 0) {
141 pa_log_warn("WARNING: Host part of ACL entry '%s/%u' is not zero!", a
, e
.bits
);
145 pa_log("failed to parse address: %s", a
);
149 n
= pa_xmemdup(&e
, sizeof(struct acl_entry
));
150 PA_LLIST_PREPEND(struct acl_entry
, acl
->entries
, n
);
164 void pa_ip_acl_free(pa_ip_acl
*acl
) {
167 while (acl
->entries
) {
168 struct acl_entry
*e
= acl
->entries
;
169 PA_LLIST_REMOVE(struct acl_entry
, acl
->entries
, e
);
176 int pa_ip_acl_check(pa_ip_acl
*acl
, int fd
) {
177 struct sockaddr_storage sa
;
185 if (getpeername(fd
, (struct sockaddr
*) &sa
, &salen
) < 0)
188 if (sa
.ss_family
!= AF_INET
&& sa
.ss_family
!= AF_INET6
)
191 if (sa
.ss_family
== AF_INET
&& salen
!= sizeof(struct sockaddr_in
))
194 if (sa
.ss_family
== AF_INET6
&& salen
!= sizeof(struct sockaddr_in6
))
197 for (e
= acl
->entries
; e
; e
= e
->next
) {
199 if (e
->family
!= sa
.ss_family
)
202 if (e
->family
== AF_INET
) {
203 struct sockaddr_in
*sai
= (struct sockaddr_in
*) &sa
;
205 if (e
->bits
== 0 || /* this needs special handling because >> takes the right-hand side modulo 32 */
206 (ntohl(sai
->sin_addr
.s_addr
^ e
->address_ipv4
.s_addr
) >> (32 - e
->bits
)) == 0)
208 } else if (e
->family
== AF_INET6
) {
210 struct sockaddr_in6
*sai
= (struct sockaddr_in6
*) &sa
;
213 return memcmp(&sai
->sin6_addr
, &e
->address_ipv6
, 16) == 0;
218 for (i
= 0, bits
= e
->bits
; i
< 16; i
++) {
221 if (sai
->sin6_addr
.s6_addr
[i
] != e
->address_ipv6
.s6_addr
[i
])
226 if ((sai
->sin6_addr
.s6_addr
[i
] ^ e
->address_ipv6
.s6_addr
[i
]) >> (8 - bits
) != 0)