1832dc76bSMariusz Zaborski.\" Copyright (c) 2020 Mariusz Zaborski <oshogbo@FreeBSD.org>
2832dc76bSMariusz Zaborski.\"
3832dc76bSMariusz Zaborski.\" Redistribution and use in source and binary forms, with or without
4832dc76bSMariusz Zaborski.\" modification, are permitted provided that the following conditions
5832dc76bSMariusz Zaborski.\" are met:
6832dc76bSMariusz Zaborski.\" 1. Redistributions of source code must retain the above copyright
7832dc76bSMariusz Zaborski.\"    notice, this list of conditions and the following disclaimer.
8832dc76bSMariusz Zaborski.\" 2. Redistributions in binary form must reproduce the above copyright
9832dc76bSMariusz Zaborski.\"    notice, this list of conditions and the following disclaimer in the
10832dc76bSMariusz Zaborski.\"    documentation and/or other materials provided with the distribution.
11832dc76bSMariusz Zaborski.\"
12832dc76bSMariusz Zaborski.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
13832dc76bSMariusz Zaborski.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
14832dc76bSMariusz Zaborski.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
15832dc76bSMariusz Zaborski.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
16832dc76bSMariusz Zaborski.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
17832dc76bSMariusz Zaborski.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
18832dc76bSMariusz Zaborski.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
19832dc76bSMariusz Zaborski.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
20832dc76bSMariusz Zaborski.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
21832dc76bSMariusz Zaborski.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
22832dc76bSMariusz Zaborski.\" SUCH DAMAGE.
23832dc76bSMariusz Zaborski.\"
24cf037972SAlan Somers.Dd December 6, 2023
25832dc76bSMariusz Zaborski.Dt CAP_NET 3
26832dc76bSMariusz Zaborski.Os
27832dc76bSMariusz Zaborski.Sh NAME
28832dc76bSMariusz Zaborski.Nm cap_bind ,
29832dc76bSMariusz Zaborski.Nm cap_connect ,
30832dc76bSMariusz Zaborski.Nm cap_getaddrinfo ,
31832dc76bSMariusz Zaborski.Nm cap_gethostbyaddr ,
32832dc76bSMariusz Zaborski.Nm cap_gethostbyname ,
33832dc76bSMariusz Zaborski.Nm cap_gethostbyname2 ,
34832dc76bSMariusz Zaborski.Nm cap_getnameinfo ,
35832dc76bSMariusz Zaborski.Nm cap_net_free ,
36832dc76bSMariusz Zaborski.Nm cap_net_limit ,
37832dc76bSMariusz Zaborski.Nm cap_net_limit_addr2name ,
38832dc76bSMariusz Zaborski.Nm cap_net_limit_addr2name_family ,
39832dc76bSMariusz Zaborski.Nm cap_net_limit_bind ,
40832dc76bSMariusz Zaborski.Nm cap_net_limit_connect ,
41832dc76bSMariusz Zaborski.Nm cap_net_limit_init ,
42832dc76bSMariusz Zaborski.Nm cap_net_limit_name2addr ,
43832dc76bSMariusz Zaborski.Nm cap_net_limit_name2addr_family ,
44832dc76bSMariusz Zaborski.Nd "library for networking in capability mode"
45832dc76bSMariusz Zaborski.Sh LIBRARY
46832dc76bSMariusz Zaborski.Lb libcap_net
47832dc76bSMariusz Zaborski.Sh SYNOPSIS
48832dc76bSMariusz Zaborski.In sys/nv.h
49832dc76bSMariusz Zaborski.In libcasper.h
50832dc76bSMariusz Zaborski.In casper/cap_net.h
51832dc76bSMariusz Zaborski.Ft int
52832dc76bSMariusz Zaborski.Fn cap_bind "cap_channel_t *chan" "int s" "const struct sockaddr *addr" "socklen_t addrlen"
53832dc76bSMariusz Zaborski.Ft int
54832dc76bSMariusz Zaborski.Fn cap_connect "cap_channel_t *chan" "int s" "const struct sockaddr *name" "socklen_t namelen"
55832dc76bSMariusz Zaborski.Ft int
56832dc76bSMariusz Zaborski.Fn cap_getaddrinfo "cap_channel_t *chan" "const char *hostname" "const char *servname" "const struct addrinfo *hints" "struct addrinfo **res"
57832dc76bSMariusz Zaborski.Ft int
58832dc76bSMariusz Zaborski.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"
59832dc76bSMariusz Zaborski.Ft "struct hostent *"
60832dc76bSMariusz Zaborski.Fn cap_gethostbyname "const cap_channel_t *chan" "const char *name"
61832dc76bSMariusz Zaborski.Ft "struct hostent *"
62832dc76bSMariusz Zaborski.Fn cap_gethostbyname2 "const cap_channel_t *chan" "const char *name" "int af"
63832dc76bSMariusz Zaborski.Ft "struct hostent *"
64832dc76bSMariusz Zaborski.Fn cap_gethostbyaddr "const cap_channel_t *chan" "const void *addr" "socklen_t len" "int af"
65832dc76bSMariusz Zaborski.Ft "cap_net_limit_t *"
66832dc76bSMariusz Zaborski.Fn cap_net_limit_init "cap_channel_t *chan" "uint64_t mode"
67832dc76bSMariusz Zaborski.Ft int
68832dc76bSMariusz Zaborski.Fn cap_net_limit "cap_net_limit_t *limit"
69832dc76bSMariusz Zaborski.Ft void
70832dc76bSMariusz Zaborski.Fn cap_net_free "cap_net_limit_t *limit"
71832dc76bSMariusz Zaborski.Ft "cap_net_limit_t *"
72832dc76bSMariusz Zaborski.Fn cap_net_limit_addr2name_family "cap_net_limit_t *limit" "int *family" "size_t size"
73832dc76bSMariusz Zaborski.Ft "cap_net_limit_t *"
74832dc76bSMariusz Zaborski.Fn cap_net_limit_addr2name "cap_net_limit_t *limit" "const struct sockaddr *sa" "socklen_t salen"
75832dc76bSMariusz Zaborski.Ft "cap_net_limit_t *"
76832dc76bSMariusz Zaborski.Fn cap_net_limit_name2addr_family "cap_net_limit_t *limit" "int *family" "size_t size"
77832dc76bSMariusz Zaborski.Ft "cap_net_limit_t *"
78832dc76bSMariusz Zaborski.Fn cap_net_limit_name2addr "cap_net_limit_t *limit" "const char *name" "const char *serv"
79832dc76bSMariusz Zaborski.Ft "cap_net_limit_t *"
80832dc76bSMariusz Zaborski.Fn cap_net_limit_connect "cap_net_limit_t *limit" "const struct sockaddr *sa" "socklen_t salen"
81832dc76bSMariusz Zaborski.Ft "cap_net_limit_t *"
82832dc76bSMariusz Zaborski.Fn cap_net_limit_bind "cap_net_limit_t *limit" "const struct sockaddr *sa" "socklen_t salen"
83832dc76bSMariusz Zaborski.Sh DESCRIPTION
84832dc76bSMariusz ZaborskiThe functions
85832dc76bSMariusz Zaborski.Fn cap_bind ,
86832dc76bSMariusz Zaborski.Fn cap_connect ,
87cf037972SAlan Somers.Fn cap_getaddrinfo ,
88cf037972SAlan Somers.Fn cap_getnameinfo ,
89832dc76bSMariusz Zaborski.Fn cap_gethostbyname ,
90832dc76bSMariusz Zaborski.Fn cap_gethostbyname2 ,
91832dc76bSMariusz Zaborskiand
92cf037972SAlan Somers.Fn cap_gethostbyaddr
93406feaa8SGeorge V. Neville-Neilprovide a set of APIs equivalent to
94832dc76bSMariusz Zaborski.Xr bind 2 ,
95832dc76bSMariusz Zaborski.Xr connect 2 ,
96cf037972SAlan Somers.Xr getaddrinfo 3 ,
97cf037972SAlan Somers.Xr getnameinfo 3 ,
98832dc76bSMariusz Zaborski.Xr gethostbyname 3 ,
99832dc76bSMariusz Zaborski.Xr gethostbyname2 3 ,
100832dc76bSMariusz Zaborskiand
101cf037972SAlan Somers.Xr gethostbyaddr 3
102406feaa8SGeorge V. Neville-Neilexcept that a connection to the
103832dc76bSMariusz Zaborski.Nm system.net
104832dc76bSMariusz Zaborskiservice needs to be provided.
105cf037972SAlan Somers.Pp
106cf037972SAlan SomersThese functions, as well as
107cf037972SAlan Somers.Fn cap_net_limit ,
108cf037972SAlan Somersare reentrant but not thread-safe.
109cf037972SAlan SomersThat is, they may be called from separate threads only with different
110cf037972SAlan Somers.Vt cap_channel_t
111cf037972SAlan Somersarguments or with synchronization.
112832dc76bSMariusz Zaborski.Sh LIMITS
113832dc76bSMariusz ZaborskiBy default, the cap_net capability provides unrestricted access to the network
114832dc76bSMariusz Zaborskinamespace.
115832dc76bSMariusz ZaborskiApplications typically only require access to a small portion of the network
116832dc76bSMariusz Zaborskinamespace:
117406feaa8SGeorge V. Neville-NeilThe
118832dc76bSMariusz Zaborski.Fn cap_net_limit
119406feaa8SGeorge V. Neville-Neilfunction can be used to restrict access to the network.
120406feaa8SGeorge V. Neville-NeilThe
121832dc76bSMariusz Zaborski.Fn cap_net_limit_init
122832dc76bSMariusz Zaborskireturns an opaque limit handle used to store a list of capabilities.
123832dc76bSMariusz ZaborskiThe
124832dc76bSMariusz Zaborski.Fv mode
125832dc76bSMariusz Zaborskirestricts the functionality of the service.
126832dc76bSMariusz ZaborskiModes are encoded using the following flags:
127832dc76bSMariusz Zaborski.Pp
128832dc76bSMariusz Zaborski.Bd -literal -offset indent -compact
129832dc76bSMariusz ZaborskiCAPNET_ADDR2NAME		reverse DNS lookups are allowed with
130832dc76bSMariusz Zaborski				cap_getnameinfo
131832dc76bSMariusz ZaborskiCAPNET_NAME2ADDR		name resolution is allowed with
132832dc76bSMariusz Zaborski				cap_getaddrinfo
133832dc76bSMariusz ZaborskiCAPNET_DEPRECATED_ADDR2NAME	reverse DNS lookups are allowed with
134832dc76bSMariusz Zaborski				cap_gethostbyaddr
135832dc76bSMariusz ZaborskiCAPNET_DEPRECATED_NAME2ADDR	name resolution is allowed with
136832dc76bSMariusz Zaborski				cap_gethostbyname and cap_gethostbyname2
137832dc76bSMariusz ZaborskiCAPNET_BIND			bind syscall is allowed
138832dc76bSMariusz ZaborskiCAPNET_CONNECT			connect syscall is allowed
139832dc76bSMariusz ZaborskiCAPNET_CONNECTDNS		connect syscall is allowed to the values
1401723e7f3SShawn Webb				returned from previous call to
141832dc76bSMariusz Zaborski				the cap_getaddrinfo or cap_gethostbyname
142832dc76bSMariusz Zaborski.Ed
143832dc76bSMariusz Zaborski.Pp
144832dc76bSMariusz Zaborski.Fn cap_net_limit_addr2name_family
145832dc76bSMariusz Zaborskilimits the
146832dc76bSMariusz Zaborski.Fn cap_getnameinfo
147832dc76bSMariusz Zaborskiand
148832dc76bSMariusz Zaborski.Fn cap_gethostbyaddr
149832dc76bSMariusz Zaborskito do reverse DNS lookups to specific family (AF_INET, AF_INET6, etc.)
150832dc76bSMariusz Zaborski.Pp
151832dc76bSMariusz Zaborski.Fn cap_net_limit_addr2name
152832dc76bSMariusz Zaborskilimits the
153832dc76bSMariusz Zaborski.Fn cap_getnameinfo
154832dc76bSMariusz Zaborskiand
155832dc76bSMariusz Zaborski.Fn cap_gethostbyaddr
156832dc76bSMariusz Zaborskito do reverse DNS lookups only on those specific structures.
157832dc76bSMariusz Zaborski.Pp
158832dc76bSMariusz Zaborski.Fn cap_net_limit_name2addr_family
159832dc76bSMariusz Zaborskilimits the
160832dc76bSMariusz Zaborski.Fn cap_getaddrinfo ,
161832dc76bSMariusz Zaborski.Fn cap_gethostbyname
162832dc76bSMariusz Zaborskiand
163832dc76bSMariusz Zaborski.Fn cap_gethostbyname2
164832dc76bSMariusz Zaborskito do the name resolution on specific family (AF_INET, AF_INET6, etc.)
165832dc76bSMariusz Zaborski.Pp
166832dc76bSMariusz Zaborski.Fn cap_net_limit_addr2name
167832dc76bSMariusz Zaborskirestricts
168832dc76bSMariusz Zaborski.Fn cap_getaddrinfo ,
169832dc76bSMariusz Zaborski.Fn cap_gethostbyname
170832dc76bSMariusz Zaborskiand
171832dc76bSMariusz Zaborski.Fn cap_gethostbyname2
172832dc76bSMariusz Zaborskito a set of domains.
173832dc76bSMariusz Zaborski.Pp
174832dc76bSMariusz Zaborski.Fn cap_net_limit_bind
175832dc76bSMariusz Zaborskilimits
176832dc76bSMariusz Zaborski.Fn cap_bind
177832dc76bSMariusz Zaborskito bind only on those specific structures.
178832dc76bSMariusz Zaborski.Pp
179832dc76bSMariusz Zaborski.Fn cap_net_limit_connect
180832dc76bSMariusz Zaborskilimits
181832dc76bSMariusz Zaborski.Fn cap_connect
182832dc76bSMariusz Zaborskito connect only on those specific structures.
183832dc76bSMariusz ZaborskiIf the CAPNET_CONNECTDNS is set the limits are extended to the values returned
184832dc76bSMariusz Zaborskiby
185832dc76bSMariusz Zaborski.Fn cap_getaddrinfo ,
186832dc76bSMariusz Zaborski.Fn cap_gethostbyname
187832dc76bSMariusz Zaborskiand
188832dc76bSMariusz Zaborski.Fn cap_gethostbyname2
189832dc76bSMariusz ZaborskiIn case of the
190832dc76bSMariusz Zaborski.Fn cap_getaddrinfo
191832dc76bSMariusz Zaborskithe restriction is strict.
192832dc76bSMariusz ZaborskiIn case of the
193832dc76bSMariusz Zaborski.Fn cap_gethostbyname
194832dc76bSMariusz Zaborskiand
195832dc76bSMariusz Zaborski.Fn cap_gethostbyname2
196832dc76bSMariusz Zaborskiany port will be accepted in the
197832dc76bSMariusz Zaborski.Fn cap_connect
198832dc76bSMariusz Zaborskifunction.
199832dc76bSMariusz Zaborski.Pp
2006b96125aSAlan SomersThe
201832dc76bSMariusz Zaborski.Fn cap_net_limit
2026b96125aSAlan Somerswill consume and apply the limits.
203832dc76bSMariusz Zaborski.Pp
204832dc76bSMariusz ZaborskiOnce a set of limits is applied, subsequent calls to
205832dc76bSMariusz Zaborski.Fn cap_net_limit
206832dc76bSMariusz Zaborskiwill fail unless the new set is a subset of the current set.
207832dc76bSMariusz Zaborski.Pp
208832dc76bSMariusz ZaborskiIf the
209832dc76bSMariusz Zaborski.Fn cap_net_limit
210832dc76bSMariusz Zaborskiwas not called the rights may be freed using
211832dc76bSMariusz Zaborski.Fn cap_net_free .
212832dc76bSMariusz ZaborskiMultiple calls to
213832dc76bSMariusz Zaborski.Fn cap_net_limit_addr2name_family ,
214832dc76bSMariusz Zaborski.Fn cap_net_limit_addr2name ,
215832dc76bSMariusz Zaborski.Fn cap_net_limit_name2addr_family ,
216832dc76bSMariusz Zaborski.Fn cap_net_limit_name2addr ,
217832dc76bSMariusz Zaborski.Fn cap_net_limit_connect ,
218832dc76bSMariusz Zaborskiand
219832dc76bSMariusz Zaborski.Fn cap_net_limit_bind
220832dc76bSMariusz Zaborskiis supported, each call is extending preview capabilities.
221832dc76bSMariusz Zaborski.Sh EXAMPLES
222832dc76bSMariusz ZaborskiThe following example first opens a capability to casper and then uses this
223832dc76bSMariusz Zaborskicapability to create the
224832dc76bSMariusz Zaborski.Nm system.net
225832dc76bSMariusz Zaborskicasper service and uses it to resolve a host and connect to it.
226832dc76bSMariusz Zaborski.Bd -literal
227832dc76bSMariusz Zaborskicap_channel_t *capcas, *capnet;
228832dc76bSMariusz Zaborskicap_net_limit_t *limit;
229832dc76bSMariusz Zaborskiint familylimit, error, s;
230832dc76bSMariusz Zaborskiconst char *host = "example.com";
231832dc76bSMariusz Zaborskistruct addrinfo hints, *res;
232832dc76bSMariusz Zaborski
233832dc76bSMariusz Zaborski/* Open capability to Casper. */
234832dc76bSMariusz Zaborskicapcas = cap_init();
235832dc76bSMariusz Zaborskiif (capcas == NULL)
236832dc76bSMariusz Zaborski	err(1, "Unable to contact Casper");
237832dc76bSMariusz Zaborski
238832dc76bSMariusz Zaborski/* Cache NLA for gai_strerror. */
239832dc76bSMariusz Zaborskicaph_cache_catpages();
240832dc76bSMariusz Zaborski
241832dc76bSMariusz Zaborski/* Enter capability mode sandbox. */
242832dc76bSMariusz Zaborskiif (caph_enter_casper() < 0)
243832dc76bSMariusz Zaborski	err(1, "Unable to enter capability mode");
244832dc76bSMariusz Zaborski
245832dc76bSMariusz Zaborski/* Use Casper capability to create capability to the system.net service. */
246832dc76bSMariusz Zaborskicapnet = cap_service_open(capcas, "system.net");
247832dc76bSMariusz Zaborskiif (capnet == NULL)
248832dc76bSMariusz Zaborski	err(1, "Unable to open system.net service");
249832dc76bSMariusz Zaborski
250832dc76bSMariusz Zaborski/* Close Casper capability. */
251832dc76bSMariusz Zaborskicap_close(capcas);
252832dc76bSMariusz Zaborski
253832dc76bSMariusz Zaborski/* Limit system.net to reserve IPv4 addresses, to host example.com . */
254832dc76bSMariusz Zaborskilimit = cap_net_limit_init(capnet, CAPNET_NAME2ADDR | CAPNET_CONNECTDNS);
255832dc76bSMariusz Zaborskiif (limit == NULL)
256832dc76bSMariusz Zaborski	err(1, "Unable to create limits.");
257832dc76bSMariusz Zaborskicap_net_limit_name2addr(limit, host, "80");
258832dc76bSMariusz Zaborskifamilylimit = AF_INET;
259832dc76bSMariusz Zaborskicap_net_limit_name2addr_family(limit, &familylimit, 1);
260832dc76bSMariusz Zaborskiif (cap_net_limit(limit) < 0)
261832dc76bSMariusz Zaborski	err(1, "Unable to apply limits.");
262832dc76bSMariusz Zaborski
263832dc76bSMariusz Zaborski/* Find IP addresses for the given host. */
264832dc76bSMariusz Zaborskimemset(&hints, 0, sizeof(hints));
265832dc76bSMariusz Zaborskihints.ai_family = AF_INET;
266832dc76bSMariusz Zaborskihints.ai_socktype = SOCK_STREAM;
267832dc76bSMariusz Zaborski
268832dc76bSMariusz Zaborskierror = cap_getaddrinfo(capnet, host, "80", &hints, &res);
269832dc76bSMariusz Zaborskiif (error != 0)
270832dc76bSMariusz Zaborski	errx(1, "cap_getaddrinfo(): %s: %s", host, gai_strerror(error));
271832dc76bSMariusz Zaborski
272832dc76bSMariusz Zaborskis = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
273832dc76bSMariusz Zaborskiif (s < 0)
274832dc76bSMariusz Zaborski	err(1, "Unable to create socket");
275832dc76bSMariusz Zaborski
276832dc76bSMariusz Zaborskiif (cap_connect(capnet, s, res->ai_addr,  res->ai_addrlen) < 0)
277832dc76bSMariusz Zaborski	err(1, "Unable to connect to host");
278832dc76bSMariusz Zaborski.Ed
279832dc76bSMariusz Zaborski.Sh SEE ALSO
280832dc76bSMariusz Zaborski.Xr bind 2 ,
281832dc76bSMariusz Zaborski.Xr cap_enter 2 ,
282832dc76bSMariusz Zaborski.Xr connect 2 ,
283832dc76bSMariusz Zaborski.Xr caph_enter 3 ,
284832dc76bSMariusz Zaborski.Xr err 3 ,
285832dc76bSMariusz Zaborski.Xr gethostbyaddr 3 ,
286832dc76bSMariusz Zaborski.Xr gethostbyname 3 ,
287832dc76bSMariusz Zaborski.Xr gethostbyname2 3 ,
288832dc76bSMariusz Zaborski.Xr getnameinfo 3 ,
289832dc76bSMariusz Zaborski.Xr capsicum 4 ,
290832dc76bSMariusz Zaborski.Xr nv 9
291832dc76bSMariusz Zaborski.Sh AUTHORS
292832dc76bSMariusz Zaborski.An Mariusz Zaborski Aq Mt oshogbo@FreeBSD.org
293