From 179012ddd48e63ca83e8f5c24537a2db45c3e122 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 3 Jul 2013 13:10:29 +0200 Subject: [PATCH] agent: Fix binary vs. text mode problem in ssh. * agent/command-ssh.c (file_to_buffer) (ssh_handler_request_identities): Open streams in binary mode. (start_command_handler_ssh): Factor some code out to .. (setup_ssh_env): new function. -- This is for now a theoretical fix because there is no ssh client yet which uses the GnuPG style IPC. OpenSSL for Cygwin uses only a quite similar one. gniibe suggested to implement that IPC style in Libassuan so that a Cygwin version of OpenSSL may be used with GnuPG. Signed-off-by: Werner Koch (cherry picked from commit ed056d67c7c93306b68829f83a2565e978dcfd9b) Also fixed one typo. --- agent/command-ssh.c | 73 +++++++++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 33 deletions(-) diff --git a/agent/command-ssh.c b/agent/command-ssh.c index 8f8e285ab..46aa94c5e 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -684,7 +684,7 @@ file_to_buffer (const char *filename, unsigned char **buffer, size_t *buffer_n) buffer_new = NULL; err = 0; - stream = es_fopen (filename, "r"); + stream = es_fopen (filename, "rb"); if (! stream) { err = gpg_error_from_syserror (); @@ -2281,7 +2281,7 @@ ssh_handler_request_identities (ctrl_t ctrl, key_counter = 0; err = 0; - key_blobs = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+"); + key_blobs = es_mopen (NULL, 0, 0, 1, NULL, NULL, "r+b"); if (! key_blobs) { err = gpg_error_from_syserror (); @@ -3356,44 +3356,51 @@ ssh_request_process (ctrl_t ctrl, estream_t stream_sock) return !!err; } + +/* Because the ssh protocol does not send us information about the + current TTY setting, we use this function to use those from startup + or those explictly set. */ +static gpg_error_t +setup_ssh_env (ctrl_t ctrl) +{ + static const char *names[] = + {"GPG_TTY", "DISPLAY", "TERM", "XAUTHORITY", "PINENTRY_USER_DATA", NULL}; + gpg_error_t err = 0; + int idx; + const char *value; + + for (idx=0; !err && names[idx]; idx++) + if (!session_env_getenv (ctrl->session_env, names[idx]) + && (value = session_env_getenv (opt.startup_env, names[idx]))) + err = session_env_setenv (ctrl->session_env, names[idx], value); + + if (!err && !ctrl->lc_ctype && opt.startup_lc_ctype) + if (!(ctrl->lc_ctype = xtrystrdup (opt.startup_lc_ctype))) + err = gpg_error_from_syserror (); + + if (!err && !ctrl->lc_messages && opt.startup_lc_messages) + if (!(ctrl->lc_messages = xtrystrdup (opt.startup_lc_messages))) + err = gpg_error_from_syserror (); + + if (err) + log_error ("error setting default session environment: %s\n", + gpg_strerror (err)); + + return err; +} + + /* Start serving client on SOCK_CLIENT. */ void start_command_handler_ssh (ctrl_t ctrl, gnupg_fd_t sock_client) { estream_t stream_sock = NULL; - gpg_error_t err = 0; + gpg_error_t err; int ret; - /* Because the ssh protocol does not send us information about the - the current TTY setting, we resort here to use those from startup - or those explictly set. */ - { - static const char *names[] = - {"GPG_TTY", "DISPLAY", "TERM", "XAUTHORITY", "PINENTRY_USER_DATA", NULL}; - int idx; - const char *value; - - for (idx=0; !err && names[idx]; idx++) - if (!session_env_getenv (ctrl->session_env, names[idx]) - && (value = session_env_getenv (opt.startup_env, names[idx]))) - err = session_env_setenv (ctrl->session_env, names[idx], value); - - if (!err && !ctrl->lc_ctype && opt.startup_lc_ctype) - if (!(ctrl->lc_ctype = xtrystrdup (opt.startup_lc_ctype))) - err = gpg_error_from_syserror (); - - if (!err && !ctrl->lc_messages && opt.startup_lc_messages) - if (!(ctrl->lc_messages = xtrystrdup (opt.startup_lc_messages))) - err = gpg_error_from_syserror (); - - if (err) - { - log_error ("error setting default session environment: %s\n", - gpg_strerror (err)); - goto out; - } - } - + err = setup_ssh_env (ctrl); + if (err) + goto out; /* Create stream from socket. */ stream_sock = es_fdopen (FD2INT(sock_client), "r+");