Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:cipriancraciun:opensuse-tumbleweed-extras
openssh
openssh-8.9p1-custom-3.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File openssh-8.9p1-custom-3.patch of Package openssh
From df59fbd1fffde1f4c06d4bda5a5d7fb3538dcc55 Mon Sep 17 00:00:00 2001 From: Ciprian Dorin Craciun <ciprian@volution.ro> Date: Fri, 7 Apr 2017 01:42:33 +0300 Subject: [PATCH 3/3] Add `PasswordCommand` option which overrides `SSH_ASKPASS` and should always provide a password (this is used only for login passwords) --- misc.h | 1 + readconf.c | 9 +++++++ readconf.h | 1 + readpass.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++ ssh.c | 10 ++++++++ sshconnect2.c | 5 +++- 6 files changed, 91 insertions(+), 1 deletion(-) diff --git a/misc.h b/misc.h index 2e1b5fec..f4b95df6 100644 --- a/misc.h +++ b/misc.h @@ -209,20 +209,21 @@ void opt_array_append2(const char *file, const int line, /* readpass.c */ #define RP_ECHO 0x0001 #define RP_ALLOW_STDIN 0x0002 #define RP_ALLOW_EOF 0x0004 #define RP_USE_ASKPASS 0x0008 struct notifier_ctx; char *read_passphrase(const char *, int); +char *read_passphrase_from_command(const char *); int ask_permission(const char *, ...) __attribute__((format(printf, 1, 2))); struct notifier_ctx *notify_start(int, const char *, ...) __attribute__((format(printf, 2, 3))); void notify_complete(struct notifier_ctx *, const char *, ...) __attribute__((format(printf, 2, 3))); #define MINIMUM(a, b) (((a) < (b)) ? (a) : (b)) #define MAXIMUM(a, b) (((a) > (b)) ? (a) : (b)) #define ROUNDUP(x, y) ((((x)+((y)-1))/(y))*(y)) diff --git a/readconf.c b/readconf.c index f26fabaa..8bbf9da4 100644 --- a/readconf.c +++ b/readconf.c @@ -168,20 +168,21 @@ typedef enum { oLocalCommand, oPermitLocalCommand, oRemoteCommand, oVisualHostKey, oKexAlgorithms, oIPQoS, oRequestTTY, oSessionType, oStdinNull, oForkAfterAuthentication, oIgnoreUnknown, oProxyUseFdpass, oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots, oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs, oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys, oFingerprintHash, oUpdateHostkeys, oHostbasedAcceptedAlgorithms, oPubkeyAcceptedAlgorithms, oCASignatureAlgorithms, oProxyJump, oSecurityKeyProvider, oKnownHostsCommand, + oPasswordCommand, oIgnore, oIgnoredUnknownOption, oDeprecated, oUnsupported } OpCodes; /* Textual representations of the tokens. */ static struct { const char *name; OpCodes opcode; } keywords[] = { /* Deprecated options */ @@ -313,20 +314,21 @@ static struct { { "fingerprinthash", oFingerprintHash }, { "updatehostkeys", oUpdateHostkeys }, { "hostbasedacceptedalgorithms", oHostbasedAcceptedAlgorithms }, { "hostbasedkeytypes", oHostbasedAcceptedAlgorithms }, /* obsolete */ { "pubkeyacceptedalgorithms", oPubkeyAcceptedAlgorithms }, { "pubkeyacceptedkeytypes", oPubkeyAcceptedAlgorithms }, /* obsolete */ { "ignoreunknown", oIgnoreUnknown }, { "proxyjump", oProxyJump }, { "securitykeyprovider", oSecurityKeyProvider }, { "knownhostscommand", oKnownHostsCommand }, + { "passwordcommand", oPasswordCommand }, { NULL, oBadOption } }; static const char *lookup_opcode_name(OpCodes code); const char * kex_default_pk_alg(void) { static char *pkalgs; @@ -2184,20 +2186,24 @@ parse_pubkey_algos: if (arg[0] == '$' && arg[1] != '{' && !valid_env_name(arg + 1)) { error("%.200s line %d: Invalid environment name %s.", filename, linenum, arg); goto out; } if (*activep && *charptr == NULL) *charptr = xstrdup(arg); break; + case oPasswordCommand: + charptr = &options->password_command; + goto parse_command; + case oDeprecated: debug("%s line %d: Deprecated option \"%s\"", filename, linenum, keyword); argv_consume(&ac); break; case oUnsupported: error("%s line %d: Unsupported option \"%s\"", filename, linenum, keyword); argv_consume(&ac); @@ -2431,20 +2437,21 @@ initialize_options(Options * options) options->num_permitted_cnames = 0; options->canonicalize_max_dots = -1; options->canonicalize_fallback_local = -1; options->canonicalize_hostname = -1; options->revoked_host_keys = NULL; options->fingerprint_hash = -1; options->update_hostkeys = -1; options->hostbased_accepted_algos = NULL; options->pubkey_accepted_algos = NULL; options->known_hosts_command = NULL; + options->password_command = NULL; } /* * A petite version of fill_default_options() that just fills the options * needed for hostname canonicalization to proceed. */ void fill_default_options_for_canonicalization(Options *options) { if (options->canonicalize_max_dots == -1) @@ -2671,20 +2678,21 @@ fill_default_options(Options * options) } \ } while(0) CLEAR_ON_NONE(options->local_command); CLEAR_ON_NONE(options->remote_command); CLEAR_ON_NONE(options->proxy_command); CLEAR_ON_NONE(options->control_path); CLEAR_ON_NONE(options->revoked_host_keys); CLEAR_ON_NONE(options->pkcs11_provider); CLEAR_ON_NONE(options->sk_provider); CLEAR_ON_NONE(options->known_hosts_command); + CLEAR_ON_NONE(options->password_command); if (options->jump_host != NULL && strcmp(options->jump_host, "none") == 0 && options->jump_port == 0 && options->jump_user == NULL) { free(options->jump_host); options->jump_host = NULL; } if (options->num_permitted_cnames == 1 && !config_has_permitted_cnames(options)) { /* clean up CanonicalizePermittedCNAMEs=none */ free(options->permitted_cnames[0].source_list); @@ -3343,20 +3351,21 @@ dump_client_config(Options *o, const char *host) dump_cfg_string(oMacs, o->macs); #ifdef ENABLE_PKCS11 dump_cfg_string(oPKCS11Provider, o->pkcs11_provider); #endif dump_cfg_string(oSecurityKeyProvider, o->sk_provider); dump_cfg_string(oPreferredAuthentications, o->preferred_authentications); dump_cfg_string(oPubkeyAcceptedAlgorithms, o->pubkey_accepted_algos); dump_cfg_string(oRevokedHostKeys, o->revoked_host_keys); dump_cfg_string(oXAuthLocation, o->xauth_location); dump_cfg_string(oKnownHostsCommand, o->known_hosts_command); + dump_cfg_string(oPasswordCommand, o->password_command); /* Forwards */ dump_cfg_forwards(oDynamicForward, o->num_local_forwards, o->local_forwards); dump_cfg_forwards(oLocalForward, o->num_local_forwards, o->local_forwards); dump_cfg_forwards(oRemoteForward, o->num_remote_forwards, o->remote_forwards); /* String array options */ dump_cfg_strarray(oIdentityFile, o->num_identity_files, o->identity_files); dump_cfg_strarray_oneline(oCanonicalDomains, o->num_canonical_domains, o->canonical_domains); dump_cfg_strarray(oCertificateFile, o->num_certificate_files, o->certificate_files); diff --git a/readconf.h b/readconf.h index ded13c94..e935eb4e 100644 --- a/readconf.h +++ b/readconf.h @@ -168,20 +168,21 @@ typedef struct { char *hostbased_accepted_algos; char *pubkey_accepted_algos; char *jump_user; char *jump_host; int jump_port; char *jump_extra; char *known_hosts_command; + char *password_command; char *ignored_unknown; /* Pattern list of unknown tokens to ignore */ } Options; #define SSH_PUBKEY_AUTH_NO 0x00 #define SSH_PUBKEY_AUTH_UNBOUND 0x01 #define SSH_PUBKEY_AUTH_HBOUND 0x02 #define SSH_PUBKEY_AUTH_ALL 0x03 #define SSH_CANONICALISE_NO 0 diff --git a/readpass.c b/readpass.c index 39af25c8..f82e6003 100644 --- a/readpass.c +++ b/readpass.c @@ -322,10 +322,76 @@ notify_complete(struct notifier_ctx *ctx, const char *fmt, ...) kill(ctx->pid, SIGTERM); while ((ret = waitpid(ctx->pid, NULL, 0)) == -1) { if (errno != EINTR) break; } if (ret == -1) fatal_f("waitpid: %s", strerror(errno)); ssh_signal(SIGCHLD, ctx->osigchld); free(ctx); } + +char * +read_passphrase_from_command(const char *command) +{ + char *shell; + pid_t pid, ret; + size_t len; + char *pass; + int p[2], status; + char buf[1024]; + void (*osigchld)(int); + + if ((shell = getenv("SHELL")) == NULL || *shell == '\0') + shell = _PATH_BSHELL; + + if (fflush(stdout) != 0) + error("password_command: fflush: %s", strerror(errno)); + if (shell == NULL) + fatal("internal error: shell undefined"); + if (pipe(p) < 0) { + error("password_command: pipe: %s", strerror(errno)); + return NULL; + } + osigchld = signal(SIGCHLD, SIG_DFL); + if ((pid = fork()) < 0) { + error("password_command: fork: %s", strerror(errno)); + signal(SIGCHLD, osigchld); + return NULL; + } + if (pid == 0) { + close(p[0]); + if (dup2(p[1], STDOUT_FILENO) < 0) + fatal("password_command: dup2: %s", strerror(errno)); + debug3("Executing (via shell %s): %s", shell, command); + execlp(shell, shell, "-c", command, (char *)NULL); + fatal("password_command: exec(%s): %s", command, strerror(errno)); + } + close(p[1]); + + len = 0; + do { + ssize_t r = read(p[0], buf + len, sizeof(buf) - 1 - len); + + if (r == -1 && errno == EINTR) + continue; + if (r <= 0) + break; + len += r; + } while (sizeof(buf) - 1 - len > 0); + buf[len] = '\0'; + + close(p[0]); + while ((ret = waitpid(pid, &status, 0)) < 0) + if (errno != EINTR) + break; + signal(SIGCHLD, osigchld); + if (ret == -1 || !WIFEXITED(status) || WEXITSTATUS(status) != 0) { + explicit_bzero(buf, sizeof(buf)); + return NULL; + } + + buf[strcspn(buf, "\r\n")] = '\0'; + pass = xstrdup(buf); + explicit_bzero(buf, sizeof(buf)); + return pass; +} diff --git a/ssh.c b/ssh.c index 8ff97881..a355a6d0 100644 --- a/ssh.c +++ b/ssh.c @@ -1384,20 +1384,30 @@ main(int ac, char **av) cp = options.remote_command; options.remote_command = default_client_percent_expand(cp, cinfo); debug3("expanded RemoteCommand: %s", options.remote_command); free(cp); if ((r = sshbuf_put(command, options.remote_command, strlen(options.remote_command))) != 0) fatal_fr(r, "buffer error"); } + if (options.password_command != NULL) { + debug3("expanding PasswordCommand: %s", options.password_command); + cp = options.password_command; + options.password_command = default_client_percent_expand(cp, + cinfo); + debug3("expanded PasswordCommand: %s", options.password_command); + free(cp); + } + + if (options.control_path != NULL) { cp = tilde_expand_filename(options.control_path, getuid()); free(options.control_path); options.control_path = default_client_percent_dollar_expand(cp, cinfo); free(cp); } if (options.identity_agent != NULL) { p = tilde_expand_filename(options.identity_agent, getuid()); diff --git a/sshconnect2.c b/sshconnect2.c index b25225e6..a7ba2948 100644 --- a/sshconnect2.c +++ b/sshconnect2.c @@ -1064,21 +1064,24 @@ userauth_passwd(struct ssh *ssh) authctxt->host; int r; if (authctxt->attempt_passwd++ >= options.number_of_password_prompts) return 0; if (authctxt->attempt_passwd != 1) error("Permission denied, please try again."); xasprintf(&prompt, "%s@%s's password: ", authctxt->server_user, host); - password = read_passphrase(prompt, 0); + if (options.password_command == NULL) + password = read_passphrase(prompt, 0); + else + password = read_passphrase_from_command(options.password_command); if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 || (r = sshpkt_put_cstring(ssh, authctxt->server_user)) != 0 || (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 || (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 || (r = sshpkt_put_u8(ssh, 0)) != 0 || (r = sshpkt_put_cstring(ssh, password)) != 0 || (r = sshpkt_add_padding(ssh, 64)) != 0 || (r = sshpkt_send(ssh)) != 0) fatal_fr(r, "send packet"); -- 2.36.1
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor