Absolute File Name: | /home/opencoverage/opencoverage/guest-scripts/openssh/src/canohost.c |
Source code | Switch to Preprocessed file |
Line | Source | Count | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | /* $OpenBSD: canohost.c,v 1.73 2016/03/07 19:02:43 djm Exp $ */ | - | ||||||||||||
2 | /* | - | ||||||||||||
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | - | ||||||||||||
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | - | ||||||||||||
5 | * All rights reserved | - | ||||||||||||
6 | * Functions for returning the canonical host name of the remote site. | - | ||||||||||||
7 | * | - | ||||||||||||
8 | * As far as I am concerned, the code I have written for this software | - | ||||||||||||
9 | * can be used freely for any purpose. Any derived versions of this | - | ||||||||||||
10 | * software must be clearly marked as such, and if the derived work is | - | ||||||||||||
11 | * incompatible with the protocol description in the RFC file, it must be | - | ||||||||||||
12 | * called by a name other than "ssh" or "Secure Shell". | - | ||||||||||||
13 | */ | - | ||||||||||||
14 | - | |||||||||||||
15 | #include "includes.h" | - | ||||||||||||
16 | - | |||||||||||||
17 | #include <sys/types.h> | - | ||||||||||||
18 | #include <sys/socket.h> | - | ||||||||||||
19 | #include <sys/un.h> | - | ||||||||||||
20 | - | |||||||||||||
21 | #include <netinet/in.h> | - | ||||||||||||
22 | #include <arpa/inet.h> | - | ||||||||||||
23 | - | |||||||||||||
24 | #include <errno.h> | - | ||||||||||||
25 | #include <netdb.h> | - | ||||||||||||
26 | #include <stdio.h> | - | ||||||||||||
27 | #include <stdlib.h> | - | ||||||||||||
28 | #include <string.h> | - | ||||||||||||
29 | #include <stdarg.h> | - | ||||||||||||
30 | #include <unistd.h> | - | ||||||||||||
31 | - | |||||||||||||
32 | #include "xmalloc.h" | - | ||||||||||||
33 | #include "packet.h" | - | ||||||||||||
34 | #include "log.h" | - | ||||||||||||
35 | #include "canohost.h" | - | ||||||||||||
36 | #include "misc.h" | - | ||||||||||||
37 | - | |||||||||||||
38 | void | - | ||||||||||||
39 | ipv64_normalise_mapped(struct sockaddr_storage *addr, socklen_t *len) | - | ||||||||||||
40 | { | - | ||||||||||||
41 | struct sockaddr_in6 *a6 = (struct sockaddr_in6 *)addr; | - | ||||||||||||
42 | struct sockaddr_in *a4 = (struct sockaddr_in *)addr; | - | ||||||||||||
43 | struct in_addr inaddr; | - | ||||||||||||
44 | u_int16_t port; | - | ||||||||||||
45 | - | |||||||||||||
46 | if (addr->ss_family != AF_INET6 ||
| 0 | ||||||||||||
47 | !IN6_IS_ADDR_V4MAPPED(&a6->sin6_addr))
| 0 | ||||||||||||
48 | return; never executed: return; | 0 | ||||||||||||
49 | - | |||||||||||||
50 | debug3("Normalising mapped IPv4 in IPv6 address"); | - | ||||||||||||
51 | - | |||||||||||||
52 | memcpy(&inaddr, ((char *)&a6->sin6_addr) + 12, sizeof(inaddr)); | - | ||||||||||||
53 | port = a6->sin6_port; | - | ||||||||||||
54 | - | |||||||||||||
55 | memset(a4, 0, sizeof(*a4)); | - | ||||||||||||
56 | - | |||||||||||||
57 | a4->sin_family = AF_INET; | - | ||||||||||||
58 | *len = sizeof(*a4); | - | ||||||||||||
59 | memcpy(&a4->sin_addr, &inaddr, sizeof(inaddr)); | - | ||||||||||||
60 | a4->sin_port = port; | - | ||||||||||||
61 | } never executed: end of block | 0 | ||||||||||||
62 | - | |||||||||||||
63 | /* | - | ||||||||||||
64 | * Returns the local/remote IP-address/hostname of socket as a string. | - | ||||||||||||
65 | * The returned string must be freed. | - | ||||||||||||
66 | */ | - | ||||||||||||
67 | static char * | - | ||||||||||||
68 | get_socket_address(int sock, int remote, int flags) | - | ||||||||||||
69 | { | - | ||||||||||||
70 | struct sockaddr_storage addr; | - | ||||||||||||
71 | socklen_t addrlen; | - | ||||||||||||
72 | char ntop[NI_MAXHOST]; | - | ||||||||||||
73 | int r; | - | ||||||||||||
74 | - | |||||||||||||
75 | /* Get IP address of client. */ | - | ||||||||||||
76 | addrlen = sizeof(addr); | - | ||||||||||||
77 | memset(&addr, 0, sizeof(addr)); | - | ||||||||||||
78 | - | |||||||||||||
79 | if (remote) {
| 0 | ||||||||||||
80 | if (getpeername(sock, (struct sockaddr *)&addr, &addrlen) != 0)
| 0 | ||||||||||||
81 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||
82 | } else { never executed: end of block | 0 | ||||||||||||
83 | if (getsockname(sock, (struct sockaddr *)&addr, &addrlen) != 0)
| 0 | ||||||||||||
84 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||
85 | } never executed: end of block | 0 | ||||||||||||
86 | - | |||||||||||||
87 | /* Work around Linux IPv6 weirdness */ | - | ||||||||||||
88 | if (addr.ss_family == AF_INET6) {
| 0 | ||||||||||||
89 | addrlen = sizeof(struct sockaddr_in6); | - | ||||||||||||
90 | ipv64_normalise_mapped(&addr, &addrlen); | - | ||||||||||||
91 | } never executed: end of block | 0 | ||||||||||||
92 | - | |||||||||||||
93 | switch (addr.ss_family) { | - | ||||||||||||
94 | case AF_INET: never executed: case 2 : | 0 | ||||||||||||
95 | case AF_INET6: never executed: case 10 : | 0 | ||||||||||||
96 | /* Get the address in ascii. */ | - | ||||||||||||
97 | if ((r = getnameinfo((struct sockaddr *)&addr, addrlen, ntop,
| 0 | ||||||||||||
98 | sizeof(ntop), NULL, 0, flags)) != 0) {
| 0 | ||||||||||||
99 | error("%s: getnameinfo %d failed: %s", __func__, | - | ||||||||||||
100 | flags, ssh_gai_strerror(r)); | - | ||||||||||||
101 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||
102 | } | - | ||||||||||||
103 | return xstrdup(ntop); never executed: return xstrdup(ntop); | 0 | ||||||||||||
104 | case AF_UNIX: never executed: case 1 : | 0 | ||||||||||||
105 | /* Get the Unix domain socket path. */ | - | ||||||||||||
106 | return xstrdup(((struct sockaddr_un *)&addr)->sun_path); never executed: return xstrdup(((struct sockaddr_un *)&addr)->sun_path); | 0 | ||||||||||||
107 | default: never executed: default: | 0 | ||||||||||||
108 | /* We can't look up remote Unix domain sockets. */ | - | ||||||||||||
109 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||
110 | } | - | ||||||||||||
111 | } | - | ||||||||||||
112 | - | |||||||||||||
113 | char * | - | ||||||||||||
114 | get_peer_ipaddr(int sock) | - | ||||||||||||
115 | { | - | ||||||||||||
116 | char *p; | - | ||||||||||||
117 | - | |||||||||||||
118 | if ((p = get_socket_address(sock, 1, NI_NUMERICHOST)) != NULL)
| 0 | ||||||||||||
119 | return p; never executed: return p; | 0 | ||||||||||||
120 | return xstrdup("UNKNOWN"); never executed: return xstrdup("UNKNOWN"); | 0 | ||||||||||||
121 | } | - | ||||||||||||
122 | - | |||||||||||||
123 | char * | - | ||||||||||||
124 | get_local_ipaddr(int sock) | - | ||||||||||||
125 | { | - | ||||||||||||
126 | char *p; | - | ||||||||||||
127 | - | |||||||||||||
128 | if ((p = get_socket_address(sock, 0, NI_NUMERICHOST)) != NULL)
| 0 | ||||||||||||
129 | return p; never executed: return p; | 0 | ||||||||||||
130 | return xstrdup("UNKNOWN"); never executed: return xstrdup("UNKNOWN"); | 0 | ||||||||||||
131 | } | - | ||||||||||||
132 | - | |||||||||||||
133 | char * | - | ||||||||||||
134 | get_local_name(int fd) | - | ||||||||||||
135 | { | - | ||||||||||||
136 | char *host, myname[NI_MAXHOST]; | - | ||||||||||||
137 | - | |||||||||||||
138 | /* Assume we were passed a socket */ | - | ||||||||||||
139 | if ((host = get_socket_address(fd, 0, NI_NAMEREQD)) != NULL)
| 0 | ||||||||||||
140 | return host; never executed: return host; | 0 | ||||||||||||
141 | - | |||||||||||||
142 | /* Handle the case where we were passed a pipe */ | - | ||||||||||||
143 | if (gethostname(myname, sizeof(myname)) == -1) {
| 0 | ||||||||||||
144 | verbose("%s: gethostname: %s", __func__, strerror(errno)); | - | ||||||||||||
145 | host = xstrdup("UNKNOWN"); | - | ||||||||||||
146 | } else { never executed: end of block | 0 | ||||||||||||
147 | host = xstrdup(myname); | - | ||||||||||||
148 | } never executed: end of block | 0 | ||||||||||||
149 | - | |||||||||||||
150 | return host; never executed: return host; | 0 | ||||||||||||
151 | } | - | ||||||||||||
152 | - | |||||||||||||
153 | /* Returns the local/remote port for the socket. */ | - | ||||||||||||
154 | - | |||||||||||||
155 | static int | - | ||||||||||||
156 | get_sock_port(int sock, int local) | - | ||||||||||||
157 | { | - | ||||||||||||
158 | struct sockaddr_storage from; | - | ||||||||||||
159 | socklen_t fromlen; | - | ||||||||||||
160 | char strport[NI_MAXSERV]; | - | ||||||||||||
161 | int r; | - | ||||||||||||
162 | - | |||||||||||||
163 | /* Get IP address of client. */ | - | ||||||||||||
164 | fromlen = sizeof(from); | - | ||||||||||||
165 | memset(&from, 0, sizeof(from)); | - | ||||||||||||
166 | if (local) {
| 0 | ||||||||||||
167 | if (getsockname(sock, (struct sockaddr *)&from, &fromlen) < 0) {
| 0 | ||||||||||||
168 | error("getsockname failed: %.100s", strerror(errno)); | - | ||||||||||||
169 | return 0; never executed: return 0; | 0 | ||||||||||||
170 | } | - | ||||||||||||
171 | } else { never executed: end of block | 0 | ||||||||||||
172 | if (getpeername(sock, (struct sockaddr *)&from, &fromlen) < 0) {
| 0 | ||||||||||||
173 | debug("getpeername failed: %.100s", strerror(errno)); | - | ||||||||||||
174 | return -1; never executed: return -1; | 0 | ||||||||||||
175 | } | - | ||||||||||||
176 | } never executed: end of block | 0 | ||||||||||||
177 | - | |||||||||||||
178 | /* Work around Linux IPv6 weirdness */ | - | ||||||||||||
179 | if (from.ss_family == AF_INET6)
| 0 | ||||||||||||
180 | fromlen = sizeof(struct sockaddr_in6); never executed: fromlen = sizeof(struct sockaddr_in6); | 0 | ||||||||||||
181 | - | |||||||||||||
182 | /* Non-inet sockets don't have a port number. */ | - | ||||||||||||
183 | if (from.ss_family != AF_INET && from.ss_family != AF_INET6)
| 0 | ||||||||||||
184 | return 0; never executed: return 0; | 0 | ||||||||||||
185 | - | |||||||||||||
186 | /* Return port number. */ | - | ||||||||||||
187 | if ((r = getnameinfo((struct sockaddr *)&from, fromlen, NULL, 0,
| 0 | ||||||||||||
188 | strport, sizeof(strport), NI_NUMERICSERV)) != 0)
| 0 | ||||||||||||
189 | fatal("%s: getnameinfo NI_NUMERICSERV failed: %s", __func__, never executed: fatal("%s: getnameinfo NI_NUMERICSERV failed: %s", __func__, ssh_gai_strerror(r)); | 0 | ||||||||||||
190 | ssh_gai_strerror(r)); never executed: fatal("%s: getnameinfo NI_NUMERICSERV failed: %s", __func__, ssh_gai_strerror(r)); | 0 | ||||||||||||
191 | return atoi(strport); never executed: return atoi(strport); | 0 | ||||||||||||
192 | } | - | ||||||||||||
193 | - | |||||||||||||
194 | int | - | ||||||||||||
195 | get_peer_port(int sock) | - | ||||||||||||
196 | { | - | ||||||||||||
197 | return get_sock_port(sock, 0); never executed: return get_sock_port(sock, 0); | 0 | ||||||||||||
198 | } | - | ||||||||||||
199 | - | |||||||||||||
200 | int | - | ||||||||||||
201 | get_local_port(int sock) | - | ||||||||||||
202 | { | - | ||||||||||||
203 | return get_sock_port(sock, 1); never executed: return get_sock_port(sock, 1); | 0 | ||||||||||||
204 | } | - | ||||||||||||
Source code | Switch to Preprocessed file |