Skip to content

Commit

Permalink
change resolve_host to 'resolve' unix sockets
Browse files Browse the repository at this point in the history
  • Loading branch information
oliverkurth committed Sep 2, 2023
1 parent 9207892 commit a87def5
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 10 deletions.
3 changes: 2 additions & 1 deletion hostfile.c
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,8 @@ write_host_entry(FILE *f, const char *host, const char *ip,
char *hashed_host = NULL, *lhost;

lhost = xstrdup(host);
lowercase(lhost);
if (host[0] != '/')
lowercase(lhost);

if (store_hash) {
if ((hashed_host = host_hash(lhost, NULL, 0)) == NULL) {
Expand Down
3 changes: 3 additions & 0 deletions misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,9 @@ set_sock_tos(int fd, int tos)
}
# endif /* IPV6_TCLASS */
break;
case AF_UNIX:
debug3_f("no tos for unix socket")
break;
default:
debug2_f("unsupported socket family %d", af);
break;
Expand Down
45 changes: 41 additions & 4 deletions ssh.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <sys/un.h>

#include <ctype.h>
#include <errno.h>
Expand Down Expand Up @@ -257,6 +258,31 @@ resolve_host(const char *name, int port, int logerr, char *cname, size_t clen)
int gaierr;
LogLevel loglevel = SYSLOG_LEVEL_DEBUG1;

if (name[0] == '/') {
struct sockaddr_un *sunaddr;

if (strlen(name) > sizeof(sunaddr->sun_path)) {
error("%.100s: %.100s", name, strerror(ENAMETOOLONG));
}
/*
* Fake up a struct addrinfo for AF_UNIX connections.
* main() must check ai_family
* and use free() not freeaddirinfo() for AF_UNIX.
*/
res = xmalloc(sizeof(*res) + sizeof(*sunaddr));
memset(res, 0, sizeof(*res) + sizeof(*sunaddr));
res->ai_addr = (struct sockaddr *)(res + 1);
res->ai_addrlen = sizeof(*sunaddr);
res->ai_family = AF_UNIX;
res->ai_socktype = SOCK_STREAM;
res->ai_protocol = PF_UNSPEC;
sunaddr = (struct sockaddr_un *)res->ai_addr;
sunaddr->sun_family = AF_UNIX;
strlcpy(sunaddr->sun_path, name, sizeof(sunaddr->sun_path));

return res;
}

if (port <= 0)
port = default_ssh_port();
if (cname != NULL)
Expand Down Expand Up @@ -1182,8 +1208,15 @@ main(int ac, char **av)
options.hostname = xstrdup(host);
}

/* enforce HashKnownHosts for unix sockets (file names) to avoid
corrupting the known_hosts file with reserved characters */
if (host[0] == '/') {
debug("enabling HashKnownHosts for unix socket");
options.hash_known_hosts = 1;
}

/* Don't lowercase addresses, they will be explicitly canonicalised */
if ((was_addr = is_addr(host)) == 0)
if (host[0] != '/' && (was_addr = is_addr(host)) == 0)
lowercase(host);

/*
Expand Down Expand Up @@ -1579,8 +1612,12 @@ main(int ac, char **av)
&timeout_ms, options.tcp_keep_alive) != 0)
exit(255);

if (addrs != NULL)
freeaddrinfo(addrs);
if (addrs != NULL) {
if (addrs->ai_family == AF_UNIX)
free(addrs);
else
freeaddrinfo(addrs);
}

ssh_packet_set_timeout(ssh, options.server_alive_interval,
options.server_alive_count_max);
Expand Down Expand Up @@ -1698,7 +1735,7 @@ main(int ac, char **av)
options.port, pw, timeout_ms, cinfo);

if (ssh_packet_connection_is_on_socket(ssh)) {
if (ssh_packet_connection_af(ssh) == AF_LOCAL) {
if (ssh_packet_connection_af(ssh) == AF_UNIX) {
verbose("Authenticated to %s.", host);
} else {
verbose("Authenticated to %s ([%s]:%d).", host,
Expand Down
17 changes: 12 additions & 5 deletions sshconnect.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
Expand Down Expand Up @@ -453,7 +454,7 @@ ssh_connect_direct(struct ssh *ssh, const char *host, struct addrinfo *aitop,
char ntop[NI_MAXHOST], strport[NI_MAXSERV];
struct addrinfo *ai;

debug3_f("entering");
debug3_f("entering, host=%s", host);
memset(ntop, 0, sizeof(ntop));
memset(strport, 0, sizeof(strport));

Expand All @@ -474,7 +475,7 @@ ssh_connect_direct(struct ssh *ssh, const char *host, struct addrinfo *aitop,
errno = EAFNOSUPPORT;
continue;
}
if (getnameinfo(ai->ai_addr, ai->ai_addrlen,
if (ai->ai_family != AF_UNIX && getnameinfo(ai->ai_addr, ai->ai_addrlen,
ntop, sizeof(ntop), strport, sizeof(strport),
NI_NUMERICHOST|NI_NUMERICSERV) != 0) {
oerrno = errno;
Expand Down Expand Up @@ -627,6 +628,9 @@ get_hostfile_hostname_ipaddr(char *hostname, struct sockaddr *hostaddr,
case AF_INET6:
addrlen = sizeof(struct sockaddr_in6);
break;
case AF_UNIX:
addrlen = sizeof(struct sockaddr_un);
break;
default:
addrlen = sizeof(struct sockaddr);
break;
Expand All @@ -636,7 +640,9 @@ get_hostfile_hostname_ipaddr(char *hostname, struct sockaddr *hostaddr,
* We don't have the remote ip-address for connections
* using a proxy command
*/
if (hostfile_ipaddr != NULL) {
if (hostaddr != NULL &&
hostaddr->sa_family != AF_UNIX &&
hostfile_ipaddr != NULL) {
if (options.proxy_command == NULL) {
if (getnameinfo(hostaddr, addrlen,
ntop, sizeof(ntop), NULL, 0, NI_NUMERICHOST) != 0)
Expand Down Expand Up @@ -1564,7 +1570,8 @@ ssh_login(struct ssh *ssh, Sensitive *sensitive, const char *orighost,

/* Convert the user-supplied hostname into all lowercase. */
host = xstrdup(orighost);
lowercase(host);
if (hostaddr->sa_family != AF_UNIX)
lowercase(host);

/* Exchange protocol version identification strings with the server. */
if ((r = kex_exchange_identification(ssh, timeout_ms, NULL)) != 0)
Expand All @@ -1575,7 +1582,7 @@ ssh_login(struct ssh *ssh, Sensitive *sensitive, const char *orighost,

/* key exchange */
/* authenticate user */
if (hostaddr->sa_family == AF_LOCAL) {
if (hostaddr->sa_family == AF_UNIX) {
debug("Authenticating to %s as '%s'", host, server_user);
} else {
debug("Authenticating to %s:%d as '%s'", host, port,
Expand Down

0 comments on commit a87def5

Please sign in to comment.