Converge fork and upstream branches
- Removed #ifdef WINDOWS blocks in base code where the feature support can be conveyed by a failed POSIX API call - Refactored password authentication code - Other misc changes - Removed DebugBreak on Release Builds
This commit is contained in:
parent
8ff5517c3a
commit
cc16f80123
|
@ -55,12 +55,7 @@
|
||||||
#include "hostfile.h"
|
#include "hostfile.h"
|
||||||
#include "auth.h"
|
#include "auth.h"
|
||||||
#include "auth-options.h"
|
#include "auth-options.h"
|
||||||
#include "authfd.h"
|
|
||||||
|
|
||||||
#ifdef WINDOWS
|
|
||||||
#include "w32api_proxies.h"
|
|
||||||
#include "misc_internal.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern struct sshbuf *loginmsg;
|
extern struct sshbuf *loginmsg;
|
||||||
extern ServerOptions options;
|
extern ServerOptions options;
|
||||||
|
@ -117,6 +112,14 @@ auth_password(struct ssh *ssh, const char *password)
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef WINDOWS
|
||||||
|
{
|
||||||
|
int windows_password_auth(const char *, const char *);
|
||||||
|
if (windows_password_auth(pw->pw_name, password) == 0)
|
||||||
|
return 0;
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#ifdef USE_PAM
|
#ifdef USE_PAM
|
||||||
if (options.use_pam)
|
if (options.use_pam)
|
||||||
return (sshpam_auth_passwd(authctxt, password) && ok);
|
return (sshpam_auth_passwd(authctxt, password) && ok);
|
||||||
|
@ -227,84 +230,4 @@ sys_auth_passwd(struct ssh *ssh, const char *password)
|
||||||
strcmp(encrypted_password, pw_password) == 0;
|
strcmp(encrypted_password, pw_password) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif defined(WINDOWS)
|
#endif
|
||||||
HANDLE password_auth_token = NULL;
|
|
||||||
HANDLE process_custom_lsa_auth(const char*, const char*, const char*);
|
|
||||||
char* get_custom_lsa_package();
|
|
||||||
/*
|
|
||||||
* Authenticate on Windows
|
|
||||||
* - Call LogonUser and retrieve user token
|
|
||||||
* - If LogonUser fails, then try the LSA (Local Security Authority) authentication.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
sys_auth_passwd(struct ssh *ssh, const char *password)
|
|
||||||
{
|
|
||||||
wchar_t *user_utf16 = NULL, *pwd_utf16 = NULL, *unam_utf16 = NULL, *udom_utf16 = L".";
|
|
||||||
Authctxt *authctxt = ssh->authctxt;
|
|
||||||
HANDLE token = NULL;
|
|
||||||
WCHAR domain_upn[MAX_UPN_LEN + 1];
|
|
||||||
ULONG domain_upn_len = ARRAYSIZE(domain_upn);
|
|
||||||
|
|
||||||
user_utf16 = utf8_to_utf16(authctxt->pw->pw_name);
|
|
||||||
pwd_utf16 = utf8_to_utf16(password);
|
|
||||||
if (user_utf16 == NULL || pwd_utf16 == NULL) {
|
|
||||||
debug("out of memory");
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* the format for the user will be constrained to the output of get_passwd()
|
|
||||||
* so only the only two formats are NetBiosDomain\SamAccountName which is
|
|
||||||
* a domain account or just SamAccountName in which is a local account */
|
|
||||||
|
|
||||||
/* default assumption - local user */
|
|
||||||
unam_utf16 = user_utf16;
|
|
||||||
|
|
||||||
/* translate to domain user if format contains a backslash */
|
|
||||||
wchar_t * backslash = wcschr(user_utf16, L'\\');
|
|
||||||
if (backslash != NULL) {
|
|
||||||
|
|
||||||
/* attempt to format into upn format as this is preferred for login */
|
|
||||||
if (lookup_principal_name(user_utf16, domain_upn) == 0) {
|
|
||||||
unam_utf16 = domain_upn;
|
|
||||||
udom_utf16 = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* could not discover upn so just use netbios for the domain parameter and
|
|
||||||
* the sam account name for the user name */
|
|
||||||
else {
|
|
||||||
*backslash = '\0';
|
|
||||||
unam_utf16 = backslash + 1;
|
|
||||||
udom_utf16 = user_utf16;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pLogonUserExExW(unam_utf16, udom_utf16, pwd_utf16, LOGON32_LOGON_NETWORK_CLEARTEXT,
|
|
||||||
LOGON32_PROVIDER_DEFAULT, NULL, &token, NULL, NULL, NULL, NULL) == TRUE)
|
|
||||||
password_auth_token = token;
|
|
||||||
else {
|
|
||||||
if (GetLastError() == ERROR_PASSWORD_MUST_CHANGE)
|
|
||||||
/*
|
|
||||||
* TODO - need to add support to force password change
|
|
||||||
* by sending back SSH_MSG_USERAUTH_PASSWD_CHANGEREQ
|
|
||||||
*/
|
|
||||||
error("password for user %s has expired", authctxt->pw->pw_name);
|
|
||||||
else {
|
|
||||||
debug("Windows authentication failed for user: %ls domain: %ls error: %d",
|
|
||||||
unam_utf16, udom_utf16, GetLastError());
|
|
||||||
|
|
||||||
/* If LSA authentication package is configured then it will return the auth_token */
|
|
||||||
if (get_custom_lsa_package())
|
|
||||||
password_auth_token = process_custom_lsa_auth(authctxt->pw->pw_name, password, get_custom_lsa_package());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
done:
|
|
||||||
|
|
||||||
if (user_utf16)
|
|
||||||
free(user_utf16);
|
|
||||||
if (pwd_utf16)
|
|
||||||
SecureZeroMemory(pwd_utf16, sizeof(wchar_t) * wcslen(pwd_utf16));
|
|
||||||
|
|
||||||
return (password_auth_token) ? 1 : 0;
|
|
||||||
}
|
|
||||||
#endif /* WINDOWS */
|
|
|
@ -67,7 +67,6 @@
|
||||||
#include "ssherr.h"
|
#include "ssherr.h"
|
||||||
#include "channels.h" /* XXX for session.h */
|
#include "channels.h" /* XXX for session.h */
|
||||||
#include "session.h" /* XXX for child_set_env(); refactor? */
|
#include "session.h" /* XXX for child_set_env(); refactor? */
|
||||||
#include "authfd.h"
|
|
||||||
|
|
||||||
/* import */
|
/* import */
|
||||||
extern ServerOptions options;
|
extern ServerOptions options;
|
||||||
|
|
1
authfd.h
1
authfd.h
|
@ -41,7 +41,6 @@ int ssh_agent_sign(int sock, const struct sshkey *key,
|
||||||
const u_char *data, size_t datalen, const char *alg, u_int compat);
|
const u_char *data, size_t datalen, const char *alg, u_int compat);
|
||||||
|
|
||||||
/* Messages for the authentication agent connection. */
|
/* Messages for the authentication agent connection. */
|
||||||
/* Message Id 0 is reserved */
|
|
||||||
#define SSH_AGENTC_REQUEST_RSA_IDENTITIES 1
|
#define SSH_AGENTC_REQUEST_RSA_IDENTITIES 1
|
||||||
#define SSH_AGENT_RSA_IDENTITIES_ANSWER 2
|
#define SSH_AGENT_RSA_IDENTITIES_ANSWER 2
|
||||||
#define SSH_AGENTC_RSA_CHALLENGE 3
|
#define SSH_AGENTC_RSA_CHALLENGE 3
|
||||||
|
|
|
@ -2313,7 +2313,6 @@ channel_post_mux_listener(struct ssh *ssh, Channel *c,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef WINDOWS /*TODO - implement user check for Windows*/
|
|
||||||
if (getpeereid(newsock, &euid, &egid) < 0) {
|
if (getpeereid(newsock, &euid, &egid) < 0) {
|
||||||
error("%s getpeereid failed: %s", __func__,
|
error("%s getpeereid failed: %s", __func__,
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
|
@ -2326,7 +2325,7 @@ channel_post_mux_listener(struct ssh *ssh, Channel *c,
|
||||||
close(newsock);
|
close(newsock);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif /* !WINDOWS */
|
|
||||||
nc = channel_new(ssh, "multiplex client", SSH_CHANNEL_MUX_CLIENT,
|
nc = channel_new(ssh, "multiplex client", SSH_CHANNEL_MUX_CLIENT,
|
||||||
newsock, newsock, -1, c->local_window_max,
|
newsock, newsock, -1, c->local_window_max,
|
||||||
c->local_maxpacket, 0, "mux-control", 1);
|
c->local_maxpacket, 0, "mux-control", 1);
|
||||||
|
|
|
@ -1071,9 +1071,6 @@ process_escapes(struct ssh *ssh, Channel *c,
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case '&':
|
case '&':
|
||||||
#ifdef WINDOWS
|
|
||||||
fatal("Background execution is not supported in Windows");
|
|
||||||
#else /* !WINDOWS */
|
|
||||||
if (c && c->ctl_chan != -1)
|
if (c && c->ctl_chan != -1)
|
||||||
goto noescape;
|
goto noescape;
|
||||||
/*
|
/*
|
||||||
|
@ -1110,7 +1107,6 @@ process_escapes(struct ssh *ssh, Channel *c,
|
||||||
fatal("%s: buffer error: %s",
|
fatal("%s: buffer error: %s",
|
||||||
__func__, ssh_err(r));
|
__func__, ssh_err(r));
|
||||||
return -1;
|
return -1;
|
||||||
#endif /* !WINDOWS */
|
|
||||||
case '?':
|
case '?':
|
||||||
print_escape_help(berr, efc->escape_char,
|
print_escape_help(berr, efc->escape_char,
|
||||||
(c && c->ctl_chan != -1),
|
(c && c->ctl_chan != -1),
|
||||||
|
|
|
@ -663,7 +663,7 @@ WriteCompletionRoutine(_In_ DWORD dwErrorCode,
|
||||||
if ((dwErrorCode == 0) && (pio->write_details.remaining != dwNumberOfBytesTransfered)) {
|
if ((dwErrorCode == 0) && (pio->write_details.remaining != dwNumberOfBytesTransfered)) {
|
||||||
error("WriteCB - ERROR: broken assumption, io:%p, wrote:%d, remaining:%d", pio,
|
error("WriteCB - ERROR: broken assumption, io:%p, wrote:%d, remaining:%d", pio,
|
||||||
dwNumberOfBytesTransfered, pio->write_details.remaining);
|
dwNumberOfBytesTransfered, pio->write_details.remaining);
|
||||||
DebugBreak();
|
debug_assert_internal();
|
||||||
}
|
}
|
||||||
pio->write_details.remaining -= dwNumberOfBytesTransfered;
|
pio->write_details.remaining -= dwNumberOfBytesTransfered;
|
||||||
pio->write_details.pending = FALSE;
|
pio->write_details.pending = FALSE;
|
||||||
|
|
|
@ -32,6 +32,8 @@ int setgid(gid_t gid);
|
||||||
int seteuid(uid_t uid);
|
int seteuid(uid_t uid);
|
||||||
int setegid(gid_t gid);
|
int setegid(gid_t gid);
|
||||||
char *user_from_uid(uid_t uid, int nouser);
|
char *user_from_uid(uid_t uid, int nouser);
|
||||||
|
struct passwd *getpwent(void);
|
||||||
|
void setpwent(void);
|
||||||
|
|
||||||
/*end - declarations not applicable in Windows */
|
/*end - declarations not applicable in Windows */
|
||||||
|
|
||||||
|
|
|
@ -4,3 +4,5 @@
|
||||||
#define environ _environ
|
#define environ _environ
|
||||||
void freezero(void *, size_t);
|
void freezero(void *, size_t);
|
||||||
int setenv(const char *name, const char *value, int rewrite);
|
int setenv(const char *name, const char *value, int rewrite);
|
||||||
|
#define system w32_system
|
||||||
|
int w32_system(const char *command);
|
||||||
|
|
|
@ -82,6 +82,8 @@ int w32_readlink(const char *path, char *link, int linklen);
|
||||||
int w32_link(const char *oldpath, const char *newpath);
|
int w32_link(const char *oldpath, const char *newpath);
|
||||||
#define link w32_link
|
#define link w32_link
|
||||||
|
|
||||||
|
int getpeereid(int, uid_t*, gid_t*);
|
||||||
|
|
||||||
int daemon(int nochdir, int noclose);
|
int daemon(int nochdir, int noclose);
|
||||||
char *crypt(const char *key, const char *salt);
|
char *crypt(const char *key, const char *salt);
|
||||||
int chroot(const char *path);
|
int chroot(const char *path);
|
||||||
|
|
|
@ -1812,3 +1812,68 @@ bash_to_win_path(const char *in, char *out, const size_t out_len)
|
||||||
|
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
getpeereid(int s, uid_t *euid, gid_t *egid)
|
||||||
|
{
|
||||||
|
verbose("%s is not supported", __func__);
|
||||||
|
errno = ENOTSUP;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
getrrsetbyname(const char *hostname, unsigned int rdclass,
|
||||||
|
unsigned int rdtype, unsigned int flags,
|
||||||
|
struct rrsetinfo **res)
|
||||||
|
{
|
||||||
|
verbose("%s is not supported", __func__);
|
||||||
|
errno = ENOTSUP;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
freerrset(struct rrsetinfo *rrset)
|
||||||
|
{
|
||||||
|
verbose("%s is not supported", __func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
debug_assert_internal()
|
||||||
|
{
|
||||||
|
/* debug break on non-release builds */
|
||||||
|
#ifndef NDEBUG
|
||||||
|
DebugBreak();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
char
|
||||||
|
*crypt(const char *key, const char *salt)
|
||||||
|
{
|
||||||
|
verbose("%s is not supported", __func__);
|
||||||
|
errno = ENOTSUP;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
w32_system(const char *command)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
wchar_t *command_w = NULL;
|
||||||
|
|
||||||
|
if (!command) {
|
||||||
|
errno = ENOTSUP;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((command_w = utf8_to_utf16(command)) == NULL)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
ret = _wsystem(command_w);
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (command_w)
|
||||||
|
free(command_w);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
|
@ -78,3 +78,4 @@ wchar_t* get_final_path_by_handle(HANDLE h);
|
||||||
int lookup_principal_name(const wchar_t * sam_account_name, wchar_t * user_principal_name);
|
int lookup_principal_name(const wchar_t * sam_account_name, wchar_t * user_principal_name);
|
||||||
BOOL is_bash_test_env();
|
BOOL is_bash_test_env();
|
||||||
int bash_to_win_path(const char *in, char *out, const size_t out_len);
|
int bash_to_win_path(const char *in, char *out, const size_t out_len);
|
||||||
|
void debug_assert_internal();
|
||||||
|
|
|
@ -416,6 +416,16 @@ setegid(gid_t gid)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct passwd *getpwent(void)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setpwent(void)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
endpwent(void)
|
endpwent(void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -219,7 +219,7 @@ sw_process_pending_signals()
|
||||||
/* unexpected signals queued up */
|
/* unexpected signals queued up */
|
||||||
error("process_signals() - ERROR unexpected signals in queue: %d", pending_tmp);
|
error("process_signals() - ERROR unexpected signals in queue: %d", pending_tmp);
|
||||||
errno = ENOTSUP;
|
errno = ENOTSUP;
|
||||||
DebugBreak();
|
debug_assert_internal();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -244,7 +244,7 @@ sw_process_pending_signals()
|
||||||
|
|
||||||
/* by now all pending signals should have been taken care of*/
|
/* by now all pending signals should have been taken care of*/
|
||||||
if (pending_tmp)
|
if (pending_tmp)
|
||||||
DebugBreak();
|
debug_assert_internal();
|
||||||
|
|
||||||
if (sig_int) {
|
if (sig_int) {
|
||||||
debug4("process_queued_signals: WARNING - A signal has interrupted and was processed");
|
debug4("process_queued_signals: WARNING - A signal has interrupted and was processed");
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#include <process.h>
|
#include <process.h>
|
||||||
|
#include "misc_internal.h"
|
||||||
|
|
||||||
/* child processes */
|
/* child processes */
|
||||||
#define MAX_CHILDREN 512
|
#define MAX_CHILDREN 512
|
||||||
|
|
|
@ -157,13 +157,13 @@ waitpid(int pid, int *status, int options)
|
||||||
debug5("waitpid - pid:%d, options:%d", pid, options);
|
debug5("waitpid - pid:%d, options:%d", pid, options);
|
||||||
if (options & (~WNOHANG)) {
|
if (options & (~WNOHANG)) {
|
||||||
errno = ENOTSUP;
|
errno = ENOTSUP;
|
||||||
DebugBreak();
|
debug_assert_internal();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((pid < -1) || (pid == 0)) {
|
if ((pid < -1) || (pid == 0)) {
|
||||||
errno = ENOTSUP;
|
errno = ENOTSUP;
|
||||||
DebugBreak();
|
debug_assert_internal();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,7 +175,7 @@ waitpid(int pid, int *status, int options)
|
||||||
if (pid > 0) {
|
if (pid > 0) {
|
||||||
if (options != 0) {
|
if (options != 0) {
|
||||||
errno = ENOTSUP;
|
errno = ENOTSUP;
|
||||||
DebugBreak();
|
debug_assert_internal();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
/* find entry in table */
|
/* find entry in table */
|
||||||
|
@ -194,7 +194,7 @@ waitpid(int pid, int *status, int options)
|
||||||
if (index < children.num_children - children.num_zombies) {
|
if (index < children.num_children - children.num_zombies) {
|
||||||
ret = WaitForSingleObject(process, INFINITE);
|
ret = WaitForSingleObject(process, INFINITE);
|
||||||
if (ret != WAIT_OBJECT_0)
|
if (ret != WAIT_OBJECT_0)
|
||||||
DebugBreak();//fatal
|
debug_assert_internal();//fatal
|
||||||
}
|
}
|
||||||
|
|
||||||
ret_id = children.process_id[index];
|
ret_id = children.process_id[index];
|
||||||
|
@ -238,7 +238,7 @@ waitpid(int pid, int *status, int options)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DebugBreak(); /* fatal */
|
debug_assert_internal(); /* fatal */
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include "w32fd.h"
|
#include "w32fd.h"
|
||||||
#include "inc\utf.h"
|
#include "inc\utf.h"
|
||||||
|
#include "misc_internal.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
#define INTERNAL_SEND_BUFFER_SIZE 70*1024 //70KB
|
#define INTERNAL_SEND_BUFFER_SIZE 70*1024 //70KB
|
||||||
|
@ -504,7 +505,7 @@ CALLBACK WSASendCompletionRoutine(IN DWORD dwError,
|
||||||
if ((dwError == 0) && (pio->write_details.remaining != cbTransferred)) {
|
if ((dwError == 0) && (pio->write_details.remaining != cbTransferred)) {
|
||||||
error("WSASendCB - ERROR: broken assumption, io:%p, sent:%d, remaining:%d", pio,
|
error("WSASendCB - ERROR: broken assumption, io:%p, sent:%d, remaining:%d", pio,
|
||||||
cbTransferred, pio->write_details.remaining);
|
cbTransferred, pio->write_details.remaining);
|
||||||
DebugBreak();
|
debug_assert_internal();
|
||||||
}
|
}
|
||||||
pio->write_details.remaining -= cbTransferred;
|
pio->write_details.remaining -= cbTransferred;
|
||||||
pio->write_details.pending = FALSE;
|
pio->write_details.pending = FALSE;
|
||||||
|
@ -637,7 +638,7 @@ socketio_close(struct w32_io* pio)
|
||||||
(pio->read_details.pending || pio->write_details.pending)) {
|
(pio->read_details.pending || pio->write_details.pending)) {
|
||||||
error("close - IO is still pending on closed socket. read:%d, write:%d, io:%p",
|
error("close - IO is still pending on closed socket. read:%d, write:%d, io:%p",
|
||||||
pio->read_details.pending, pio->write_details.pending, pio);
|
pio->read_details.pending, pio->write_details.pending, pio);
|
||||||
DebugBreak();
|
debug_assert_internal();
|
||||||
}
|
}
|
||||||
if (pio->internal.state == SOCK_LISTENING) {
|
if (pio->internal.state == SOCK_LISTENING) {
|
||||||
if (pio->read_overlapped.hEvent)
|
if (pio->read_overlapped.hEvent)
|
||||||
|
|
|
@ -55,7 +55,7 @@ agent_connection_on_io(struct agent_connection* con, DWORD bytes, OVERLAPPED* ol
|
||||||
if ((bytes == 0) && (GetOverlappedResult(con->pipe_handle, ol, &bytes, FALSE) == FALSE))
|
if ((bytes == 0) && (GetOverlappedResult(con->pipe_handle, ol, &bytes, FALSE) == FALSE))
|
||||||
ABORT_CONNECTION_RETURN(con);
|
ABORT_CONNECTION_RETURN(con);
|
||||||
if (con->state == DONE)
|
if (con->state == DONE)
|
||||||
DebugBreak();
|
debug_assert_internal();
|
||||||
|
|
||||||
switch (con->state) {
|
switch (con->state) {
|
||||||
case LISTENING:
|
case LISTENING:
|
||||||
|
@ -63,7 +63,7 @@ agent_connection_on_io(struct agent_connection* con, DWORD bytes, OVERLAPPED* ol
|
||||||
/* Writing is done, read next request */
|
/* Writing is done, read next request */
|
||||||
/* assert on assumption that write always completes on sending all bytes*/
|
/* assert on assumption that write always completes on sending all bytes*/
|
||||||
if (bytes != con->io_buf.num_bytes)
|
if (bytes != con->io_buf.num_bytes)
|
||||||
DebugBreak();
|
debug_assert_internal();
|
||||||
con->state = READING_HEADER;
|
con->state = READING_HEADER;
|
||||||
ZeroMemory(&con->io_buf, sizeof(con->io_buf));
|
ZeroMemory(&con->io_buf, sizeof(con->io_buf));
|
||||||
if (!ReadFile(con->pipe_handle, con->io_buf.buf,
|
if (!ReadFile(con->pipe_handle, con->io_buf.buf,
|
||||||
|
@ -105,7 +105,7 @@ agent_connection_on_io(struct agent_connection* con, DWORD bytes, OVERLAPPED* ol
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
DebugBreak();
|
debug_assert_internal();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -132,7 +132,7 @@ done:
|
||||||
if (0 == QueueUserAPC(ReadAPCProc, main_thread, (ULONG_PTR)pio)) {
|
if (0 == QueueUserAPC(ReadAPCProc, main_thread, (ULONG_PTR)pio)) {
|
||||||
pio->read_details.pending = FALSE;
|
pio->read_details.pending = FALSE;
|
||||||
pio->read_details.error = GetLastError();
|
pio->read_details.error = GetLastError();
|
||||||
DebugBreak();
|
debug_assert_internal();
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -217,7 +217,7 @@ WriteThread(_In_ LPVOID lpParameter)
|
||||||
error("WriteThread thread - ERROR QueueUserAPC failed %d, io:%p", GetLastError(), pio);
|
error("WriteThread thread - ERROR QueueUserAPC failed %d, io:%p", GetLastError(), pio);
|
||||||
pio->write_details.pending = FALSE;
|
pio->write_details.pending = FALSE;
|
||||||
pio->write_details.error = GetLastError();
|
pio->write_details.error = GetLastError();
|
||||||
DebugBreak();
|
debug_assert_internal();
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -227,11 +227,11 @@ w32posix_initialize()
|
||||||
{
|
{
|
||||||
init_prog_paths();
|
init_prog_paths();
|
||||||
if ((fd_table_initialize() != 0) || (socketio_initialize() != 0))
|
if ((fd_table_initialize() != 0) || (socketio_initialize() != 0))
|
||||||
DebugBreak();
|
debug_assert_internal();
|
||||||
main_thread = OpenThread(THREAD_SET_CONTEXT | SYNCHRONIZE, FALSE, GetCurrentThreadId());
|
main_thread = OpenThread(THREAD_SET_CONTEXT | SYNCHRONIZE, FALSE, GetCurrentThreadId());
|
||||||
if (main_thread == NULL ||
|
if (main_thread == NULL ||
|
||||||
sw_initialize() != 0 ) {
|
sw_initialize() != 0 ) {
|
||||||
DebugBreak();
|
debug_assert_internal();
|
||||||
fatal("failed to initialize w32posix wrapper");
|
fatal("failed to initialize w32posix wrapper");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -327,6 +327,12 @@ w32_accept(int fd, struct sockaddr* addr, int* addrlen)
|
||||||
if (min_index == -1)
|
if (min_index == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
if (fd_table.w32_ios[fd]->type == NONSOCK_FD) {
|
||||||
|
errno = ENOTSUP;
|
||||||
|
verbose("Unix domain server sockets are not supported");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
pio = socketio_accept(fd_table.w32_ios[fd], addr, addrlen);
|
pio = socketio_accept(fd_table.w32_ios[fd], addr, addrlen);
|
||||||
if (!pio)
|
if (!pio)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -373,6 +379,12 @@ int
|
||||||
w32_listen(int fd, int backlog)
|
w32_listen(int fd, int backlog)
|
||||||
{
|
{
|
||||||
CHECK_FD(fd);
|
CHECK_FD(fd);
|
||||||
|
if (fd_table.w32_ios[fd]->type == NONSOCK_FD) {
|
||||||
|
errno = ENOTSUP;
|
||||||
|
verbose("Unix domain server sockets are not supported");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
CHECK_SOCK_IO(fd_table.w32_ios[fd]);
|
CHECK_SOCK_IO(fd_table.w32_ios[fd]);
|
||||||
return socketio_listen(fd_table.w32_ios[fd], backlog);
|
return socketio_listen(fd_table.w32_ios[fd], backlog);
|
||||||
}
|
}
|
||||||
|
@ -381,6 +393,12 @@ int
|
||||||
w32_bind(int fd, const struct sockaddr *name, int namelen)
|
w32_bind(int fd, const struct sockaddr *name, int namelen)
|
||||||
{
|
{
|
||||||
CHECK_FD(fd);
|
CHECK_FD(fd);
|
||||||
|
if (fd_table.w32_ios[fd]->type == NONSOCK_FD) {
|
||||||
|
errno = ENOTSUP;
|
||||||
|
verbose("Unix domain server sockets are not supported");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
CHECK_SOCK_IO(fd_table.w32_ios[fd]);
|
CHECK_SOCK_IO(fd_table.w32_ios[fd]);
|
||||||
return socketio_bind(fd_table.w32_ios[fd], name, namelen);
|
return socketio_bind(fd_table.w32_ios[fd], name, namelen);
|
||||||
}
|
}
|
||||||
|
@ -1013,7 +1031,7 @@ w32_fsync(int fd)
|
||||||
|
|
||||||
int fork()
|
int fork()
|
||||||
{
|
{
|
||||||
error("fork is not supported");
|
verbose("fork is not supported");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,7 @@
|
||||||
#include "inc\pwd.h"
|
#include "inc\pwd.h"
|
||||||
|
|
||||||
#pragma warning(push, 3)
|
#pragma warning(push, 3)
|
||||||
|
HANDLE password_auth_token = NULL;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
InitLsaString(LSA_STRING *lsa_string, const char *str)
|
InitLsaString(LSA_STRING *lsa_string, const char *str)
|
||||||
|
@ -769,4 +770,76 @@ int lookup_principal_name(const wchar_t * sam_account_name, wchar_t * user_princ
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
windows_password_auth(const char *username, const char* password)
|
||||||
|
{
|
||||||
|
wchar_t *user_utf16 = NULL, *pwd_utf16 = NULL, *unam_utf16 = NULL, *udom_utf16 = L".";
|
||||||
|
HANDLE token = NULL;
|
||||||
|
WCHAR domain_upn[MAX_UPN_LEN + 1];
|
||||||
|
ULONG domain_upn_len = ARRAYSIZE(domain_upn);
|
||||||
|
|
||||||
|
user_utf16 = utf8_to_utf16(username);
|
||||||
|
pwd_utf16 = utf8_to_utf16(password);
|
||||||
|
if (user_utf16 == NULL || pwd_utf16 == NULL) {
|
||||||
|
debug("out of memory");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* the format for the user will be constrained to the output of get_passwd()
|
||||||
|
* so only the only two formats are NetBiosDomain\SamAccountName which is
|
||||||
|
* a domain account or just SamAccountName in which is a local account */
|
||||||
|
|
||||||
|
/* default assumption - local user */
|
||||||
|
unam_utf16 = user_utf16;
|
||||||
|
|
||||||
|
/* translate to domain user if format contains a backslash */
|
||||||
|
wchar_t * backslash = wcschr(user_utf16, L'\\');
|
||||||
|
if (backslash != NULL) {
|
||||||
|
|
||||||
|
/* attempt to format into upn format as this is preferred for login */
|
||||||
|
if (lookup_principal_name(user_utf16, domain_upn) == 0) {
|
||||||
|
unam_utf16 = domain_upn;
|
||||||
|
udom_utf16 = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* could not discover upn so just use netbios for the domain parameter and
|
||||||
|
* the sam account name for the user name */
|
||||||
|
else {
|
||||||
|
*backslash = '\0';
|
||||||
|
unam_utf16 = backslash + 1;
|
||||||
|
udom_utf16 = user_utf16;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pLogonUserExExW(unam_utf16, udom_utf16, pwd_utf16, LOGON32_LOGON_NETWORK_CLEARTEXT,
|
||||||
|
LOGON32_PROVIDER_DEFAULT, NULL, &token, NULL, NULL, NULL, NULL) == TRUE)
|
||||||
|
password_auth_token = token;
|
||||||
|
else {
|
||||||
|
if (GetLastError() == ERROR_PASSWORD_MUST_CHANGE)
|
||||||
|
/*
|
||||||
|
* TODO - need to add support to force password change
|
||||||
|
* by sending back SSH_MSG_USERAUTH_PASSWD_CHANGEREQ
|
||||||
|
*/
|
||||||
|
error("password for user %s has expired", username);
|
||||||
|
else {
|
||||||
|
debug("Windows authentication failed for user: %ls domain: %ls error: %d",
|
||||||
|
unam_utf16, udom_utf16, GetLastError());
|
||||||
|
|
||||||
|
/* If LSA authentication package is configured then it will return the auth_token */
|
||||||
|
if (get_custom_lsa_package())
|
||||||
|
password_auth_token = process_custom_lsa_auth(username, password, get_custom_lsa_package());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
|
||||||
|
if (user_utf16)
|
||||||
|
free(user_utf16);
|
||||||
|
if (pwd_utf16)
|
||||||
|
SecureZeroMemory(pwd_utf16, sizeof(wchar_t) * wcslen(pwd_utf16));
|
||||||
|
|
||||||
|
return (password_auth_token) ? 1 : 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
|
@ -783,11 +783,6 @@ struct winsize {
|
||||||
# define CUSTOM_SYS_AUTH_PASSWD 1
|
# define CUSTOM_SYS_AUTH_PASSWD 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WINDOWS
|
|
||||||
/* Windows has custom non-BSD logic for password auth */
|
|
||||||
# define CUSTOM_SYS_AUTH_PASSWD 1
|
|
||||||
#endif /* WINDOWS */
|
|
||||||
|
|
||||||
#if defined(HAVE_LIBIAF) && defined(HAVE_SET_ID) && !defined(HAVE_SECUREWARE)
|
#if defined(HAVE_LIBIAF) && defined(HAVE_SET_ID) && !defined(HAVE_SECUREWARE)
|
||||||
# define CUSTOM_SYS_AUTH_PASSWD 1
|
# define CUSTOM_SYS_AUTH_PASSWD 1
|
||||||
#endif
|
#endif
|
||||||
|
|
5
dns.c
5
dns.c
|
@ -209,10 +209,6 @@ int
|
||||||
verify_host_key_dns(const char *hostname, struct sockaddr *address,
|
verify_host_key_dns(const char *hostname, struct sockaddr *address,
|
||||||
struct sshkey *hostkey, int *flags)
|
struct sshkey *hostkey, int *flags)
|
||||||
{
|
{
|
||||||
#ifdef WINDOWS
|
|
||||||
error("dns host key verification is not supported in Windows yet");
|
|
||||||
return -1;
|
|
||||||
#else /* !WINDOWS */
|
|
||||||
u_int counter;
|
u_int counter;
|
||||||
int result;
|
int result;
|
||||||
struct rrsetinfo *fingerprints = NULL;
|
struct rrsetinfo *fingerprints = NULL;
|
||||||
|
@ -315,7 +311,6 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address,
|
||||||
debug("no host key fingerprint found in DNS");
|
debug("no host key fingerprint found in DNS");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
#endif /* !WINDOWS */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -531,7 +531,6 @@ getlast_entry(struct logininfo *li)
|
||||||
/* If wtmp isn't available, try wtmpx */
|
/* If wtmp isn't available, try wtmpx */
|
||||||
return (wtmpx_get_entry(li));
|
return (wtmpx_get_entry(li));
|
||||||
# else
|
# else
|
||||||
/* TODO - implement last_login_entry in Windows*/
|
|
||||||
/* Give up: No means of retrieving last login time */
|
/* Give up: No means of retrieving last login time */
|
||||||
return (0);
|
return (0);
|
||||||
# endif /* DISABLE_LASTLOG */
|
# endif /* DISABLE_LASTLOG */
|
||||||
|
|
|
@ -82,11 +82,11 @@ static int
|
||||||
can_output(void)
|
can_output(void)
|
||||||
{
|
{
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
/* TODO - confirm this is always true */
|
/* On Windows, we can output if the stdout is a terminal*/
|
||||||
return 1;
|
return isatty(STDOUT_FILENO);
|
||||||
#else /* !WINDOWS */
|
#else
|
||||||
return (getpgrp() == tcgetpgrp(STDOUT_FILENO));
|
return (getpgrp() == tcgetpgrp(STDOUT_FILENO));
|
||||||
#endif /* !WINDOWS */
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
16
readconf.c
16
readconf.c
|
@ -479,21 +479,14 @@ default_ssh_port(void)
|
||||||
static int
|
static int
|
||||||
execute_in_shell(const char *cmd)
|
execute_in_shell(const char *cmd)
|
||||||
{
|
{
|
||||||
#ifdef WINDOWS
|
|
||||||
int retVal = -1;
|
|
||||||
wchar_t *cmd_w = utf8_to_utf16(cmd);
|
|
||||||
|
|
||||||
if (cmd_w) {
|
|
||||||
retVal = _wsystem(cmd_w);
|
|
||||||
free(cmd_w);
|
|
||||||
}
|
|
||||||
|
|
||||||
return retVal;
|
|
||||||
#else /* !WINDOWS */
|
|
||||||
char *shell;
|
char *shell;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
int devnull, status;
|
int devnull, status;
|
||||||
|
|
||||||
|
#ifdef WINDOWS
|
||||||
|
return system(cmd);
|
||||||
|
#endif
|
||||||
|
|
||||||
if ((shell = getenv("SHELL")) == NULL)
|
if ((shell = getenv("SHELL")) == NULL)
|
||||||
shell = _PATH_BSHELL;
|
shell = _PATH_BSHELL;
|
||||||
|
|
||||||
|
@ -544,7 +537,6 @@ execute_in_shell(const char *cmd)
|
||||||
}
|
}
|
||||||
debug3("command returned status %d", WEXITSTATUS(status));
|
debug3("command returned status %d", WEXITSTATUS(status));
|
||||||
return WEXITSTATUS(status);
|
return WEXITSTATUS(status);
|
||||||
#endif /* !WINDOWS */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -188,10 +188,6 @@ auth_sock_cleanup_proc(struct passwd *pw)
|
||||||
static int
|
static int
|
||||||
auth_input_request_forwarding(struct ssh *ssh, struct passwd * pw)
|
auth_input_request_forwarding(struct ssh *ssh, struct passwd * pw)
|
||||||
{
|
{
|
||||||
#ifdef WINDOWS
|
|
||||||
packet_send_debug("Agent forwarding not supported in Windows yet");
|
|
||||||
return 0;
|
|
||||||
#else /* !WINDOWS */
|
|
||||||
Channel *nc;
|
Channel *nc;
|
||||||
int sock = -1;
|
int sock = -1;
|
||||||
|
|
||||||
|
@ -248,7 +244,6 @@ auth_input_request_forwarding(struct ssh *ssh, struct passwd * pw)
|
||||||
auth_sock_name = NULL;
|
auth_sock_name = NULL;
|
||||||
auth_sock_dir = NULL;
|
auth_sock_dir = NULL;
|
||||||
return 0;
|
return 0;
|
||||||
#endif /* !WINDOWS */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -60,7 +60,6 @@
|
||||||
#include "digest.h"
|
#include "digest.h"
|
||||||
#include "utf8.h"
|
#include "utf8.h"
|
||||||
#include "authfd.h"
|
#include "authfd.h"
|
||||||
#include "sshfileperm.h"
|
|
||||||
|
|
||||||
#ifdef WITH_OPENSSL
|
#ifdef WITH_OPENSSL
|
||||||
# define DEFAULT_KEY_TYPE_NAME "rsa"
|
# define DEFAULT_KEY_TYPE_NAME "rsa"
|
||||||
|
@ -1095,9 +1094,6 @@ do_gen_all_hostkeys(struct passwd *pw)
|
||||||
if (f == NULL) {
|
if (f == NULL) {
|
||||||
error("fdopen %s failed: %s", pub_tmp, strerror(errno));
|
error("fdopen %s failed: %s", pub_tmp, strerror(errno));
|
||||||
close(fd);
|
close(fd);
|
||||||
sshkey_free(public);
|
|
||||||
first = 0;
|
|
||||||
continue;
|
|
||||||
goto failnext;
|
goto failnext;
|
||||||
}
|
}
|
||||||
if ((r = sshkey_write(public, f)) != 0) {
|
if ((r = sshkey_write(public, f)) != 0) {
|
||||||
|
@ -1665,7 +1661,6 @@ load_pkcs11_key(char *path)
|
||||||
return private;
|
return private;
|
||||||
#else
|
#else
|
||||||
fatal("no pkcs11 support");
|
fatal("no pkcs11 support");
|
||||||
return NULL;
|
|
||||||
#endif /* ENABLE_PKCS11 */
|
#endif /* ENABLE_PKCS11 */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,12 +70,7 @@ int hash_hosts = 0; /* Hash hostname on output */
|
||||||
|
|
||||||
int print_sshfp = 0; /* Print SSHFP records instead of known_hosts */
|
int print_sshfp = 0; /* Print SSHFP records instead of known_hosts */
|
||||||
|
|
||||||
#ifdef WINDOWS
|
|
||||||
#define MAXMAXFD 32
|
|
||||||
#else
|
|
||||||
#define MAXMAXFD 256
|
#define MAXMAXFD 256
|
||||||
#endif // WINDOWS
|
|
||||||
|
|
||||||
|
|
||||||
/* The number of seconds after which to give up on a TCP connection */
|
/* The number of seconds after which to give up on a TCP connection */
|
||||||
int timeout = 5;
|
int timeout = 5;
|
||||||
|
|
11
ssh.c
11
ssh.c
|
@ -1539,14 +1539,6 @@ main(int ac, char **av)
|
||||||
static void
|
static void
|
||||||
control_persist_detach(void)
|
control_persist_detach(void)
|
||||||
{
|
{
|
||||||
#ifdef WINDOWS
|
|
||||||
/*
|
|
||||||
* This needs some level of support for domain sockets in Windows
|
|
||||||
* Domain sockets (w/out ancillary data support) can easily be
|
|
||||||
* implemented using named pipes.
|
|
||||||
*/
|
|
||||||
fatal("ControlMaster is not supported in Windows yet");
|
|
||||||
#else /* !WINDOWS */
|
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
int devnull, keep_stderr;
|
int devnull, keep_stderr;
|
||||||
|
|
||||||
|
@ -1589,7 +1581,6 @@ control_persist_detach(void)
|
||||||
}
|
}
|
||||||
daemon(1, 1);
|
daemon(1, 1);
|
||||||
setproctitle("%s [mux]", options.control_path);
|
setproctitle("%s [mux]", options.control_path);
|
||||||
#endif /* !WINDOWS */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Do fork() after authentication. Used by "ssh -f" */
|
/* Do fork() after authentication. Used by "ssh -f" */
|
||||||
|
@ -1959,7 +1950,6 @@ ssh_session2(struct ssh *ssh, struct passwd *pw)
|
||||||
* NB. this can only happen after LocalCommand has completed,
|
* NB. this can only happen after LocalCommand has completed,
|
||||||
* as it may want to write to stdout.
|
* as it may want to write to stdout.
|
||||||
*/
|
*/
|
||||||
#ifndef WINDOWS /* TODO - implement dup2 for Windows */
|
|
||||||
if (!need_controlpersist_detach) {
|
if (!need_controlpersist_detach) {
|
||||||
if ((devnull = open(_PATH_DEVNULL, O_WRONLY)) == -1)
|
if ((devnull = open(_PATH_DEVNULL, O_WRONLY)) == -1)
|
||||||
error("%s: open %s: %s", __func__,
|
error("%s: open %s: %s", __func__,
|
||||||
|
@ -1969,7 +1959,6 @@ ssh_session2(struct ssh *ssh, struct passwd *pw)
|
||||||
if (devnull > STDERR_FILENO)
|
if (devnull > STDERR_FILENO)
|
||||||
close(devnull);
|
close(devnull);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If requested and we are not interested in replies to remote
|
* If requested and we are not interested in replies to remote
|
||||||
|
|
31
sshconnect.c
31
sshconnect.c
|
@ -107,16 +107,6 @@ static int
|
||||||
ssh_proxy_fdpass_connect(struct ssh *ssh, const char *host, u_short port,
|
ssh_proxy_fdpass_connect(struct ssh *ssh, const char *host, u_short port,
|
||||||
const char *proxy_command)
|
const char *proxy_command)
|
||||||
{
|
{
|
||||||
#ifdef WINDOWS
|
|
||||||
fatal("proxy fdpass connect is not supported in Windows");
|
|
||||||
/*
|
|
||||||
* Unix logic relies on passing in ancillary data over domain sockets
|
|
||||||
* This concept does not exist in Windows.
|
|
||||||
* Possible implementation in Windows could have proxy_command return
|
|
||||||
* connection handle through IPC means
|
|
||||||
*/
|
|
||||||
return 0;
|
|
||||||
#else /* !WINDOWS */
|
|
||||||
char *command_string;
|
char *command_string;
|
||||||
int sp[2], sock;
|
int sp[2], sock;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
|
@ -186,7 +176,6 @@ ssh_proxy_fdpass_connect(struct ssh *ssh, const char *host, u_short port,
|
||||||
return -1; /* ssh_packet_set_connection logs error */
|
return -1; /* ssh_packet_set_connection logs error */
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
#endif /* !WINDOWS */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1555,21 +1544,6 @@ warn_changed_key(struct sshkey *host_key)
|
||||||
int
|
int
|
||||||
ssh_local_cmd(const char *args)
|
ssh_local_cmd(const char *args)
|
||||||
{
|
{
|
||||||
#ifdef WINDOWS
|
|
||||||
if (!options.permit_local_command ||
|
|
||||||
args == NULL || !*args)
|
|
||||||
return (1);
|
|
||||||
|
|
||||||
int retVal = -1;
|
|
||||||
wchar_t *args_w = utf8_to_utf16(args);
|
|
||||||
|
|
||||||
if (args_w) {
|
|
||||||
retVal = _wsystem(args_w);
|
|
||||||
free(args_w);
|
|
||||||
}
|
|
||||||
|
|
||||||
return retVal;
|
|
||||||
#else /* !WINDOWS */
|
|
||||||
char *shell;
|
char *shell;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
int status;
|
int status;
|
||||||
|
@ -1579,6 +1553,10 @@ ssh_local_cmd(const char *args)
|
||||||
args == NULL || !*args)
|
args == NULL || !*args)
|
||||||
return (1);
|
return (1);
|
||||||
|
|
||||||
|
#ifdef WINDOWS
|
||||||
|
return system(args);
|
||||||
|
#endif
|
||||||
|
|
||||||
if ((shell = getenv("SHELL")) == NULL || *shell == '\0')
|
if ((shell = getenv("SHELL")) == NULL || *shell == '\0')
|
||||||
shell = _PATH_BSHELL;
|
shell = _PATH_BSHELL;
|
||||||
|
|
||||||
|
@ -1602,7 +1580,6 @@ ssh_local_cmd(const char *args)
|
||||||
return (1);
|
return (1);
|
||||||
|
|
||||||
return (WEXITSTATUS(status));
|
return (WEXITSTATUS(status));
|
||||||
#endif /* !WINDOWS */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -1811,10 +1811,6 @@ static int
|
||||||
ssh_keysign(struct sshkey *key, u_char **sigp, size_t *lenp,
|
ssh_keysign(struct sshkey *key, u_char **sigp, size_t *lenp,
|
||||||
const u_char *data, size_t datalen)
|
const u_char *data, size_t datalen)
|
||||||
{
|
{
|
||||||
#ifdef WINDOWS
|
|
||||||
fatal("keysign is not supported in Windows yet");
|
|
||||||
return -1;
|
|
||||||
#else /* !WINDOWS */
|
|
||||||
struct sshbuf *b;
|
struct sshbuf *b;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
|
@ -1923,7 +1919,6 @@ ssh_keysign(struct sshkey *key, u_char **sigp, size_t *lenp,
|
||||||
sshbuf_free(b);
|
sshbuf_free(b);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
#endif /* !WINDOWS */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
Loading…
Reference in New Issue