xref: /freebsd/lib/libcasper/services/cap_net/cap_net.3 (revision e5b786625f7f82a1fa91e41823332459ea5550f9)
1.\" Copyright (c) 2020 Mariusz Zaborski <oshogbo@FreeBSD.org>
2.\"
3.\" Redistribution and use in source and binary forms, with or without
4.\" modification, are permitted provided that the following conditions
5.\" are met:
6.\" 1. Redistributions of source code must retain the above copyright
7.\"    notice, this list of conditions and the following disclaimer.
8.\" 2. Redistributions in binary form must reproduce the above copyright
9.\"    notice, this list of conditions and the following disclaimer in the
10.\"    documentation and/or other materials provided with the distribution.
11.\"
12.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
13.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
14.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
15.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
16.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
17.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
18.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
19.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
20.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
21.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
22.\" SUCH DAMAGE.
23.\"
24.Dd November 15, 2021
25.Dt CAP_NET 3
26.Os
27.Sh NAME
28.Nm cap_bind ,
29.Nm cap_connect ,
30.Nm cap_getaddrinfo ,
31.Nm cap_gethostbyaddr ,
32.Nm cap_gethostbyname ,
33.Nm cap_gethostbyname2 ,
34.Nm cap_getnameinfo ,
35.Nm cap_net_free ,
36.Nm cap_net_limit ,
37.Nm cap_net_limit_addr2name ,
38.Nm cap_net_limit_addr2name_family ,
39.Nm cap_net_limit_bind ,
40.Nm cap_net_limit_connect ,
41.Nm cap_net_limit_init ,
42.Nm cap_net_limit_name2addr ,
43.Nm cap_net_limit_name2addr_family ,
44.Nd "library for networking in capability mode"
45.Sh LIBRARY
46.Lb libcap_net
47.Sh SYNOPSIS
48.In sys/nv.h
49.In libcasper.h
50.In casper/cap_net.h
51.Ft int
52.Fn cap_bind "cap_channel_t *chan" "int s" "const struct sockaddr *addr" "socklen_t addrlen"
53.Ft int
54.Fn cap_connect "cap_channel_t *chan" "int s" "const struct sockaddr *name" "socklen_t namelen"
55.Ft int
56.Fn cap_getaddrinfo "cap_channel_t *chan" "const char *hostname" "const char *servname" "const struct addrinfo *hints" "struct addrinfo **res"
57.Ft int
58.Fn cap_getnameinfo "cap_channel_t *chan" "const struct sockaddr *sa" "socklen_t salen" "char *host" "size_t hostlen" "char *serv" "size_t servlen" "int flags"
59.Ft "struct hostent *"
60.Fn cap_gethostbyname "const cap_channel_t *chan" "const char *name"
61.Ft "struct hostent *"
62.Fn cap_gethostbyname2 "const cap_channel_t *chan" "const char *name" "int af"
63.Ft "struct hostent *"
64.Fn cap_gethostbyaddr "const cap_channel_t *chan" "const void *addr" "socklen_t len" "int af"
65.Ft "cap_net_limit_t *"
66.Fn cap_net_limit_init "cap_channel_t *chan" "uint64_t mode"
67.Ft int
68.Fn cap_net_limit "cap_net_limit_t *limit"
69.Ft void
70.Fn cap_net_free "cap_net_limit_t *limit"
71.Ft "cap_net_limit_t *"
72.Fn cap_net_limit_addr2name_family "cap_net_limit_t *limit" "int *family" "size_t size"
73.Ft "cap_net_limit_t *"
74.Fn cap_net_limit_addr2name "cap_net_limit_t *limit" "const struct sockaddr *sa" "socklen_t salen"
75.Ft "cap_net_limit_t *"
76.Fn cap_net_limit_name2addr_family "cap_net_limit_t *limit" "int *family" "size_t size"
77.Ft "cap_net_limit_t *"
78.Fn cap_net_limit_name2addr "cap_net_limit_t *limit" "const char *name" "const char *serv"
79.Ft "cap_net_limit_t *"
80.Fn cap_net_limit_connect "cap_net_limit_t *limit" "const struct sockaddr *sa" "socklen_t salen"
81.Ft "cap_net_limit_t *"
82.Fn cap_net_limit_bind "cap_net_limit_t *limit" "const struct sockaddr *sa" "socklen_t salen"
83.Sh DESCRIPTION
84The functions
85.Fn cap_bind ,
86.Fn cap_connect ,
87.Fn cap_gethostbyname ,
88.Fn cap_gethostbyname2 ,
89.Fn cap_gethostbyaddr
90and
91.Fn cap_getnameinfo
92provide a set of APIs equivalent to
93.Xr bind 2 ,
94.Xr connect 2 ,
95.Xr gethostbyname 3 ,
96.Xr gethostbyname2 3 ,
97.Xr gethostbyaddr 3
98and
99.Xr getnameinfo 3
100except that a connection to the
101.Nm system.net
102service needs to be provided.
103.Sh LIMITS
104By default, the cap_net capability provides unrestricted access to the network
105namespace.
106Applications typically only require access to a small portion of the network
107namespace:
108The
109.Fn cap_net_limit
110function can be used to restrict access to the network.
111The
112.Fn cap_net_limit_init
113returns an opaque limit handle used to store a list of capabilities.
114The
115.Fv mode
116restricts the functionality of the service.
117Modes are encoded using the following flags:
118.Pp
119.Bd -literal -offset indent -compact
120CAPNET_ADDR2NAME		reverse DNS lookups are allowed with
121				cap_getnameinfo
122CAPNET_NAME2ADDR		name resolution is allowed with
123				cap_getaddrinfo
124CAPNET_DEPRECATED_ADDR2NAME	reverse DNS lookups are allowed with
125				cap_gethostbyaddr
126CAPNET_DEPRECATED_NAME2ADDR	name resolution is allowed with
127				cap_gethostbyname and cap_gethostbyname2
128CAPNET_BIND			bind syscall is allowed
129CAPNET_CONNECT			connect syscall is allowed
130CAPNET_CONNECTDNS		connect syscall is allowed to the values
131				returned from previous call to
132				the cap_getaddrinfo or cap_gethostbyname
133.Ed
134.Pp
135.Fn cap_net_limit_addr2name_family
136limits the
137.Fn cap_getnameinfo
138and
139.Fn cap_gethostbyaddr
140to do reverse DNS lookups to specific family (AF_INET, AF_INET6, etc.)
141.Pp
142.Fn cap_net_limit_addr2name
143limits the
144.Fn cap_getnameinfo
145and
146.Fn cap_gethostbyaddr
147to do reverse DNS lookups only on those specific structures.
148.Pp
149.Fn cap_net_limit_name2addr_family
150limits the
151.Fn cap_getaddrinfo ,
152.Fn cap_gethostbyname
153and
154.Fn cap_gethostbyname2
155to do the name resolution on specific family (AF_INET, AF_INET6, etc.)
156.Pp
157.Fn cap_net_limit_addr2name
158restricts
159.Fn cap_getaddrinfo ,
160.Fn cap_gethostbyname
161and
162.Fn cap_gethostbyname2
163to a set of domains.
164.Pp
165.Fn cap_net_limit_bind
166limits
167.Fn cap_bind
168to bind only on those specific structures.
169.Pp
170.Fn cap_net_limit_connect
171limits
172.Fn cap_connect
173to connect only on those specific structures.
174If the CAPNET_CONNECTDNS is set the limits are extended to the values returned
175by
176.Fn cap_getaddrinfo ,
177.Fn cap_gethostbyname
178and
179.Fn cap_gethostbyname2
180In case of the
181.Fn cap_getaddrinfo
182the restriction is strict.
183In case of the
184.Fn cap_gethostbyname
185and
186.Fn cap_gethostbyname2
187any port will be accepted in the
188.Fn cap_connect
189function.
190.Pp
191.Fn cap_net_limit
192applies a set of sysctl limits to the capability, denying access to sysctl
193variables not belonging to the set.
194.Pp
195Once a set of limits is applied, subsequent calls to
196.Fn cap_net_limit
197will fail unless the new set is a subset of the current set.
198.Pp
199The
200.Fn cap_net_limit
201will consume the limits.
202If the
203.Fn cap_net_limit
204was not called the rights may be freed using
205.Fn cap_net_free .
206Multiple calls to
207.Fn cap_net_limit_addr2name_family ,
208.Fn cap_net_limit_addr2name ,
209.Fn cap_net_limit_name2addr_family ,
210.Fn cap_net_limit_name2addr ,
211.Fn cap_net_limit_connect ,
212and
213.Fn cap_net_limit_bind
214is supported, each call is extending preview capabilities.
215.Sh EXAMPLES
216The following example first opens a capability to casper and then uses this
217capability to create the
218.Nm system.net
219casper service and uses it to resolve a host and connect to it.
220.Bd -literal
221cap_channel_t *capcas, *capnet;
222cap_net_limit_t *limit;
223int familylimit, error, s;
224const char *host = "example.com";
225struct addrinfo hints, *res;
226
227/* Open capability to Casper. */
228capcas = cap_init();
229if (capcas == NULL)
230	err(1, "Unable to contact Casper");
231
232/* Cache NLA for gai_strerror. */
233caph_cache_catpages();
234
235/* Enter capability mode sandbox. */
236if (caph_enter_casper() < 0)
237	err(1, "Unable to enter capability mode");
238
239/* Use Casper capability to create capability to the system.net service. */
240capnet = cap_service_open(capcas, "system.net");
241if (capnet == NULL)
242	err(1, "Unable to open system.net service");
243
244/* Close Casper capability. */
245cap_close(capcas);
246
247/* Limit system.net to reserve IPv4 addresses, to host example.com . */
248limit = cap_net_limit_init(capnet, CAPNET_NAME2ADDR | CAPNET_CONNECTDNS);
249if (limit == NULL)
250	err(1, "Unable to create limits.");
251cap_net_limit_name2addr(limit, host, "80");
252familylimit = AF_INET;
253cap_net_limit_name2addr_family(limit, &familylimit, 1);
254if (cap_net_limit(limit) < 0)
255	err(1, "Unable to apply limits.");
256
257/* Find IP addresses for the given host. */
258memset(&hints, 0, sizeof(hints));
259hints.ai_family = AF_INET;
260hints.ai_socktype = SOCK_STREAM;
261
262error = cap_getaddrinfo(capnet, host, "80", &hints, &res);
263if (error != 0)
264	errx(1, "cap_getaddrinfo(): %s: %s", host, gai_strerror(error));
265
266s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
267if (s < 0)
268	err(1, "Unable to create socket");
269
270if (cap_connect(capnet, s, res->ai_addr,  res->ai_addrlen) < 0)
271	err(1, "Unable to connect to host");
272.Ed
273.Sh SEE ALSO
274.Xr bind 2 ,
275.Xr cap_enter 2 ,
276.Xr connect 2 ,
277.Xr caph_enter 3 ,
278.Xr err 3 ,
279.Xr gethostbyaddr 3 ,
280.Xr gethostbyname 3 ,
281.Xr gethostbyname2 3 ,
282.Xr getnameinfo 3 ,
283.Xr capsicum 4 ,
284.Xr nv 9
285.Sh AUTHORS
286.An Mariusz Zaborski Aq Mt oshogbo@FreeBSD.org
287