Esempio n. 1
0
/* Stderr */
SshStream ssh_stream_fd_stderr(void)
{
  SshStream str;
  str = ssh_stream_fd_wrap2(2, 2, FALSE);
  if (str == NULL)
    ssh_fatal("Insufficient resources to create stderr stream");
  return str;
}
Esempio n. 2
0
int main(int argc, char **argv)
{
    SshStream stdio_stream;
    SshSigner signer;
    char config_filename[512];
    char *temp_name;

#ifdef SLEEP_AFTER_STARTUP
    sleep(30);
#endif /* SLEEP_AFTER_STARTUP */

    /* Get program name (without path). */
    if ((temp_name = strrchr(argv[0], '/')) != NULL)
        progname = ssh_xstrdup(temp_name + 1);
    else
        progname = ssh_xstrdup(argv[0]);

    /* XXX there should be a way to give command-line parameters to this
       program, but, they should only be used if the uid is the same as
       euid. */
    ssh_event_loop_initialize();

    signer = ssh_xcalloc(1, sizeof(*signer));

#ifdef SIGNER_QUIET
    signer->quiet = TRUE;
#else /* SIGNER_QUIET */
    signer->quiet = FALSE;
#endif /* SIGNER_QUIET */
    ssh_debug_register_callbacks(signer_ssh_fatal, signer_ssh_warning,
                                 signer_ssh_debug, (void *)signer);
#ifdef SIGNER_DEBUG
    ssh_debug_set_global_level(5);
#endif /* SIGNER_DEBUG */

    /* Act as server. */
    signer->config = ssh_server_create_config();

    SSH_TRACE(2, ("public key file: %s", signer->config->public_host_key_file));
    SSH_TRACE(2, ("private key file: %s", signer->config->host_key_file));
    SSH_TRACE(2, ("randomseed file: %s", signer->config->random_seed_file));

    /* Initialize user context with euid. This is used to dig up the
       hostkey and such. */
    signer->effective_user_data = ssh_user_initialize_with_uid(geteuid(), FALSE);

    signer->random_state = ssh_randseed_open(signer->effective_user_data,
                           signer->config);

    /* XXX what about alternative config files? This should be possible
       to configure somehow. An option for configure is probably a good
       idea. */
    snprintf(config_filename, sizeof(config_filename), "%s/%s",
             SSH_SERVER_DIR, SSH_SERVER_CONFIG_FILE);

    if (!ssh_config_read_file(signer->effective_user_data, signer->config,
                              NULL, config_filename, NULL))
        ssh_warning("%s: Failed to read config file %s", argv[0],
                    config_filename);

    stdio_stream = ssh_stream_fd_wrap2(fileno(stdin), fileno(stdout),
                                       TRUE);

    signer->wrapper = ssh_packet_wrap(stdio_stream,
                                      signer_received_packet,
                                      signer_received_eof,
                                      signer_can_send,
                                      signer);

    ssh_event_loop_run();

    return 0;
}
Esempio n. 3
0
SshStream ssh_stream_fd_stdio()
{
  return ssh_stream_fd_wrap2(0, 1, FALSE);
}
Esempio n. 4
0
SshStream ssh_stream_fd_wrap(int fd, Boolean close_on_destroy)
{
  return ssh_stream_fd_wrap2(fd, fd, close_on_destroy);
}
Esempio n. 5
0
SshPipeStatus ssh_pipe_create_and_fork(SshStream *stdio_return,
                                       SshStream *stderr_return)
{
    int pin[2], pout[2], perr[2];
    pid_t pid;
    SshPipeStream pipes;

    if (pipe(pin) < 0)
        return SSH_PIPE_ERROR;
    if (pipe(pout) < 0)
    {
        close(pin[0]);
        close(pin[1]);
        return SSH_PIPE_ERROR;
    }
    if (stderr_return != NULL && pipe(perr) < 0)
    {
        close(pin[0]);
        close(pin[1]);
        close(pout[0]);
        close(pout[1]);
        return SSH_PIPE_ERROR;
    }

    /* Initialize SIGCHLD handling.  This will ensure the SIGCHLD won't get
       delivered until we register the handler for the new process below. */
    ssh_sigchld_initialize();

    /* Fork a child process. */
    pid = fork();
    if (pid < 0)
    {
        ssh_warning("Fork failed: %s", strerror(errno));
        close(pin[0]);
        close(pin[1]);
        close(pout[0]);
        close(pout[1]);
        if (stderr_return != NULL)
        {
            close(perr[0]);
            close(perr[1]);
        }
        return SSH_PIPE_ERROR;
    }

    /* The remaining processing depends on whether we are the parent or
       the child. */
    if (pid == 0)
    {
        /* Redirect stdin. */
        close(pin[1]);
        if (dup2(pin[0], 0) < 0)
            perror("dup2 stdin");
        close(pin[0]);

        /* Redirect stdout. */
        close(pout[0]);
        if (dup2(pout[1], 1) < 0)
            perror("dup2 stdout");
        close(pout[1]);

        if (stderr_return != NULL)
        {
            /* Redirect stderr. */
            close(perr[0]);
            if (dup2(perr[1], 2) < 0)
                perror("dup2 stderr");
            close(perr[1]);
        }

        *stdio_return = NULL;
        if (stderr_return != NULL)
            *stderr_return = NULL;
        return SSH_PIPE_CHILD_OK;
    }

    /* Parent */
    pipes = ssh_xcalloc(sizeof(*pipes), 1);
    pipes->pid = pid;
    pipes->callback = NULL;
    pipes->callback_context = NULL;

    pipes->status_returned = FALSE;
    pipes->exit_status = -1;

    /* Close the child-side file descriptors. */
    close(pin[0]);
    close(pout[1]);
    if (stderr_return != NULL)
        close(perr[1]);

    /* Register a handler for SIGCHLD for our new child. */
    ssh_sigchld_register(pid, ssh_pipe_sigchld_handler, (void *)pipes);

    /* Wrap the master fd into a stream. */
    pipes->stdio_stream = ssh_stream_fd_wrap2(pout[0], pin[1], TRUE);
    *stdio_return = ssh_stream_create(&ssh_pipe_methods, (void *) pipes);

    /* Create the stderr stream if requested. */
    /* XXX should another context (errpipes?) be allocated for this, so that
       this, too, could be created as above?*/
    if (stderr_return != NULL)
        *stderr_return = ssh_stream_fd_wrap(perr[0], TRUE);

    return SSH_PIPE_PARENT_OK;
}
Esempio n. 6
0
SshStream ssh_stream_fd_wrap(SshIOHandle fd, Boolean close_on_destroy)
{
  return ssh_stream_fd_wrap2(fd, fd, close_on_destroy);
}