Blame tests/server/test_server/main.c

Packit 6c0a39
/*
Packit 6c0a39
 * This file is part of the SSH Library
Packit 6c0a39
 *
Packit 6c0a39
 * Copyright (c) 2018 by Red Hat, Inc.
Packit 6c0a39
 *
Packit 6c0a39
 * Author: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Packit 6c0a39
 *
Packit 6c0a39
 * The SSH Library is free software; you can redistribute it and/or modify
Packit 6c0a39
 * it under the terms of the GNU Lesser General Public License as published by
Packit 6c0a39
 * the Free Software Foundation; either version 2.1 of the License, or (at your
Packit 6c0a39
 * option) any later version.
Packit 6c0a39
 *
Packit 6c0a39
 * The SSH Library is distributed in the hope that it will be useful, but
Packit 6c0a39
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
Packit 6c0a39
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
Packit 6c0a39
 * License for more details.
Packit 6c0a39
 *
Packit 6c0a39
 * You should have received a copy of the GNU Lesser General Public License
Packit 6c0a39
 * along with the SSH Library; see the file COPYING.  If not, write to
Packit 6c0a39
 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
Packit 6c0a39
 * MA 02111-1307, USA.
Packit 6c0a39
 */
Packit 6c0a39
Packit 6c0a39
#include "config.h"
Packit 6c0a39
#include "test_server.h"
Packit 6c0a39
#include "default_cb.h"
Packit 6c0a39
Packit 6c0a39
#include <libssh/priv.h>
Packit 6c0a39
Packit 6c0a39
#include <libssh/libssh.h>
Packit 6c0a39
#include <libssh/server.h>
Packit 6c0a39
#include <libssh/callbacks.h>
Packit 6c0a39
Packit 6c0a39
#ifdef HAVE_ARGP_H
Packit 6c0a39
#include <argp.h>
Packit 6c0a39
#endif
Packit 6c0a39
Packit 6c0a39
#include <stdlib.h>
Packit 6c0a39
#include <string.h>
Packit 6c0a39
#include <stdio.h>
Packit 6c0a39
#include <stdbool.h>
Packit 6c0a39
Packit 6c0a39
struct arguments_st {
Packit 6c0a39
    char *address;
Packit 6c0a39
    char *port;
Packit 6c0a39
Packit 6c0a39
    char *ecdsa_key;
Packit 6c0a39
    char *dsa_key;
Packit 6c0a39
    char *ed25519_key;
Packit 6c0a39
    char *rsa_key;
Packit 6c0a39
    char *host_key;
Packit 6c0a39
Packit 6c0a39
    char *verbosity;
Packit 6c0a39
    char *auth_methods;
Packit 6c0a39
    bool with_pcap;
Packit 6c0a39
Packit 6c0a39
    char *pcap_file;
Packit 6c0a39
Packit 6c0a39
    char *username;
Packit 6c0a39
    char *password;
Packit 6c0a39
Packit 6c0a39
    char *config_file;
Packit 6c0a39
    bool with_global_config;
Packit 6c0a39
};
Packit 6c0a39
Packit 6c0a39
static void free_arguments(struct arguments_st *arguments)
Packit 6c0a39
{
Packit 6c0a39
    if (arguments == NULL) {
Packit 6c0a39
        goto end;
Packit 6c0a39
    }
Packit 6c0a39
Packit 6c0a39
    SAFE_FREE(arguments->address);
Packit 6c0a39
    SAFE_FREE(arguments->port);
Packit 6c0a39
Packit 6c0a39
    SAFE_FREE(arguments->ecdsa_key);
Packit 6c0a39
    SAFE_FREE(arguments->dsa_key);
Packit 6c0a39
    SAFE_FREE(arguments->ed25519_key);
Packit 6c0a39
    SAFE_FREE(arguments->rsa_key);
Packit 6c0a39
    SAFE_FREE(arguments->host_key);
Packit 6c0a39
Packit 6c0a39
    SAFE_FREE(arguments->verbosity);
Packit 6c0a39
    SAFE_FREE(arguments->auth_methods);
Packit 6c0a39
    SAFE_FREE(arguments->pcap_file);
Packit 6c0a39
Packit 6c0a39
    SAFE_FREE(arguments->username);
Packit 6c0a39
    SAFE_FREE(arguments->password);
Packit 6c0a39
    SAFE_FREE(arguments->config_file);
Packit 6c0a39
Packit 6c0a39
end:
Packit 6c0a39
    return;
Packit 6c0a39
}
Packit 6c0a39
Packit 6c0a39
#ifdef HAVE_ARGP_H
Packit 6c0a39
Packit 6c0a39
static void print_auth_methods(int auth_methods)
Packit 6c0a39
{
Packit 6c0a39
    printf("auth_methods = \n");
Packit 6c0a39
    if (auth_methods & SSH_AUTH_METHOD_NONE) {
Packit 6c0a39
        printf("\tSSH_AUTH_METHOD_NONE\n");
Packit 6c0a39
    }
Packit 6c0a39
    if (auth_methods & SSH_AUTH_METHOD_PASSWORD) {
Packit 6c0a39
        printf("\tSSH_AUTH_METHOD_PASSWORD\n");
Packit 6c0a39
    }
Packit 6c0a39
    if (auth_methods & SSH_AUTH_METHOD_PUBLICKEY) {
Packit 6c0a39
        printf("\tSSH_AUTH_METHOD_PUBLICKEY\n");
Packit 6c0a39
    }
Packit 6c0a39
    if (auth_methods & SSH_AUTH_METHOD_HOSTBASED) {
Packit 6c0a39
        printf("\tSSH_AUTH_METHOD_HOSTBASED\n");
Packit 6c0a39
    }
Packit 6c0a39
    if (auth_methods & SSH_AUTH_METHOD_INTERACTIVE) {
Packit 6c0a39
        printf("\tSSH_AUTH_METHOD_INTERACTIVE\n");
Packit 6c0a39
    }
Packit 6c0a39
    if (auth_methods & SSH_AUTH_METHOD_GSSAPI_MIC) {
Packit 6c0a39
        printf("\tSSH_AUTH_METHOD_GSSAPI_MIC\n");
Packit 6c0a39
    }
Packit 6c0a39
}
Packit 6c0a39
Packit 6c0a39
static void print_verbosity(int verbosity)
Packit 6c0a39
{
Packit 6c0a39
    printf("verbosity = ");
Packit 6c0a39
    switch(verbosity) {
Packit 6c0a39
    case SSH_LOG_NOLOG:
Packit 6c0a39
        printf("NO LOG\n");
Packit 6c0a39
        break;
Packit 6c0a39
    case SSH_LOG_WARNING:
Packit 6c0a39
        printf("WARNING\n");
Packit 6c0a39
        break;
Packit 6c0a39
    case SSH_LOG_PROTOCOL:
Packit 6c0a39
        printf("PROTOCOL\n");
Packit 6c0a39
        break;
Packit 6c0a39
    case SSH_LOG_PACKET:
Packit 6c0a39
        printf("PACKET\n");
Packit 6c0a39
        break;
Packit 6c0a39
    case SSH_LOG_FUNCTIONS:
Packit 6c0a39
        printf("FUNCTIONS\n");
Packit 6c0a39
        break;
Packit 6c0a39
    default:
Packit 6c0a39
        printf("UNKNOWN\n");;
Packit 6c0a39
        break;
Packit 6c0a39
    }
Packit 6c0a39
}
Packit 6c0a39
Packit 6c0a39
static void print_server_state(struct server_state_st *state)
Packit 6c0a39
{
Packit 6c0a39
    if (state) {
Packit 6c0a39
        printf("===================| STATE |=====================\n");
Packit 6c0a39
        printf("address = %s\n",
Packit 6c0a39
                state->address? state->address: "NULL");
Packit 6c0a39
        printf("port = %d\n",
Packit 6c0a39
                state->port? state->port: 0);
Packit 6c0a39
        printf("=================================================\n");
Packit 6c0a39
        printf("ecdsa_key = %s\n",
Packit 6c0a39
                state->ecdsa_key? state->ecdsa_key: "NULL");
Packit 6c0a39
        printf("dsa_key = %s\n",
Packit 6c0a39
                state->dsa_key? state->dsa_key: "NULL");
Packit 6c0a39
        printf("ed25519_key = %s\n",
Packit 6c0a39
                state->ed25519_key? state->ed25519_key: "NULL");
Packit 6c0a39
        printf("rsa_key = %s\n",
Packit 6c0a39
                state->rsa_key? state->rsa_key: "NULL");
Packit 6c0a39
        printf("host_key = %s\n",
Packit 6c0a39
                state->host_key? state->host_key: "NULL");
Packit 6c0a39
        printf("=================================================\n");
Packit 6c0a39
        print_auth_methods(state->auth_methods);
Packit 6c0a39
        print_verbosity(state->verbosity);
Packit 6c0a39
        printf("with_pcap = %s\n",
Packit 6c0a39
                state->with_pcap? "TRUE": "FALSE");
Packit 6c0a39
        printf("pcap_file = %s\n",
Packit 6c0a39
                state->pcap_file? state->pcap_file: "NULL");
Packit 6c0a39
        printf("=================================================\n");
Packit 6c0a39
        printf("username = %s\n",
Packit 6c0a39
                state->expected_username? state->expected_username: "NULL");
Packit 6c0a39
        printf("password = %s\n",
Packit 6c0a39
                state->expected_password? state->expected_password: "NULL");
Packit 6c0a39
        printf("=================================================\n");
Packit 6c0a39
        printf("with_global_config = %s\n",
Packit 6c0a39
                state->parse_global_config? "TRUE": "FALSE");
Packit 6c0a39
        printf("config_file = %s\n",
Packit 6c0a39
                state->config_file? state->config_file: "NULL");
Packit 6c0a39
        printf("=================================================\n");
Packit 6c0a39
    }
Packit 6c0a39
}
Packit 6c0a39
Packit 6c0a39
static int init_server_state(struct server_state_st *state,
Packit 6c0a39
                             struct arguments_st *arguments)
