9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta/*
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta Authors:
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta Jan Cholasta <jcholast@redhat.com>
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta Copyright (C) 2012 Red Hat
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta This program is free software; you can redistribute it and/or modify
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta it under the terms of the GNU General Public License as published by
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta the Free Software Foundation; either version 3 of the License, or
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta (at your option) any later version.
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta This program is distributed in the hope that it will be useful,
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta but WITHOUT ANY WARRANTY; without even the implied warranty of
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta GNU General Public License for more details.
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta You should have received a copy of the GNU General Public License
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta along with this program. If not, see <http://www.gnu.org/licenses/>.
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta*/
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta#include <stdio.h>
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta#include <talloc.h>
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta#include <unistd.h>
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta#include <fcntl.h>
1e68ae21e7ae46744700753ccf28bcbcaedbe017Jan Cholasta#include <poll.h>
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta#include <sys/types.h>
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta#include <sys/socket.h>
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta#include <netinet/in.h>
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta#include <netinet/tcp.h>
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta#include <netdb.h>
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta#include <popt.h>
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta#include "util/util.h"
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta#include "util/crypto/sss_crypto.h"
748ba184db97b7534254f97018fa04e8aa458faeJan Cholasta#include "util/sss_ssh.h"
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta#include "sss_client/sss_cli.h"
748ba184db97b7534254f97018fa04e8aa458faeJan Cholasta#include "sss_client/ssh/sss_ssh_client.h"
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta#define BUFFER_SIZE 8192
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta
1e68ae21e7ae46744700753ccf28bcbcaedbe017Jan Cholasta/* connect to server using socket */
1e68ae21e7ae46744700753ccf28bcbcaedbe017Jan Cholastastatic int
244adc327f7e29ba2c7ef60bc9f732d8fe3e68c9Simo Sorceconnect_socket(int family, struct sockaddr *addr, size_t addr_len, int *sd)
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta{
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta int flags;
1e68ae21e7ae46744700753ccf28bcbcaedbe017Jan Cholasta int sock = -1;
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta int ret;
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta /* set O_NONBLOCK on standard input */
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta flags = fcntl(0, F_GETFL);
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta if (flags == -1) {
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta ret = errno;
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_OP_FAILURE, "fcntl() failed (%d): %s\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov ret, strerror(ret));
1e68ae21e7ae46744700753ccf28bcbcaedbe017Jan Cholasta goto done;
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta }
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta ret = fcntl(0, F_SETFL, flags | O_NONBLOCK);
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta if (ret == -1) {
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta ret = errno;
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_OP_FAILURE, "fcntl() failed (%d): %s\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov ret, strerror(ret));
1e68ae21e7ae46744700753ccf28bcbcaedbe017Jan Cholasta goto done;
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta }
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta /* create socket */
d0a8981bce0c462bcd4b5db2900c0f29a40a41f0Jan Cholasta sock = socket(family, SOCK_STREAM, IPPROTO_TCP);
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta if (sock == -1) {
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta ret = errno;
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_OP_FAILURE, "socket() failed (%d): %s\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov ret, strerror(ret));
1e68ae21e7ae46744700753ccf28bcbcaedbe017Jan Cholasta goto done;
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta }
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta /* connect to the server */
d0a8981bce0c462bcd4b5db2900c0f29a40a41f0Jan Cholasta ret = connect(sock, addr, addr_len);
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta if (ret == -1) {
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta ret = errno;
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_OP_FAILURE, "connect() failed (%d): %s\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov ret, strerror(ret));
1e68ae21e7ae46744700753ccf28bcbcaedbe017Jan Cholasta goto done;
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta }
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta
244adc327f7e29ba2c7ef60bc9f732d8fe3e68c9Simo Sorce *sd = sock;
244adc327f7e29ba2c7ef60bc9f732d8fe3e68c9Simo Sorce
244adc327f7e29ba2c7ef60bc9f732d8fe3e68c9Simo Sorcedone:
244adc327f7e29ba2c7ef60bc9f732d8fe3e68c9Simo Sorce if (ret != 0 && sock >= 0) close(sock);
244adc327f7e29ba2c7ef60bc9f732d8fe3e68c9Simo Sorce return ret;
244adc327f7e29ba2c7ef60bc9f732d8fe3e68c9Simo Sorce}
244adc327f7e29ba2c7ef60bc9f732d8fe3e68c9Simo Sorce
244adc327f7e29ba2c7ef60bc9f732d8fe3e68c9Simo Sorcestatic int proxy_data(int sock)
244adc327f7e29ba2c7ef60bc9f732d8fe3e68c9Simo Sorce{
244adc327f7e29ba2c7ef60bc9f732d8fe3e68c9Simo Sorce int flags;
244adc327f7e29ba2c7ef60bc9f732d8fe3e68c9Simo Sorce struct pollfd fds[2];
244adc327f7e29ba2c7ef60bc9f732d8fe3e68c9Simo Sorce char buffer[BUFFER_SIZE];
244adc327f7e29ba2c7ef60bc9f732d8fe3e68c9Simo Sorce int i;
244adc327f7e29ba2c7ef60bc9f732d8fe3e68c9Simo Sorce ssize_t res;
244adc327f7e29ba2c7ef60bc9f732d8fe3e68c9Simo Sorce int ret;
244adc327f7e29ba2c7ef60bc9f732d8fe3e68c9Simo Sorce
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta /* set O_NONBLOCK on the socket */
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta flags = fcntl(sock, F_GETFL);
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta if (flags == -1) {
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta ret = errno;
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_OP_FAILURE, "fcntl() failed (%d): %s\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov ret, strerror(ret));
1e68ae21e7ae46744700753ccf28bcbcaedbe017Jan Cholasta goto done;
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta }
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta ret = fcntl(sock, F_SETFL, flags | O_NONBLOCK);
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta if (ret == -1) {
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta ret = errno;
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_OP_FAILURE, "fcntl() failed (%d): %s\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov ret, strerror(ret));
1e68ae21e7ae46744700753ccf28bcbcaedbe017Jan Cholasta goto done;
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta }
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta
1e68ae21e7ae46744700753ccf28bcbcaedbe017Jan Cholasta fds[0].fd = 0;
1e68ae21e7ae46744700753ccf28bcbcaedbe017Jan Cholasta fds[0].events = POLLIN;
1e68ae21e7ae46744700753ccf28bcbcaedbe017Jan Cholasta fds[1].fd = sock;
1e68ae21e7ae46744700753ccf28bcbcaedbe017Jan Cholasta fds[1].events = POLLIN;
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta
1e68ae21e7ae46744700753ccf28bcbcaedbe017Jan Cholasta while (1) {
1e68ae21e7ae46744700753ccf28bcbcaedbe017Jan Cholasta ret = poll(fds, 2, -1);
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta if (ret == -1) {
1e68ae21e7ae46744700753ccf28bcbcaedbe017Jan Cholasta ret = errno;
1e68ae21e7ae46744700753ccf28bcbcaedbe017Jan Cholasta if (ret == EINTR || ret == EAGAIN) {
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta continue;
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta }
e5359baeac6e2d49769aceddbdbc606833b1ec69Jan Cholasta DEBUG(SSSDBG_OP_FAILURE,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "poll() failed (%d): %s\n", ret, strerror(ret));
1e68ae21e7ae46744700753ccf28bcbcaedbe017Jan Cholasta goto done;
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta }
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta /* read from standard input & write to socket */
1e68ae21e7ae46744700753ccf28bcbcaedbe017Jan Cholasta /* read from socket & write to standard output */
1e68ae21e7ae46744700753ccf28bcbcaedbe017Jan Cholasta for (i = 0; i < 2; i++) {
1e68ae21e7ae46744700753ccf28bcbcaedbe017Jan Cholasta if (fds[i].revents & POLLIN) {
1e68ae21e7ae46744700753ccf28bcbcaedbe017Jan Cholasta res = read(fds[i].fd, buffer, BUFFER_SIZE);
1e68ae21e7ae46744700753ccf28bcbcaedbe017Jan Cholasta if (res == -1) {
1e68ae21e7ae46744700753ccf28bcbcaedbe017Jan Cholasta ret = errno;
1e68ae21e7ae46744700753ccf28bcbcaedbe017Jan Cholasta if (ret == EAGAIN || ret == EINTR || ret == EWOULDBLOCK) {
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta continue;
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta }
e5359baeac6e2d49769aceddbdbc606833b1ec69Jan Cholasta DEBUG(SSSDBG_OP_FAILURE,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "read() failed (%d): %s\n", ret, strerror(ret));
1e68ae21e7ae46744700753ccf28bcbcaedbe017Jan Cholasta goto done;
1e68ae21e7ae46744700753ccf28bcbcaedbe017Jan Cholasta } else if (res == 0) {
5ca493af3e24e2cf7299289364cf23ccec9e5d35Jan Cholasta ret = EOK;
5ca493af3e24e2cf7299289364cf23ccec9e5d35Jan Cholasta goto done;
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta }
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta
5ca493af3e24e2cf7299289364cf23ccec9e5d35Jan Cholasta errno = 0;
9d7d4458d94d0aac0a7edf999368eb18f89cb76aJakub Hrozek res = sss_atomic_write_s(i == 0 ? sock : 1, buffer, res);
5ca493af3e24e2cf7299289364cf23ccec9e5d35Jan Cholasta ret = errno;
1e68ae21e7ae46744700753ccf28bcbcaedbe017Jan Cholasta if (res == -1) {
e5359baeac6e2d49769aceddbdbc606833b1ec69Jan Cholasta DEBUG(SSSDBG_OP_FAILURE,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "sss_atomic_write_s() failed (%d): %s\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov ret, strerror(ret));
1e68ae21e7ae46744700753ccf28bcbcaedbe017Jan Cholasta goto done;
5ca493af3e24e2cf7299289364cf23ccec9e5d35Jan Cholasta } else if (ret == EPIPE) {
5ca493af3e24e2cf7299289364cf23ccec9e5d35Jan Cholasta ret = EOK;
5ca493af3e24e2cf7299289364cf23ccec9e5d35Jan Cholasta goto done;
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta }
1e68ae21e7ae46744700753ccf28bcbcaedbe017Jan Cholasta }
1e68ae21e7ae46744700753ccf28bcbcaedbe017Jan Cholasta if (fds[i].revents & POLLHUP) {
5ca493af3e24e2cf7299289364cf23ccec9e5d35Jan Cholasta ret = EOK;
5ca493af3e24e2cf7299289364cf23ccec9e5d35Jan Cholasta goto done;
1e68ae21e7ae46744700753ccf28bcbcaedbe017Jan Cholasta }
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta }
1e68ae21e7ae46744700753ccf28bcbcaedbe017Jan Cholasta }
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta
1e68ae21e7ae46744700753ccf28bcbcaedbe017Jan Cholastadone:
244adc327f7e29ba2c7ef60bc9f732d8fe3e68c9Simo Sorce close(sock);
1e68ae21e7ae46744700753ccf28bcbcaedbe017Jan Cholasta return ret;
1e68ae21e7ae46744700753ccf28bcbcaedbe017Jan Cholasta}
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta
1e68ae21e7ae46744700753ccf28bcbcaedbe017Jan Cholasta/* connect to server using proxy command */
1e68ae21e7ae46744700753ccf28bcbcaedbe017Jan Cholastastatic int
1e68ae21e7ae46744700753ccf28bcbcaedbe017Jan Cholastaconnect_proxy_command(char **args)
1e68ae21e7ae46744700753ccf28bcbcaedbe017Jan Cholasta{
1e68ae21e7ae46744700753ccf28bcbcaedbe017Jan Cholasta int ret;
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta
1e68ae21e7ae46744700753ccf28bcbcaedbe017Jan Cholasta execv(args[0], (char * const *)args);
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta
1e68ae21e7ae46744700753ccf28bcbcaedbe017Jan Cholasta ret = errno;
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_OP_FAILURE, "execv() failed (%d): %s\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov ret, strerror(ret));
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta
1e68ae21e7ae46744700753ccf28bcbcaedbe017Jan Cholasta return ret;
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta}
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholastaint main(int argc, const char **argv)
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta{
f646a0653964eb76b59c2881930687068c752b09Jan Zeleny TALLOC_CTX *mem_ctx = NULL;
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta int pc_debug = SSSDBG_DEFAULT;
b9698ee9e8365f16aebd780087d1ef4830ea9f39Jan Cholasta int pc_port = 22;
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta const char *pc_domain = NULL;
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta const char *pc_host = NULL;
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta const char **pc_args = NULL;
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta struct poptOption long_options[] = {
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta POPT_AUTOHELP
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta { "debug", '\0', POPT_ARG_INT | POPT_ARGFLAG_DOC_HIDDEN, &pc_debug, 0,
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta _("The debug level to run with"), NULL },
b9698ee9e8365f16aebd780087d1ef4830ea9f39Jan Cholasta { "port", 'p', POPT_ARG_INT, &pc_port, 0,
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta _("The port to use to connect to the host"), NULL },
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta { "domain", 'd', POPT_ARG_STRING, &pc_domain, 0,
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta _("The SSSD domain to use"), NULL },
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta POPT_TABLEEND
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta };
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta poptContext pc = NULL;
b9698ee9e8365f16aebd780087d1ef4830ea9f39Jan Cholasta char strport[6];
d0a8981bce0c462bcd4b5db2900c0f29a40a41f0Jan Cholasta struct addrinfo ai_hint;
d0a8981bce0c462bcd4b5db2900c0f29a40a41f0Jan Cholasta struct addrinfo *ai = NULL;
d0a8981bce0c462bcd4b5db2900c0f29a40a41f0Jan Cholasta char canonhost[NI_MAXHOST];
b9698ee9e8365f16aebd780087d1ef4830ea9f39Jan Cholasta const char *host = NULL;
748ba184db97b7534254f97018fa04e8aa458faeJan Cholasta struct sss_ssh_ent *ent;
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta int ret;
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta debug_prg_name = argv[0];
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta ret = set_locale();
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta if (ret != EOK) {
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta DEBUG(SSSDBG_CRIT_FAILURE,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "set_locale() failed (%d): %s\n", ret, strerror(ret));
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta ret = EXIT_FAILURE;
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta goto fini;
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta }
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta mem_ctx = talloc_new(NULL);
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta if (!mem_ctx) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Not enough memory\n");
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta ret = EXIT_FAILURE;
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta goto fini;
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta }
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta /* parse parameters */
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta pc = poptGetContext(NULL, argc, argv, long_options, 0);
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta poptSetOtherOptionHelp(pc, "HOST [PROXY_COMMAND]");
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta while ((ret = poptGetNextOpt(pc)) > 0)
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta ;
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta
9e2c64c6d4f5560e27207193efea6536a566865eMichal Zidek DEBUG_INIT(pc_debug);
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta if (ret != -1) {
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta BAD_POPT_PARAMS(pc, poptStrerror(ret), ret, fini);
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta }
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta
b9698ee9e8365f16aebd780087d1ef4830ea9f39Jan Cholasta if (pc_port < 1 || pc_port > 65535) {
b9698ee9e8365f16aebd780087d1ef4830ea9f39Jan Cholasta BAD_POPT_PARAMS(pc, _("Invalid port\n"), ret, fini);
b9698ee9e8365f16aebd780087d1ef4830ea9f39Jan Cholasta }
b9698ee9e8365f16aebd780087d1ef4830ea9f39Jan Cholasta
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta pc_host = poptGetArg(pc);
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta if (pc_host == NULL) {
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta BAD_POPT_PARAMS(pc, _("Host not specified\n"), ret, fini);
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta }
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta pc_args = poptGetArgs(pc);
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta if (pc_args && pc_args[0] && pc_args[0][0] != '/') {
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta BAD_POPT_PARAMS(pc,
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta _("The path to the proxy command must be absolute\n"),
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta ret, fini);
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta }
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta
b9698ee9e8365f16aebd780087d1ef4830ea9f39Jan Cholasta /* canonicalize hostname */
b9698ee9e8365f16aebd780087d1ef4830ea9f39Jan Cholasta snprintf(strport, 6, "%d", pc_port);
b9698ee9e8365f16aebd780087d1ef4830ea9f39Jan Cholasta
d0a8981bce0c462bcd4b5db2900c0f29a40a41f0Jan Cholasta memset(&ai_hint, 0, sizeof(struct addrinfo));
d0a8981bce0c462bcd4b5db2900c0f29a40a41f0Jan Cholasta ai_hint.ai_family = AF_UNSPEC;
d0a8981bce0c462bcd4b5db2900c0f29a40a41f0Jan Cholasta ai_hint.ai_socktype = SOCK_STREAM;
d0a8981bce0c462bcd4b5db2900c0f29a40a41f0Jan Cholasta ai_hint.ai_protocol = IPPROTO_TCP;
b9698ee9e8365f16aebd780087d1ef4830ea9f39Jan Cholasta ai_hint.ai_flags = AI_ADDRCONFIG | AI_NUMERICHOST | AI_NUMERICSERV;
d0a8981bce0c462bcd4b5db2900c0f29a40a41f0Jan Cholasta
b9698ee9e8365f16aebd780087d1ef4830ea9f39Jan Cholasta ret = getaddrinfo(pc_host, strport, &ai_hint, &ai);
d0a8981bce0c462bcd4b5db2900c0f29a40a41f0Jan Cholasta if (ret) {
b9698ee9e8365f16aebd780087d1ef4830ea9f39Jan Cholasta ai_hint.ai_flags = AI_ADDRCONFIG | AI_CANONNAME | AI_NUMERICSERV;
d0a8981bce0c462bcd4b5db2900c0f29a40a41f0Jan Cholasta
b9698ee9e8365f16aebd780087d1ef4830ea9f39Jan Cholasta ret = getaddrinfo(pc_host, strport, &ai_hint, &ai);
b9698ee9e8365f16aebd780087d1ef4830ea9f39Jan Cholasta if (ret) {
b9698ee9e8365f16aebd780087d1ef4830ea9f39Jan Cholasta DEBUG(SSSDBG_OP_FAILURE,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "getaddrinfo() failed (%d): %s\n", ret, gai_strerror(ret));
b9698ee9e8365f16aebd780087d1ef4830ea9f39Jan Cholasta } else {
08084b1179bb9fc38bc22b464b3d44907107bfd3Simo Sorce host = ai->ai_canonname;
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta }
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta } else {
08084b1179bb9fc38bc22b464b3d44907107bfd3Simo Sorce ret = getnameinfo(ai->ai_addr, ai->ai_addrlen,
b9698ee9e8365f16aebd780087d1ef4830ea9f39Jan Cholasta canonhost, NI_MAXHOST, NULL, 0, NI_NAMEREQD);
b9698ee9e8365f16aebd780087d1ef4830ea9f39Jan Cholasta if (ret) {
b9698ee9e8365f16aebd780087d1ef4830ea9f39Jan Cholasta DEBUG(SSSDBG_OP_FAILURE,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "getnameinfo() failed (%d): %s\n", ret, gai_strerror(ret));
b9698ee9e8365f16aebd780087d1ef4830ea9f39Jan Cholasta } else {
b9698ee9e8365f16aebd780087d1ef4830ea9f39Jan Cholasta host = canonhost;
b9698ee9e8365f16aebd780087d1ef4830ea9f39Jan Cholasta }
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta }
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta
b9698ee9e8365f16aebd780087d1ef4830ea9f39Jan Cholasta if (host) {
b9698ee9e8365f16aebd780087d1ef4830ea9f39Jan Cholasta /* look up public keys */
b9698ee9e8365f16aebd780087d1ef4830ea9f39Jan Cholasta ret = sss_ssh_get_ent(mem_ctx, SSS_SSH_GET_HOST_PUBKEYS,
28e55560008f21a532b103b3f612c6fca2a54d76Jan Cholasta host, pc_domain, pc_host, &ent);
b9698ee9e8365f16aebd780087d1ef4830ea9f39Jan Cholasta if (ret != EOK) {
b9698ee9e8365f16aebd780087d1ef4830ea9f39Jan Cholasta DEBUG(SSSDBG_OP_FAILURE,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "sss_ssh_get_ent() failed (%d): %s\n", ret, strerror(ret));
b9698ee9e8365f16aebd780087d1ef4830ea9f39Jan Cholasta }
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta }
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta /* connect to server */
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta if (pc_args) {
1e68ae21e7ae46744700753ccf28bcbcaedbe017Jan Cholasta ret = connect_proxy_command(discard_const(pc_args));
b9698ee9e8365f16aebd780087d1ef4830ea9f39Jan Cholasta } else if (ai) {
5f6232c7e6d9635c1d6b6b09f799309b6094b143Simo Sorce /* Try all IP addresses before giving up */
5f6232c7e6d9635c1d6b6b09f799309b6094b143Simo Sorce for (struct addrinfo *ti = ai; ti != NULL; ti = ti->ai_next) {
244adc327f7e29ba2c7ef60bc9f732d8fe3e68c9Simo Sorce int socket_descriptor = -1;
244adc327f7e29ba2c7ef60bc9f732d8fe3e68c9Simo Sorce ret = connect_socket(ti->ai_family, ti->ai_addr, ti->ai_addrlen,
244adc327f7e29ba2c7ef60bc9f732d8fe3e68c9Simo Sorce &socket_descriptor);
5f6232c7e6d9635c1d6b6b09f799309b6094b143Simo Sorce if (ret == 0) {
244adc327f7e29ba2c7ef60bc9f732d8fe3e68c9Simo Sorce ret = proxy_data(socket_descriptor);
5f6232c7e6d9635c1d6b6b09f799309b6094b143Simo Sorce break;
5f6232c7e6d9635c1d6b6b09f799309b6094b143Simo Sorce }
5f6232c7e6d9635c1d6b6b09f799309b6094b143Simo Sorce }
b9698ee9e8365f16aebd780087d1ef4830ea9f39Jan Cholasta } else {
b9698ee9e8365f16aebd780087d1ef4830ea9f39Jan Cholasta ret = EFAULT;
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta }
1e68ae21e7ae46744700753ccf28bcbcaedbe017Jan Cholasta ret = (ret == EOK) ? EXIT_SUCCESS : EXIT_FAILURE;
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholastafini:
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta poptFreeContext(pc);
d0a8981bce0c462bcd4b5db2900c0f29a40a41f0Jan Cholasta if (ai) freeaddrinfo(ai);
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta talloc_free(mem_ctx);
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta return ret;
9a3e40dc49c1e38bf58e45be5adff37615f3910bJan Cholasta}