1.\" Copyright (c) 2018 Mariusz Zaborski <oshogbo@FreeBSD.org>
2.\" All rights reserved.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions
6.\" are met:
7.\" 1. Redistributions of source code must retain the above copyright
8.\"    notice, this list of conditions and the following disclaimer.
9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\"    notice, this list of conditions and the following disclaimer in the
11.\"    documentation and/or other materials provided with the distribution.
12.\"
13.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
14.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
17.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23.\" SUCH DAMAGE.
24.\"
25.\" $FreeBSD$
26.\"
27.Dd April 18, 2020
28.Dt CAP_DNS 3
29.Os
30.Sh NAME
31.Nm cap_getaddrinfo ,
32.Nm cap_getnameinfo ,
33.Nm cap_gethostbyname ,
34.Nm cap_gethostbyname2 ,
35.Nm cap_gethostbyaddr ,
36.Nm cap_dns_type_limit ,
37.Nm cap_dns_family_limit
38.Nd "library for getting network host entry in capability mode"
39.Sh LIBRARY
40.Lb libcap_dns
41.Sh SYNOPSIS
42.In sys/nv.h
43.In libcasper.h
44.In casper/cap_dns.h
45.Ft int
46.Fn cap_getaddrinfo "cap_channel_t *chan" "const char *hostname" "const char *servname" "const struct addrinfo *hints" "struct addrinfo **res"
47.Ft int
48.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"
49.Ft "struct hostent *"
50.Fn cap_gethostbyname "const cap_channel_t *chan" "const char *name"
51.Ft "struct hostent *"
52.Fn cap_gethostbyname2 "const cap_channel_t *chan" "const char *name" "int af"
53.Ft "struct hostent *"
54.Fn cap_gethostbyaddr "const cap_channel_t *chan" "const void *addr" "socklen_t len" "int af"
55.Ft "int"
56.Fn cap_dns_type_limit "cap_channel_t *chan" "const char * const *types" "size_t ntypes"
57.Ft "int"
58.Fn cap_dns_family_limit "const cap_channel_t *chan" "const int *families" "size_t nfamilies"
59.Sh DESCRIPTION
60.Bf -symbolic
61The
62.Fn cap_getaddrinfo ,
63and
64.Fn cap_getnameinfo ,
65functions are preferred over the
66.Fn cap_gethostbyname ,
67.Fn cap_gethostbyname2 ,
68and
69.Fn cap_gethostbyaddr
70functions.
71.Ef
72.Pp
73The functions
74.Fn cap_gethostbyname ,
75.Fn cap_gethostbyname2 ,
76.Fn cep_gethostbyaddr
77and
78.Fn cap_getnameinfo
79are respectively equivalent to
80.Xr gethostbyname 3 ,
81.Xr gethostbyname2 3 ,
82.Xr gethostbyaddr 3
83and
84.Xr getnameinfo 3
85except that the connection to the
86.Nm system.dns
87service needs to be provided.
88.Pp
89The
90.Fn cap_dns_type_limit
91function limits the functions allowed in the service.
92The
93.Fa types
94variable can be set to
95.Dv ADDR2NAME
96or
97.Dv NAME2ADDR .
98See the
99.Sx LIMITS
100section for more details.
101The
102.Fa ntpyes
103variable contains the number of
104.Fa types
105provided.
106.Pp
107The
108.Fn cap_dns_family_limit
109functions allows to limit address families.
110For details see
111.Sx LIMITS .
112The
113.Fa nfamilies
114variable contains the number of
115.Fa families
116provided.
117.Sh LIMITS
118The preferred way of setting limits is to use the
119.Fn cap_dns_type_limit
120and
121.Fn cap_dns_family_limit
122functions, but the limits of service can be set also using
123.Xr cap_limit_set 3 .
124The
125.Xr nvlist 9
126for that function can contain the following values and types:
127.Bl -ohang -offset indent
128.It type ( NV_TYPE_STRING )
129The
130.Va type
131can have two values:
132.Dv ADDR2NAME
133or
134.Dv NAME2ADDR .
135The
136.Dv ADDR2NAME
137means that reverse DNS lookups are allowed with
138.Fn cap_getnameinfo
139and
140.Fn cap_gethostbyaddr
141functions.
142In case when
143.Va type
144is set to
145.Dv NAME2ADDR
146the name resolution is allowed with
147.Fn cap_getaddrinfo ,
148.Fn cap_gethostbyname ,
149and
150.Fn cap_gethostbyname2
151functions.
152.It family ( NV_TYPE_NUMBER )
153The
154.Va family
155limits service to one of the address families (e.g.
156.Dv AF_INET , AF_INET6 ,
157etc.).
158.Sh EXAMPLES
159The following example first opens a capability to casper and then uses this
160capability to create the
161.Nm system.dns
162casper service and uses it to resolve an IP address.
163.Bd -literal
164cap_channel_t *capcas, *capdns;
165int familylimit, error;
166const char *ipstr = "127.0.0.1";
167const char *typelimit = "ADDR2NAME";
168char hname[NI_MAXHOST];
169struct addrinfo hints, *res;
170
171/* Open capability to Casper. */
172capcas = cap_init();
173if (capcas == NULL)
174	err(1, "Unable to contact Casper");
175
176/* Cache NLA for gai_strerror. */
177caph_cache_catpages();
178
179/* Enter capability mode sandbox. */
180if (caph_enter() < 0)
181	err(1, "Unable to enter capability mode");
182
183/* Use Casper capability to create capability to the system.dns service. */
184capdns = cap_service_open(capcas, "system.dns");
185if (capdns == NULL)
186	err(1, "Unable to open system.dns service");
187
188/* Close Casper capability, we don't need it anymore. */
189cap_close(capcas);
190
191/* Limit system.dns to reserve IPv4 addresses */
192familylimit = AF_INET;
193if (cap_dns_family_limit(capdns, &familylimit, 1) < 0)
194	err(1, "Unable to limit access to the system.dns service");
195
196/* Convert IP address in C-string to struct sockaddr. */
197memset(&hints, 0, sizeof(hints));
198hints.ai_family = familylimit;
199hints.ai_flags = AI_NUMERICHOST;
200error = cap_getaddrinfo(capdns, ipstr, NULL, &hints, &res);
201if (error != 0)
202       errx(1, "cap_getaddrinfo(): %s: %s", ipstr, gai_strerror(error));
203
204/* Limit system.dns to reverse DNS lookups. */
205if (cap_dns_type_limit(capdns, &typelimit, 1) < 0)
206	err(1, "Unable to limit access to the system.dns service");
207
208/* Find hostname for the given IP address. */
209error = cap_getnameinfo(capdns, res->ai_addr, res->ai_addrlen, hname, sizeof(hname),
210    NULL, 0, 0);
211if (error != 0)
212	errx(1, "cap_getnameinfo(): %s: %s", ipstr, gai_strerror(error));
213
214printf("Name associated with %s is %s.\\n", ipstr, hname);
215.Ed
216.Sh SEE ALSO
217.Xr cap_enter 2 ,
218.Xr caph_enter 3 ,
219.Xr err 3 ,
220.Xr gethostbyaddr 3 ,
221.Xr gethostbyname 3 ,
222.Xr gethostbyname2 3 ,
223.Xr getnameinfo 3 ,
224.Xr capsicum 4 ,
225.Xr nv 9
226.Sh AUTHORS
227The
228.Nm cap_dns
229service was implemented by
230.An Pawel Jakub Dawidek Aq Mt pawel@dawidek.net
231under sponsorship from the FreeBSD Foundation.
232.Pp
233This manual page was written by
234.An Mariusz Zaborski Aq Mt oshogbo@FreeBSD.org .
235