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