On Wed, Apr 24, 2024, at 21:32, bryon wrote: > ssh client has the ability to set the destination of debug logs via the `-E` flag. ssh_config lacks an equivalent keyword to set the same option via configs. > > This patch follows the same semantics of other `*Path` type keywords and creates a new ssh_config keyword `LogPath`. > > [0] Bugzilla: https://bugzilla.mindrot.org/show_bug.cgi?id=3683 > [1] GitHub PR: https://github.com/openssh/openssh-portable/pull/491 > Updated patch below: - Moved the parsing of the config files slightly earlier to allow for configurations to be used for log output locations. - Updated ssh_config.5 to add documentation for `LogPath` PR also updated on github [0]. [0] https://github.com/openssh/openssh-portable/pull/491 --- readconf.c | 10 +++++++++- readconf.h | 1 + ssh.c | 22 ++++++++++++++-------- ssh_config.5 | 8 ++++++++ 4 files changed, 32 insertions(+), 9 deletions(-) diff --git a/readconf.c b/readconf.c index 3a64a0441..f7d2a9064 100644 --- a/readconf.c +++ b/readconf.c @@ -156,7 +156,7 @@ typedef enum { oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts, oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression, oTCPKeepAlive, oNumberOfPasswordPrompts, - oLogFacility, oLogLevel, oLogVerbose, oCiphers, oMacs, + oLogFacility, oLogLevel, oLogPath, oLogVerbose, oCiphers, oMacs, oPubkeyAuthentication, oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias, oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication, @@ -271,6 +271,7 @@ static struct { { "numberofpasswordprompts", oNumberOfPasswordPrompts }, { "syslogfacility", oLogFacility }, { "loglevel", oLogLevel }, + { "logpath", oLogPath }, { "logverbose", oLogVerbose }, { "dynamicforward", oDynamicForward }, { "preferredauthentications", oPreferredAuthentications }, @@ -1629,6 +1630,10 @@ parse_pubkey_algos: } break; + case oLogPath: + charptr = &options->log_path; + goto parse_string; + case oLocalForward: case oRemoteForward: case oDynamicForward: @@ -2585,6 +2590,7 @@ initialize_options(Options * options) options->num_permitted_remote_opens = 0; options->log_facility = SYSLOG_FACILITY_NOT_SET; options->log_level = SYSLOG_LEVEL_NOT_SET; + options->log_path = NULL; options->num_log_verbose = 0; options->log_verbose = NULL; options->preferred_authentications = NULL; @@ -2962,6 +2968,7 @@ free_options(Options *o) free(o->forward_agent_sock_path); free(o->xauth_location); FREE_ARRAY(u_int, o->num_log_verbose, o->log_verbose); + free(o->log_path); free(o->log_verbose); free(o->ciphers); free(o->macs); @@ -3584,6 +3591,7 @@ dump_client_config(Options *o, const char *host) dump_cfg_string(oLocalCommand, o->local_command); dump_cfg_string(oRemoteCommand, o->remote_command); dump_cfg_string(oLogLevel, log_level_name(o->log_level)); + dump_cfg_string(oLogPath, o->log_path); dump_cfg_string(oMacs, o->macs); #ifdef ENABLE_PKCS11 dump_cfg_string(oPKCS11Provider, o->pkcs11_provider); diff --git a/readconf.h b/readconf.h index 9447d5d6e..0137b6690 100644 --- a/readconf.h +++ b/readconf.h @@ -54,6 +54,7 @@ typedef struct { int ip_qos_bulk; /* IP ToS/DSCP/class for bulk traffic */ SyslogFacility log_facility; /* Facility for system logging. */ LogLevel log_level; /* Level for logging. */ + char *log_path; /* Path for debug logs. */ u_int num_log_verbose; /* Verbose log overrides */ char **log_verbose; int port; /* Port to connect. */ diff --git a/ssh.c b/ssh.c index 0019281f4..63c426592 100644 --- a/ssh.c +++ b/ssh.c @@ -670,7 +670,7 @@ main(int ac, char **av) struct ssh *ssh = NULL; int i, r, opt, exit_status, use_syslog, direct, timeout_ms; int was_addr, config_test = 0, opt_terminated = 0, want_final_pass = 0; - char *p, *cp, *line, *argv0, *logfile; + char *p, *cp, *line, *argv0; char cname[NI_MAXHOST], thishost[NI_MAXHOST]; struct stat st; struct passwd *pw; @@ -741,7 +741,6 @@ main(int ac, char **av) /* Parse command-line arguments. */ host = NULL; use_syslog = 0; - logfile = NULL; argv0 = av[0]; again: @@ -777,7 +776,8 @@ main(int ac, char **av) use_syslog = 1; break; case 'E': - logfile = optarg; + free(options.control_path); + options.log_path = xstrdup(optarg); break; case 'G': config_test = 1; @@ -1186,14 +1186,22 @@ main(int ac, char **av) ssh_signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE early */ + /* Parse the configuration files */ + process_config_files(options.host_arg, pw, 0, &want_final_pass); + /* * Initialize "log" output. Since we are the client all output * goes to stderr unless otherwise specified by -y or -E. */ - if (use_syslog && logfile != NULL) + if (use_syslog && options.log_path != NULL) fatal("Can't specify both -y and -E"); - if (logfile != NULL) - log_redirect_stderr_to(logfile); + if (options.log_path != NULL) { + p = tilde_expand_filename(options.log_path, getuid()); + options.log_path = p; + logit("Debug logging to file: %s", options.log_path); + log_redirect_stderr_to(options.log_path); + free(p); + } log_init(argv0, options.log_level == SYSLOG_LEVEL_NOT_SET ? SYSLOG_LEVEL_INFO : options.log_level, @@ -1204,8 +1212,6 @@ main(int ac, char **av) if (debug_flag) logit("%s, %s", SSH_RELEASE, SSH_OPENSSL_VERSION); - /* Parse the configuration files */ - process_config_files(options.host_arg, pw, 0, &want_final_pass); if (want_final_pass) debug("configuration requests final Match pass"); diff --git a/ssh_config.5 b/ssh_config.5 index 2931d807e..b61bd2df8 100644 --- a/ssh_config.5 +++ b/ssh_config.5 @@ -1393,6 +1393,14 @@ function, and all code in the .Pa packet.c file. This option is intended for debugging and no overrides are enabled by default. +.It Cm LogPath +Specify the path to the log file where debug logging should be appended. +Arguments to +.Cm LogPath +may use the tilde syntax to refer to a user's home directory and +environment variables as described in the +.Sx ENVIRONMENT VARIABLES +section. .It Cm MACs Specifies the MAC (message authentication code) algorithms in order of preference. -- 2.39.2 _______________________________________________ openssh-unix-dev mailing list openssh-unix-dev@xxxxxxxxxxx https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev