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 December 5, 2023 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 191The 192.Fn cap_net_limit 193will consume and apply the limits. 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 199If the 200.Fn cap_net_limit 201was not called the rights may be freed using 202.Fn cap_net_free . 203Multiple calls to 204.Fn cap_net_limit_addr2name_family , 205.Fn cap_net_limit_addr2name , 206.Fn cap_net_limit_name2addr_family , 207.Fn cap_net_limit_name2addr , 208.Fn cap_net_limit_connect , 209and 210.Fn cap_net_limit_bind 211is supported, each call is extending preview capabilities. 212.Sh EXAMPLES 213The following example first opens a capability to casper and then uses this 214capability to create the 215.Nm system.net 216casper service and uses it to resolve a host and connect to it. 217.Bd -literal 218cap_channel_t *capcas, *capnet; 219cap_net_limit_t *limit; 220int familylimit, error, s; 221const char *host = "example.com"; 222struct addrinfo hints, *res; 223 224/* Open capability to Casper. */ 225capcas = cap_init(); 226if (capcas == NULL) 227 err(1, "Unable to contact Casper"); 228 229/* Cache NLA for gai_strerror. */ 230caph_cache_catpages(); 231 232/* Enter capability mode sandbox. */ 233if (caph_enter_casper() < 0) 234 err(1, "Unable to enter capability mode"); 235 236/* Use Casper capability to create capability to the system.net service. */ 237capnet = cap_service_open(capcas, "system.net"); 238if (capnet == NULL) 239 err(1, "Unable to open system.net service"); 240 241/* Close Casper capability. */ 242cap_close(capcas); 243 244/* Limit system.net to reserve IPv4 addresses, to host example.com . */ 245limit = cap_net_limit_init(capnet, CAPNET_NAME2ADDR | CAPNET_CONNECTDNS); 246if (limit == NULL) 247 err(1, "Unable to create limits."); 248cap_net_limit_name2addr(limit, host, "80"); 249familylimit = AF_INET; 250cap_net_limit_name2addr_family(limit, &familylimit, 1); 251if (cap_net_limit(limit) < 0) 252 err(1, "Unable to apply limits."); 253 254/* Find IP addresses for the given host. */ 255memset(&hints, 0, sizeof(hints)); 256hints.ai_family = AF_INET; 257hints.ai_socktype = SOCK_STREAM; 258 259error = cap_getaddrinfo(capnet, host, "80", &hints, &res); 260if (error != 0) 261 errx(1, "cap_getaddrinfo(): %s: %s", host, gai_strerror(error)); 262 263s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); 264if (s < 0) 265 err(1, "Unable to create socket"); 266 267if (cap_connect(capnet, s, res->ai_addr, res->ai_addrlen) < 0) 268 err(1, "Unable to connect to host"); 269.Ed 270.Sh SEE ALSO 271.Xr bind 2 , 272.Xr cap_enter 2 , 273.Xr connect 2 , 274.Xr caph_enter 3 , 275.Xr err 3 , 276.Xr gethostbyaddr 3 , 277.Xr gethostbyname 3 , 278.Xr gethostbyname2 3 , 279.Xr getnameinfo 3 , 280.Xr capsicum 4 , 281.Xr nv 9 282.Sh AUTHORS 283.An Mariusz Zaborski Aq Mt oshogbo@FreeBSD.org 284