Packit 6c0a39
{
Packit 6c0a39
    int rc = 0;
Packit 6c0a39
Packit 6c0a39
    if (state == NULL) {
Packit 6c0a39
        rc = SSH_ERROR;
Packit 6c0a39
        goto end;
Packit 6c0a39
    }
Packit 6c0a39
Packit 6c0a39
    /* Initialize server state. The "arguments structure" */
Packit 6c0a39
    if (arguments->address) {
Packit 6c0a39
        state->address = arguments->address;
Packit 6c0a39
        arguments->address = NULL;
Packit 6c0a39
    } else {
Packit 6c0a39
        state->address = strdup(SSHD_DEFAULT_ADDRESS);
Packit 6c0a39
        if (state->address == NULL) {
Packit 6c0a39
            fprintf(stderr, "Out of memory\n");
Packit 6c0a39
            rc = SSH_ERROR;
Packit 6c0a39
            goto end;
Packit 6c0a39
        }
Packit 6c0a39
    }
Packit 6c0a39
Packit 6c0a39
    if (arguments->port) {
Packit 6c0a39
        state->port = atoi(arguments->port);
Packit 6c0a39
    } else {
Packit 6c0a39
        state->port = SSHD_DEFAULT_PORT;
Packit 6c0a39
    }
Packit 6c0a39
Packit 6c0a39
    if (arguments->ecdsa_key) {
Packit 6c0a39
        state->ecdsa_key = arguments->ecdsa_key;
Packit 6c0a39
        arguments->ecdsa_key = NULL;
Packit 6c0a39
    } else {
Packit 6c0a39
        state->ecdsa_key = NULL;
Packit 6c0a39
    }
Packit 6c0a39
Packit 6c0a39
    if (arguments->dsa_key) {
Packit 6c0a39
        state->dsa_key = arguments->dsa_key;
Packit 6c0a39
        arguments->dsa_key = NULL;
Packit 6c0a39
    } else {
Packit 6c0a39
        state->dsa_key = NULL;
Packit 6c0a39
    }
Packit 6c0a39
Packit 6c0a39
    if (arguments->ed25519_key) {
Packit 6c0a39
        state->ed25519_key = arguments->ed25519_key;
Packit 6c0a39
        arguments->ed25519_key = NULL;
Packit 6c0a39
    } else {
Packit 6c0a39
        state->ed25519_key = NULL;
Packit 6c0a39
    }
Packit 6c0a39
Packit 6c0a39
    if (arguments->rsa_key) {
Packit 6c0a39
        state->rsa_key = arguments->rsa_key;
Packit 6c0a39
        arguments->rsa_key = NULL;
Packit 6c0a39
    } else {
Packit 6c0a39
        state->rsa_key = NULL;
Packit 6c0a39
    }
Packit 6c0a39
Packit 6c0a39
    if (arguments->host_key) {
Packit 6c0a39
        state->host_key = arguments->host_key;
Packit 6c0a39
        arguments->host_key = NULL;
Packit 6c0a39
    } else {
Packit 6c0a39
        state->host_key = NULL;
Packit 6c0a39
    }
Packit 6c0a39
Packit 6c0a39
    if (arguments->username) {
Packit 6c0a39
        state->expected_username = arguments->username;
Packit 6c0a39
        arguments->username = NULL;
Packit 6c0a39
    } else {
Packit 6c0a39
        state->expected_username = strdup(SSHD_DEFAULT_USER);
Packit 6c0a39
        if (state->expected_username == NULL) {
Packit 6c0a39
            fprintf(stderr, "Out of memory\n");
Packit 6c0a39
            rc = SSH_ERROR;
Packit 6c0a39
            goto end;
Packit 6c0a39
        }
Packit 6c0a39
    }
Packit 6c0a39
Packit 6c0a39
    if (arguments->password) {
Packit 6c0a39
        state->expected_password = arguments->password;
Packit 6c0a39
        arguments->password = NULL;
Packit 6c0a39
    } else {
Packit 6c0a39
        state->expected_password = strdup(SSHD_DEFAULT_PASSWORD);
Packit 6c0a39
        if (state->expected_password == NULL) {
Packit 6c0a39
            fprintf(stderr, "Out of memory\n");
Packit 6c0a39
            rc = SSH_ERROR;
Packit 6c0a39
            goto end;
Packit 6c0a39
        }
Packit 6c0a39
    }
Packit 6c0a39
Packit 6c0a39
    if (arguments->verbosity) {
Packit 6c0a39
        state->verbosity = atoi(arguments->verbosity);
Packit 6c0a39
    } else {
Packit 6c0a39
        state->verbosity = 0;
Packit 6c0a39
    }
Packit 6c0a39
Packit 6c0a39
    if (arguments->auth_methods) {
Packit 6c0a39
        state->auth_methods = atoi(arguments->auth_methods);
Packit 6c0a39
    } else {
Packit 6c0a39
        state->auth_methods = SSH_AUTH_METHOD_PASSWORD |
Packit 6c0a39
                              SSH_AUTH_METHOD_PUBLICKEY;
Packit 6c0a39
    }
Packit 6c0a39
Packit 6c0a39
    state->with_pcap = arguments->with_pcap;
Packit 6c0a39
Packit 6c0a39
    if (arguments->pcap_file) {
Packit 6c0a39
        state->pcap_file = arguments->pcap_file;
Packit 6c0a39
        arguments->pcap_file = NULL;
Packit 6c0a39
    } else {
Packit 6c0a39
        if (arguments->with_pcap) {
Packit 6c0a39
            state->pcap_file = strdup(SSHD_DEFAULT_PCAP_FILE);
Packit 6c0a39
            if (state->pcap_file == NULL) {
Packit 6c0a39
                fprintf(stderr, "Out of memory\n");
Packit 6c0a39
                rc = SSH_ERROR;
Packit 6c0a39
                goto end;
Packit 6c0a39
            }
Packit 6c0a39
        } else {
Packit 6c0a39
            state->pcap_file = NULL;
Packit 6c0a39
        }
Packit 6c0a39
    }
Packit 6c0a39
Packit 6c0a39
    state->parse_global_config = arguments->with_global_config;
Packit 6c0a39
Packit 6c0a39
    if (arguments->config_file) {
Packit 6c0a39
        state->config_file = arguments->config_file;
Packit 6c0a39
        arguments->config_file = NULL;
Packit 6c0a39
    }
Packit 6c0a39
Packit 6c0a39
    /* TODO make configurable */
Packit 6c0a39
    state->max_tries = 3;
Packit 6c0a39
    state->error = 0;
Packit 6c0a39
Packit 6c0a39
Packit 6c0a39
    if (state) {
Packit 6c0a39
        print_server_state(state);
Packit 6c0a39
    }
Packit 6c0a39
Packit 6c0a39
    /* TODO make callbacks configurable through command line ? */
Packit 6c0a39
    /* Set callbacks to be used */
Packit 6c0a39
    state->handle_session = default_handle_session_cb;
Packit 6c0a39
Packit 6c0a39
    /* Check required parameters */
Packit 6c0a39
    if (state->address == NULL) {
Packit 6c0a39
        rc = SSH_ERROR;
Packit 6c0a39
        goto end;
Packit 6c0a39
    }
Packit 6c0a39
Packit 6c0a39
end:
Packit 6c0a39
    if (rc != 0) {
Packit 6c0a39
        free_server_state(state);
Packit 6c0a39
    }
Packit 6c0a39
Packit 6c0a39
    return rc;
Packit 6c0a39
}
Packit 6c0a39
Packit 6c0a39
const char *argp_program_version = "libssh test server "
Packit 6c0a39
SSH_STRINGIFY(LIBSSH_VERSION);
Packit 6c0a39
const char *argp_program_bug_address = "<libssh@libssh.org>";
Packit 6c0a39
Packit 6c0a39
/* Program documentation. */
Packit 6c0a39
static char doc[] = "libssh -- a Secure Shell protocol implementation";
Packit 6c0a39
Packit 6c0a39
/* A description of the arguments we accept. */
Packit 6c0a39
static char args_doc[] = "BINDADDR";
Packit 6c0a39
Packit 6c0a39
/* The options we understand. */
Packit 6c0a39
static struct argp_option options[] = {
Packit 6c0a39
    {
Packit 6c0a39
        .name  = "port",
Packit 6c0a39
        .key   = 'p',
Packit 6c0a39
        .arg   = "PORT",
Packit 6c0a39
        .flags = 0,
Packit 6c0a39
        .doc   = "Set the port to bind.",
Packit 6c0a39
        .group = 0
Packit 6c0a39
    },
Packit 6c0a39
    {
Packit 6c0a39
        .name  = "ecdsakey",
Packit 6c0a39
        .key   = 'c',
Packit 6c0a39
        .arg   = "FILE",
Packit 6c0a39
        .flags = 0,
Packit 6c0a39
        .doc   = "Set the ECDSA key.",
Packit 6c0a39
        .group = 0
Packit 6c0a39
    },
Packit 6c0a39
    {
Packit 6c0a39
        .name  = "dsakey",
Packit 6c0a39
        .key   = 'd',
Packit 6c0a39
        .arg   = "FILE",
Packit 6c0a39
        .flags = 0,
Packit 6c0a39
        .doc   = "Set the DSA key.",
Packit 6c0a39
        .group = 0
Packit 6c0a39
    },
Packit 6c0a39
    {
Packit 6c0a39
        .name  = "ed25519key",
Packit 6c0a39
        .key   = 'e',
Packit 6c0a39
        .arg   = "FILE",
Packit 6c0a39
        .flags = 0,
Packit 6c0a39
        .doc   = "Set the ed25519 key.",
Packit 6c0a39
        .group = 0
Packit 6c0a39
    },
Packit 6c0a39
    {
Packit 6c0a39
        .name  = "rsakey",
Packit 6c0a39
        .key   = 'r',
Packit 6c0a39
        .arg   = "FILE",
Packit 6c0a39
        .flags = 0,
Packit 6c0a39
        .doc   = "Set the RSA key.",
Packit 6c0a39
        .group = 0
Packit 6c0a39
    },
Packit 6c0a39
    {
Packit 6c0a39
        .name  = "hostkey",
Packit 6c0a39
        .key   = 'k',
Packit 6c0a39
        .arg   = "FILE",
Packit 6c0a39
        .flags = 0,
Packit 6c0a39
        .doc   = "Set the host key.",
Packit 6c0a39
        .group = 0
Packit 6c0a39
    },
Packit 6c0a39
    {
Packit 6c0a39
        .name  = "pcapfile",
Packit 6c0a39
        .key   = 'f',
Packit 6c0a39
        .arg   = "FILE",
Packit 6c0a39
        .flags = 0,
Packit 6c0a39
        .doc   = "Set the pcap output file.",
Packit 6c0a39
        .group = 0
Packit 6c0a39
    },
Packit 6c0a39
    {
Packit 6c0a39
        .name  = "auth-methods",
Packit 6c0a39
        .key   = 'a',
Packit 6c0a39
        .arg   = "METHODS",
Packit 6c0a39
        .flags = 0,
Packit 6c0a39
        .doc   = "Set supported authentication methods.",
Packit 6c0a39
        .group = 0
Packit 6c0a39
    },
Packit 6c0a39
    {
Packit 6c0a39
        .name  = "user",
Packit 6c0a39
        .key   = 'u',
Packit 6c0a39
        .arg   = "USERNAME",
Packit 6c0a39
        .flags = 0,
Packit 6c0a39
        .doc   = "Set expected username.",
Packit 6c0a39
        .group = 0
Packit 6c0a39
    },
Packit 6c0a39
    {
Packit 6c0a39
        .name  = "verbosity",
Packit 6c0a39
        .key   = 'v',
Packit 6c0a39
        .arg   = "VERBOSITY",
Packit 6c0a39
        .flags = 0,
Packit 6c0a39
        .doc   = "Set output verbosity [0-4].",
Packit 6c0a39
        .group = 0
Packit 6c0a39
    },
Packit 6c0a39
    {
Packit 6c0a39
        .name  = "with-pcap",
Packit 6c0a39
        .key   = 'w',
Packit 6c0a39
        .arg   = NULL,
Packit 6c0a39
        .flags = 0,
Packit 6c0a39
        .doc   = "Use PCAP.",
Packit 6c0a39
        .group = 0
Packit 6c0a39
    },
Packit 6c0a39
    {
Packit 6c0a39
        .name  = "without-global-config",
Packit 6c0a39
        .key   = 'g',
Packit 6c0a39
        .arg   = NULL,
Packit 6c0a39
        .flags = 0,
Packit 6c0a39
        .doc   = "Do not use system-wide configuration file.",
Packit 6c0a39
        .group = 0
Packit 6c0a39
    },
Packit 6c0a39
    {
Packit 6c0a39
        .name  = "config",
Packit 6c0a39
        .key   = 'C',
Packit 6c0a39
        .arg   = "CONFIG_FILE",
Packit 6c0a39
        .flags = 0,
Packit 6c0a39
        .doc   = "Use this server configuration file.",
Packit 6c0a39
        .group = 0
Packit 6c0a39
    },
Packit 6c0a39
    { .name = NULL }
Packit 6c0a39
};
Packit 6c0a39
Packit 6c0a39
/* Parse a single option. */
Packit 6c0a39
static error_t parse_opt (int key, char *arg, struct argp_state *state)
Packit 6c0a39
{
Packit 6c0a39
    /* Get the input argument from argp_parse, which we
Packit 6c0a39
     * know is a pointer to our arguments structure.
Packit 6c0a39
     */
Packit 6c0a39
    struct arguments_st *arguments = state->input;
Packit 6c0a39
    error_t rc = 0;
Packit 6c0a39
Packit 6c0a39
    if (arguments == NULL) {
Packit 6c0a39
        fprintf(stderr, "NULL pointer to arguments structure provided\n");
Packit 6c0a39
        rc = EINVAL;
Packit 6c0a39
        goto end;
Packit 6c0a39
    }
Packit 6c0a39
Packit 6c0a39
    switch (key) {
Packit 6c0a39
    case 'c':
Packit 6c0a39
        arguments->ecdsa_key = strdup(arg);
Packit 6c0a39
        if (arguments->ecdsa_key == NULL) {
Packit 6c0a39
            fprintf(stderr, "Out of memory\n");
Packit 6c0a39
            rc = ENOMEM;
Packit 6c0a39
            goto end;
Packit 6c0a39
        }
Packit 6c0a39
        break;
Packit 6c0a39
    case 'd':
Packit 6c0a39
        arguments->dsa_key = strdup(arg);
Packit 6c0a39
        if (arguments->dsa_key == NULL) {
Packit 6c0a39
            fprintf(stderr, "Out of memory\n");
Packit 6c0a39
            rc = ENOMEM;
Packit 6c0a39
            goto end;
Packit 6c0a39
        }
Packit 6c0a39
        break;
Packit 6c0a39
    case 'e':
Packit 6c0a39
        arguments->ed25519_key = strdup(arg);
Packit 6c0a39
        if (arguments->ed25519_key == NULL) {
Packit 6c0a39
            fprintf(stderr, "Out of memory\n");
Packit 6c0a39
            rc = ENOMEM;
Packit 6c0a39
            goto end;
Packit 6c0a39
        }
Packit 6c0a39
        break;
Packit 6c0a39
    case 'f':
Packit 6c0a39
        arguments->pcap_file = strdup(arg);
Packit 6c0a39
        if (arguments->pcap_file == NULL) {
Packit 6c0a39
            fprintf(stderr, "Out of memory\n");
Packit 6c0a39
            rc = ENOMEM;
Packit 6c0a39
            goto end;
Packit 6c0a39
        }
Packit 6c0a39
        break;
Packit 6c0a39
    case 'k':
Packit 6c0a39
        arguments->host_key = strdup(arg);
Packit 6c0a39
        if (arguments->host_key == NULL) {
Packit 6c0a39
            fprintf(stderr, "Out of memory\n");
Packit 6c0a39
            rc = ENOMEM;
Packit 6c0a39
            goto end;
Packit 6c0a39
        }
Packit 6c0a39
        break;
Packit 6c0a39
    case 'a':
Packit 6c0a39
        arguments->auth_methods = strdup(arg);
Packit 6c0a39
        if (arguments->auth_methods == NULL) {
Packit 6c0a39
            fprintf(stderr, "Out of memory\n");
Packit 6c0a39
            rc = ENOMEM;
Packit 6c0a39
            goto end;
Packit 6c0a39
        }
Packit 6c0a39
        break;
Packit 6c0a39
    case 'p':
Packit 6c0a39
        arguments->port = strdup(arg);
Packit 6c0a39
        if (arguments->port == NULL) {
Packit 6c0a39
            fprintf(stderr, "Out of memory\n");
Packit 6c0a39
            rc = ENOMEM;
Packit 6c0a39
            goto end;
Packit 6c0a39
        }
Packit 6c0a39
        break;
Packit 6c0a39
    case 'r':
Packit 6c0a39
        arguments->rsa_key = strdup(arg);
Packit 6c0a39
        if (arguments->rsa_key == NULL) {
Packit 6c0a39
            fprintf(stderr, "Out of memory\n");
Packit 6c0a39
            rc = ENOMEM;
Packit 6c0a39
            goto end;
Packit 6c0a39
        }
Packit 6c0a39
        break;
Packit 6c0a39
    case 'u':
Packit 6c0a39
        arguments->username = strdup(arg);
Packit 6c0a39
        if (arguments->username == NULL) {
Packit 6c0a39
            fprintf(stderr, "Out of memory\n");
Packit 6c0a39
            rc = ENOMEM;
Packit 6c0a39
            goto end;
Packit 6c0a39
        }
Packit 6c0a39
        break;
Packit 6c0a39
    case 'v':
Packit 6c0a39
        arguments->verbosity = strdup(arg);
Packit 6c0a39
        if (arguments->verbosity == NULL) {
Packit 6c0a39
            fprintf(stderr, "Out of memory\n");
Packit 6c0a39
            rc = ENOMEM;
Packit 6c0a39
            goto end;
Packit 6c0a39
        }
Packit 6c0a39
        break;
Packit 6c0a39
    case 'w':
Packit 6c0a39
        arguments->with_pcap = true;
Packit 6c0a39
        break;
Packit 6c0a39
    case 'g':
Packit 6c0a39
        arguments->with_global_config = false;
Packit 6c0a39
        break;
Packit 6c0a39
    case 'C':
Packit 6c0a39
        arguments->config_file = strdup(arg);
Packit 6c0a39
        if (arguments->config_file == NULL) {
Packit 6c0a39
            fprintf(stderr, "Out of memory\n");
Packit 6c0a39
            rc = ENOMEM;
Packit 6c0a39
            goto end;
Packit 6c0a39
        }
Packit 6c0a39
        break;
Packit 6c0a39
    case ARGP_KEY_ARG:
Packit 6c0a39
        if (state->arg_num >= 1) {
Packit 6c0a39
            /* Too many arguments. */
Packit 6c0a39
            printf("Too many arguments\n");
Packit 6c0a39
            argp_usage(state);
Packit 6c0a39
        }
Packit 6c0a39
        arguments->address = strdup(arg);
Packit 6c0a39
        if (arguments->address == NULL) {
Packit 6c0a39
            fprintf(stderr, "Out of memory\n");
Packit 6c0a39
            rc = ENOMEM;
Packit 6c0a39
            goto end;
Packit 6c0a39
        }
Packit 6c0a39
        break;
Packit 6c0a39
    case ARGP_KEY_END:
Packit 6c0a39
        if (state->arg_num < 1) {
Packit 6c0a39
            printf("Too few arguments\n");
Packit 6c0a39
            /* Not enough arguments. */
Packit 6c0a39
            argp_usage(state);
Packit 6c0a39
        }
Packit 6c0a39
        break;
Packit 6c0a39
    default:
Packit 6c0a39
        return ARGP_ERR_UNKNOWN;
Packit 6c0a39
    }
Packit 6c0a39
Packit 6c0a39
end:
Packit 6c0a39
    return rc;
Packit 6c0a39
}
Packit 6c0a39
Packit 6c0a39
/* Our argp parser. */
Packit 6c0a39
static struct argp argp = {options, parse_opt, args_doc, doc, NULL, NULL, NULL};
Packit 6c0a39
Packit 6c0a39
#endif /* HAVE_ARGP_H */
Packit 6c0a39
Packit 6c0a39
int main(UNUSED_PARAM(int argc), UNUSED_PARAM(char **argv))
Packit 6c0a39
{
Packit 6c0a39
    int rc;
Packit 6c0a39
Packit 6c0a39
    struct arguments_st arguments = {
Packit 6c0a39
        .address = NULL,
Packit 6c0a39
        .with_global_config = true,
Packit 6c0a39
    };
Packit 6c0a39
    struct server_state_st state = {
Packit 6c0a39
        .address = NULL,
Packit 6c0a39
    };
Packit 6c0a39
Packit 6c0a39
#ifdef HAVE_ARGP_H
Packit 6c0a39
    argp_parse (&argp, argc, argv, 0, 0, &arguments);
Packit 6c0a39
#endif
Packit 6c0a39
Packit 6c0a39
    /* Initialize the state using default or given parameters */
Packit 6c0a39
    rc = init_server_state(&state, &arguments);
Packit 6c0a39
    if (rc != 0) {
Packit 6c0a39
        goto free_arguments;
Packit 6c0a39
    }
Packit 6c0a39
Packit 6c0a39
    /* Free the arguments used to initialize the state before fork */
Packit 6c0a39
    free_arguments(&arguments);
Packit 6c0a39
Packit 6c0a39
    /* Run the server */
Packit 6c0a39
    rc = run_server(&state);
Packit 6c0a39
    if (rc != 0) {
Packit 6c0a39
        goto free_state;
Packit 6c0a39
    }
Packit 6c0a39
Packit 6c0a39
free_state:
Packit 6c0a39
    free_server_state(&state);
Packit 6c0a39
free_arguments:
Packit 6c0a39
    free_arguments(&arguments);
Packit 6c0a39
    return rc;
Packit 6c0a39
}