mirror of
https://github.com/PowerShell/Win32-OpenSSH.git
synced 2025-07-21 21:14:51 +02:00
Merge branch 'console-updates-integration' of https://github.com/PowerShell/Win32-OpenSSH.git
This commit is contained in:
commit
bbc576eeaf
@ -54,7 +54,7 @@ atomicio6(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n,
|
||||
{
|
||||
char *s = _s;
|
||||
size_t pos = 0;
|
||||
ssize_t res;
|
||||
int res;
|
||||
struct pollfd pfd;
|
||||
|
||||
#ifndef BROKEN_READ_COMPARISON
|
||||
|
148
channels.c
148
channels.c
@ -1722,85 +1722,91 @@ channel_handle_wfd(Channel *c, fd_set *readset, fd_set *writeset)
|
||||
int len;
|
||||
|
||||
/* Send buffered output data to the socket. */
|
||||
if (c->wfd != -1 &&
|
||||
FD_ISSET(c->wfd, writeset) &&
|
||||
buffer_len(&c->output) > 0) {
|
||||
olen = buffer_len(&c->output);
|
||||
if (c->output_filter != NULL) {
|
||||
if ((buf = c->output_filter(c, &data, &dlen)) == NULL) {
|
||||
debug2("channel %d: filter stops", c->self);
|
||||
if (c->type != SSH_CHANNEL_OPEN)
|
||||
chan_mark_dead(c);
|
||||
else
|
||||
chan_write_failed(c);
|
||||
return -1;
|
||||
}
|
||||
} else if (c->datagram) {
|
||||
buf = data = buffer_get_string(&c->output, &dlen);
|
||||
} else {
|
||||
buf = data = buffer_ptr(&c->output);
|
||||
dlen = buffer_len(&c->output);
|
||||
}
|
||||
if (c->wfd != -1 &&
|
||||
FD_ISSET(c->wfd, writeset) &&
|
||||
buffer_len(&c->output) > 0) {
|
||||
olen = buffer_len(&c->output);
|
||||
if (c->output_filter != NULL) {
|
||||
if ((buf = c->output_filter(c, &data, &dlen)) == NULL) {
|
||||
debug2("channel %d: filter stops", c->self);
|
||||
if (c->type != SSH_CHANNEL_OPEN)
|
||||
chan_mark_dead(c);
|
||||
else
|
||||
chan_write_failed(c);
|
||||
return -1;
|
||||
}
|
||||
} else if (c->datagram) {
|
||||
buf = data = buffer_get_string(&c->output, &dlen);
|
||||
} else {
|
||||
buf = data = buffer_ptr(&c->output);
|
||||
dlen = buffer_len(&c->output);
|
||||
}
|
||||
|
||||
if (c->datagram) {
|
||||
/* ignore truncated writes, datagrams might get lost */
|
||||
len = write(c->wfd, buf, dlen);
|
||||
free(data);
|
||||
if (len < 0 && (errno == EINTR || errno == EAGAIN ||
|
||||
errno == EWOULDBLOCK))
|
||||
return 1;
|
||||
if (len <= 0) {
|
||||
if (c->type != SSH_CHANNEL_OPEN)
|
||||
chan_mark_dead(c);
|
||||
else
|
||||
chan_write_failed(c);
|
||||
return -1;
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
if (c->datagram) {
|
||||
/* ignore truncated writes, datagrams might get lost */
|
||||
len = write(c->wfd, buf, dlen);
|
||||
free(data);
|
||||
if (len < 0 && (errno == EINTR || errno == EAGAIN ||
|
||||
errno == EWOULDBLOCK))
|
||||
return 1;
|
||||
if (len <= 0) {
|
||||
if (c->type != SSH_CHANNEL_OPEN)
|
||||
chan_mark_dead(c);
|
||||
else
|
||||
chan_write_failed(c);
|
||||
return -1;
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
#ifdef _AIX
|
||||
/* XXX: Later AIX versions can't push as much data to tty */
|
||||
if (compat20 && c->wfd_isatty)
|
||||
dlen = MIN(dlen, 8*1024);
|
||||
/* XXX: Later AIX versions can't push as much data to tty */
|
||||
if (compat20 && c->wfd_isatty)
|
||||
dlen = MIN(dlen, 8 * 1024);
|
||||
#endif
|
||||
#ifdef WIN32_FIXME /* TODO - Fix this - on windows we somehow end up with dlen = 0*/
|
||||
if (dlen > 0) {
|
||||
#endif
|
||||
|
||||
len = write(c->wfd, buf, dlen);
|
||||
if (len < 0 &&
|
||||
(errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK))
|
||||
return 1;
|
||||
if (len <= 0) {
|
||||
if (c->type != SSH_CHANNEL_OPEN) {
|
||||
debug2("channel %d: not open", c->self);
|
||||
chan_mark_dead(c);
|
||||
return -1;
|
||||
} else if (compat13) {
|
||||
buffer_clear(&c->output);
|
||||
debug2("channel %d: input draining.", c->self);
|
||||
c->type = SSH_CHANNEL_INPUT_DRAINING;
|
||||
} else {
|
||||
chan_write_failed(c);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
len = write(c->wfd, buf, dlen);
|
||||
if (len < 0 &&
|
||||
(errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK))
|
||||
return 1;
|
||||
if (len <= 0) {
|
||||
if (c->type != SSH_CHANNEL_OPEN) {
|
||||
debug2("channel %d: not open", c->self);
|
||||
chan_mark_dead(c);
|
||||
return -1;
|
||||
} else if (compat13) {
|
||||
buffer_clear(&c->output);
|
||||
debug2("channel %d: input draining.", c->self);
|
||||
c->type = SSH_CHANNEL_INPUT_DRAINING;
|
||||
} else {
|
||||
chan_write_failed(c);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
#ifndef WIN32_FIXME//R
|
||||
#ifndef BROKEN_TCGETATTR_ICANON
|
||||
if (compat20 && c->isatty && dlen >= 1 && buf[0] != '\r') {
|
||||
if (tcgetattr(c->wfd, &tio) == 0 &&
|
||||
!(tio.c_lflag & ECHO) && (tio.c_lflag & ICANON)) {
|
||||
/*
|
||||
* Simulate echo to reduce the impact of
|
||||
* traffic analysis. We need to match the
|
||||
* size of a SSH2_MSG_CHANNEL_DATA message
|
||||
* (4 byte channel id + buf)
|
||||
*/
|
||||
packet_send_ignore(4 + len);
|
||||
packet_send();
|
||||
}
|
||||
}
|
||||
if (compat20 && c->isatty && dlen >= 1 && buf[0] != '\r') {
|
||||
if (tcgetattr(c->wfd, &tio) == 0 &&
|
||||
!(tio.c_lflag & ECHO) && (tio.c_lflag & ICANON)) {
|
||||
/*
|
||||
* Simulate echo to reduce the impact of
|
||||
* traffic analysis. We need to match the
|
||||
* size of a SSH2_MSG_CHANNEL_DATA message
|
||||
* (4 byte channel id + buf)
|
||||
*/
|
||||
packet_send_ignore(4 + len);
|
||||
packet_send();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
buffer_consume(&c->output, len);
|
||||
}
|
||||
buffer_consume(&c->output, len);
|
||||
}
|
||||
#ifdef WIN32_FIXME /* for if (dlen > 0) */
|
||||
}
|
||||
#endif
|
||||
out:
|
||||
if (compat20 && olen > 0)
|
||||
c->local_consumed += olen - buffer_len(&c->output);
|
||||
|
@ -1671,6 +1671,7 @@
|
||||
#define HAVE_KRB5_FREE_ERROR_MESSAGE 1
|
||||
#define HAVE_DECL_NFDBITS 0
|
||||
#define HAVE_DECL_HOWMANY 0
|
||||
#define HAVE_DES_CRYPT 1
|
||||
|
||||
#define WIN32_ZLIB_NO 1
|
||||
#define USE_MSCNG 1
|
||||
|
@ -151,8 +151,6 @@
|
||||
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\gettimeofday.c" />
|
||||
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\homedirhelp.c" />
|
||||
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\kerberos.c" />
|
||||
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\lsalogon.c" />
|
||||
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\lsastring.c" />
|
||||
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\pwd.c" />
|
||||
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\startupneeds.c" />
|
||||
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\strcasecmp.c" />
|
||||
|
@ -57,12 +57,6 @@
|
||||
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\kerberos.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\lsalogon.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\lsastring.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\pwd.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
|
@ -70,6 +70,8 @@ typedef int sigset_t;
|
||||
|
||||
typedef unsigned short _mode_t;
|
||||
typedef _mode_t mode_t;
|
||||
/* TODO - investigate if it makes sense to make pid_t a DWORD_PTR.
|
||||
* Double check usage of pid_t as int */
|
||||
typedef int pid_t;
|
||||
|
||||
/* wait pid options */
|
||||
|
@ -19,4 +19,4 @@
|
||||
#define recv(a,b,c,d) w32_recv((a), (b), (c), (d))
|
||||
#define send(a,b,c,d) w32_send((a), (b), (c), (d))
|
||||
#define shutdown(a,b) w32_shutdown((a), (b))
|
||||
#define socketpair(a,b,c) w32_socketpair((a), (b), (c))
|
||||
#define socketpair(a,b,c,d) w32_socketpair((a), (b), (c), (d))
|
||||
|
@ -38,7 +38,6 @@
|
||||
/* Compatibility header to avoid lots of #ifdefs in includes.h on Win32 */
|
||||
|
||||
#include <conio.h>
|
||||
#include <direct.h>
|
||||
|
||||
/* We can't put these in string.h since we can't easily override that header, so here they are */
|
||||
#if !defined(HAVE_STRCASECMP) && !defined(__MINGW32__)
|
||||
|
@ -32,16 +32,17 @@ int w32_connect(int fd, const struct sockaddr* name, int namelen);
|
||||
int w32_recv(int fd, void *buf, size_t len, int flags);
|
||||
int w32_send(int fd, const void *buf, size_t len, int flags);
|
||||
int w32_shutdown(int fd, int how);
|
||||
int w32_socketpair(int domain, int type, int sv[2]);
|
||||
int w32_socketpair(int domain, int type, int protocol, int sv[2]);
|
||||
|
||||
/*non-network (file) i/o*/
|
||||
#undef fdopen
|
||||
#define fdopen(a,b) w32_fdopen((a), (b))
|
||||
#define fstat(a,b) w32_fstat((a), (b))
|
||||
|
||||
struct w32_stat;
|
||||
int w32_pipe(int *pfds);
|
||||
int w32_open(const char *pathname, int flags, ...);
|
||||
int w32_read(int fd, void *dst, unsigned int max);
|
||||
int w32_read(int fd, void *dst, size_t max);
|
||||
int w32_write(int fd, const void *buf, unsigned int max);
|
||||
int w32_fstat(int fd, struct w32_stat *buf);
|
||||
int w32_stat(const char *path, struct w32_stat *buf);
|
||||
|
@ -26,8 +26,7 @@ struct passwd *getpwuid(uid_t uid);
|
||||
struct passwd *getpwnam(const char *username);
|
||||
void endpwent(void);
|
||||
|
||||
typedef int PWD_USER_TOKEN; /* This is really just a HANDLE, but we might not have windows.h included */
|
||||
PWD_USER_TOKEN PwdCreateUserToken(const char *pUserName, const char *pDomainName, const char *pSourceName);
|
||||
char *realpathWin32(const char *path, char resolved[PATH_MAX]);
|
||||
|
||||
const char *
|
||||
user_from_uid(uid_t uid, int nouser);
|
||||
|
@ -96,15 +96,15 @@ void LsaFreeUnicodeString(PUNICODE_STRING lsaStr)
|
||||
NTSTATUS FillUnicodeString(UNICODE_STRING *lsaStr, const Char *str)
|
||||
{
|
||||
NTSTATUS ntStat = STATUS_NO_MEMORY;
|
||||
USHORT cbSize = 0;
|
||||
FAIL(lsaStr == NULL);
|
||||
size_t cbSize = 0;
|
||||
FAIL(lsaStr == NULL);
|
||||
FAIL(lsaStr->Buffer == NULL);
|
||||
FAIL(str == NULL);
|
||||
cbSize = strlen(str);
|
||||
FAIL(cbSize >= lsaStr->MaximumLength);
|
||||
_swprintf(lsaStr->Buffer, L"%hs", str);
|
||||
lsaStr->Length = cbSize * 2;
|
||||
lsaStr->Buffer[cbSize * 2] = 0x0000;
|
||||
lsaStr->Length = (USHORT)(cbSize * 2);
|
||||
lsaStr->Buffer[cbSize * 2] = 0x0000;
|
||||
ntStat = STATUS_SUCCESS;
|
||||
|
||||
fail:
|
||||
|
@ -1,481 +0,0 @@
|
||||
/*
|
||||
* Author: NoMachine <developers@nomachine.com>
|
||||
*
|
||||
* Copyright (c) 2009, 2011 NoMachine
|
||||
* All rights reserved
|
||||
*
|
||||
* Support functions and system calls' replacements needed to let the
|
||||
* software run on Win32 based operating systems.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "lsalogon.h"
|
||||
#include <stdio.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/dsa.h>
|
||||
|
||||
#include "Debug.h"
|
||||
#include "lsastring.h"
|
||||
#include "win32auth.h"
|
||||
#include "Debug.h"
|
||||
|
||||
|
||||
#include "log.h"
|
||||
#include "servconf.h"
|
||||
|
||||
|
||||
#define STATUS_LOGON_FAILURE ((NTSTATUS)0xC000006DL) // ntsubauth
|
||||
#define STATUS_NO_SUCH_PACKAGE ((NTSTATUS)0xC00000FEL)
|
||||
|
||||
extern ServerOptions options;
|
||||
|
||||
/*
|
||||
* Allocate new LsaAuth struct and initialize it with given auth data.
|
||||
* This function is needed becouse:
|
||||
*
|
||||
* a) LSA needs one continous memory block on input.
|
||||
*
|
||||
* b) We can't send pointers in auth data to LSA 'server', becouse
|
||||
* LSA package can be 32 or 64 bit and the same to client application.
|
||||
* Client and Server must be compatible, so all fields must have the
|
||||
* same size in lsa 'server' and logon client application.
|
||||
*
|
||||
* So, we allocate one 'big' LsaAuth struct and copy to it all
|
||||
* needed auth data.
|
||||
*
|
||||
* lsaauth - new allocated LsaAuth struct (OUT)
|
||||
* user - user name, in UTF-8 (IN)
|
||||
* pkblob - public key blob (IN)
|
||||
* blen - pkblob size in bytes (IN)
|
||||
* sign - signature (IN)
|
||||
* signSize - signature size in bytes (IN)
|
||||
* data - ?? We copy it from ssh auth code (IN)
|
||||
* dataSize - size of data field in bytes (IN)
|
||||
* dataFellow - ?? We pass global 'datafellow' variable from sshd here (IN)
|
||||
*
|
||||
* RETURNS: 0 if OK.
|
||||
*/
|
||||
|
||||
int AllocLsaAuth(LsaAuth **lsaAuth, char *user, char *pkBlob,
|
||||
int pkBlobSize, char *sign, int signSize,
|
||||
char *data, int dataSize, int dataFellow)
|
||||
{
|
||||
int exitCode = 1;
|
||||
|
||||
LPWSTR userUTF16 = NULL;
|
||||
|
||||
int i = 0;
|
||||
|
||||
int authFileSize = 0;
|
||||
|
||||
/*
|
||||
* Pointers to fields in local allocated LsaAuth struct.
|
||||
*/
|
||||
|
||||
char *userPtr = NULL;
|
||||
char *signPtr = NULL;
|
||||
char *dataPtr = NULL;
|
||||
char *blobPtr = NULL;
|
||||
char *authPtr = NULL;
|
||||
|
||||
char *p = NULL;
|
||||
|
||||
/*
|
||||
* Are arguments ok?
|
||||
*/
|
||||
|
||||
debug3("Checking args...");
|
||||
|
||||
FAIL(user == NULL);
|
||||
FAIL(lsaAuth == NULL);
|
||||
FAIL(pkBlob == NULL);
|
||||
FAIL(sign == NULL);
|
||||
FAIL(signSize == 0);
|
||||
FAIL(dataSize == 0);
|
||||
FAIL(pkBlobSize == 0);
|
||||
|
||||
*lsaAuth = NULL;
|
||||
|
||||
/*
|
||||
* Compute total size of authorize files list.
|
||||
* For each files we need : real content + zero terminate word.
|
||||
*/
|
||||
|
||||
for (i = 0; i < options.num_authkeys_files; i++)
|
||||
{
|
||||
debug3("Adding authorized file [%s] to LsaAuth...",
|
||||
options.authorized_keys_files[i]);
|
||||
|
||||
int cchLen = MultiByteToWideChar(CP_UTF8, 0,
|
||||
options.authorized_keys_files[i],
|
||||
-1, NULL, 0);
|
||||
|
||||
authFileSize += (cchLen + 1) * sizeof(wchar_t);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert username to UTF-16.
|
||||
*/
|
||||
|
||||
int userSize = MultiByteToWideChar(CP_UTF8, 0, user, -1, NULL, 0);
|
||||
|
||||
FAIL(userSize == 0);
|
||||
|
||||
userSize = 4 * userSize;
|
||||
|
||||
userUTF16 = (LPWSTR) malloc(userSize);
|
||||
|
||||
FAIL(userUTF16 == NULL);
|
||||
|
||||
FAIL(0 == MultiByteToWideChar(CP_UTF8, 0, user, -1, userUTF16, userSize));
|
||||
|
||||
/*
|
||||
* Compute total size of LsaAuth struct.
|
||||
*/
|
||||
|
||||
debug3("Computing total size of LsaAuth...");
|
||||
|
||||
int totalSize = sizeof(LsaAuth) + userSize + signSize +
|
||||
dataSize + pkBlobSize + authFileSize;
|
||||
|
||||
/*
|
||||
* Allocate new LsaAuth struct.
|
||||
*/
|
||||
|
||||
debug3("Allocating new LsaAuth structure...");
|
||||
|
||||
*lsaAuth = (LsaAuth *) malloc(totalSize);
|
||||
|
||||
FAIL(*lsaAuth == NULL);
|
||||
|
||||
/*
|
||||
* Store sizes of fields in LsaAuth.
|
||||
*/
|
||||
|
||||
(*lsaAuth) -> totalSize_ = totalSize;
|
||||
(*lsaAuth) -> userSize_ = userSize;
|
||||
(*lsaAuth) -> signSize_ = signSize;
|
||||
(*lsaAuth) -> dataSize_ = dataSize;
|
||||
(*lsaAuth) -> pkBlobSize_ = pkBlobSize;
|
||||
|
||||
/*
|
||||
* Compute adressess of fields.
|
||||
*/
|
||||
|
||||
userPtr = (char *) &((*lsaAuth) -> buf_);
|
||||
signPtr = (char *) (userPtr + userSize);
|
||||
dataPtr = (char *) (signPtr + signSize);
|
||||
blobPtr = (char *) (dataPtr + dataSize);
|
||||
authPtr = (char *) (blobPtr + pkBlobSize);
|
||||
|
||||
/*
|
||||
* Copy input buffers into output structure's fields.
|
||||
*/
|
||||
|
||||
debug3("Filling up LsaAuth struct...");
|
||||
|
||||
memcpy(userPtr, userUTF16, userSize);
|
||||
memcpy(signPtr, sign, signSize);
|
||||
memcpy(dataPtr, data, dataSize);
|
||||
memcpy(blobPtr, pkBlob, pkBlobSize);
|
||||
|
||||
(*lsaAuth) -> dataFellow_ = dataFellow;
|
||||
|
||||
/*
|
||||
* Copy authorized files list into output struct.
|
||||
*/
|
||||
|
||||
(*lsaAuth) -> authFilesCount_ = options.num_authkeys_files;
|
||||
|
||||
p = authPtr;
|
||||
|
||||
for (i = 0; i < options.num_authkeys_files; i++)
|
||||
{
|
||||
char *nextFile = options.authorized_keys_files[i];
|
||||
|
||||
int bytesLeft = (char *) (*lsaAuth) + totalSize - p;
|
||||
|
||||
/*
|
||||
* Put next UTF8 string to struct.
|
||||
*/
|
||||
|
||||
debug3("Converting [%s] to UTF8...", nextFile);
|
||||
|
||||
int writtenCch = MultiByteToWideChar(CP_UTF8, 0, nextFile, -1,
|
||||
(wchar_t *) p, bytesLeft);
|
||||
|
||||
FAIL(writtenCch <= 0);
|
||||
|
||||
p += (writtenCch + 1) * sizeof(wchar_t);
|
||||
}
|
||||
|
||||
exitCode = 0;
|
||||
|
||||
fail:
|
||||
|
||||
/*
|
||||
* Clean up if function fails.
|
||||
*/
|
||||
|
||||
if (exitCode)
|
||||
{
|
||||
debug("ERROR. Cannot create LsaAuth struct (%u).", GetLastError());
|
||||
|
||||
if (lsaAuth && *lsaAuth)
|
||||
{
|
||||
free(*lsaAuth);
|
||||
|
||||
*lsaAuth = NULL;
|
||||
}
|
||||
|
||||
if (userUTF16)
|
||||
{
|
||||
free(userUTF16);
|
||||
}
|
||||
}
|
||||
|
||||
return exitCode;
|
||||
}
|
||||
|
||||
/*
|
||||
* Try to logon using SSH-LSA package.
|
||||
*
|
||||
* hToken - user token if success (OUT)
|
||||
* user - user name (IN)
|
||||
* pkblob - public key blob (IN)
|
||||
* blen - pkblob size in bytes (IN)
|
||||
* sign - signature (IN)
|
||||
* signSize - signature size in bytes (IN)
|
||||
* data - ?? We copy it from ssh auth code (IN)
|
||||
* dataSize - size of data field in bytes (IN)
|
||||
* dataFellow - ?? We copy it from ssh auth code (IN)
|
||||
*
|
||||
* RETURNS: 0 if OK.
|
||||
*/
|
||||
|
||||
int LsaLogon(HANDLE *hToken, char homeDir[MAX_PATH], char *user,
|
||||
char *pkBlob, int pkBlobSize, char *sign, int signSize,
|
||||
char *data, int dataSize, int dataFellow)
|
||||
{
|
||||
int exitCode = 1;
|
||||
|
||||
NTSTATUS ntStat = 0;
|
||||
|
||||
LSA_STRING logonProcName;
|
||||
LSA_STRING originName;
|
||||
LSA_STRING authPckgName;
|
||||
|
||||
HANDLE hLsa = NULL;
|
||||
|
||||
LSA_OPERATIONAL_MODE securityMode;
|
||||
|
||||
/*
|
||||
* Impersonation, "weak" token returned from network logon.
|
||||
* We can't create process as other user via this token.
|
||||
*/
|
||||
|
||||
HANDLE hWeakToken = NULL;
|
||||
|
||||
/*
|
||||
* Login data.
|
||||
*/
|
||||
|
||||
LsaAuth *lsaAuth = NULL;
|
||||
|
||||
ULONG lsaAuthSize = 0;
|
||||
|
||||
ULONG authPckgId = 0;
|
||||
|
||||
TOKEN_SOURCE srcToken;
|
||||
|
||||
PVOID profile = NULL;
|
||||
|
||||
ULONG profileSize;
|
||||
|
||||
LUID logonId;
|
||||
|
||||
QUOTA_LIMITS quotas;
|
||||
|
||||
NTSTATUS loginStat;
|
||||
|
||||
|
||||
debug("-> LsaLogon()...");
|
||||
|
||||
/*
|
||||
* We check only hToken arg, becouse other args are tested in AllocLsaAuth().
|
||||
*/
|
||||
|
||||
debug("Checking args...");
|
||||
|
||||
FAIL(hToken == NULL);
|
||||
|
||||
/*
|
||||
* Setup lsa strings.
|
||||
*/
|
||||
|
||||
debug("Setting up LSA Strings...");
|
||||
|
||||
FAIL(InitLsaString(&logonProcName, "sshd-logon"));
|
||||
FAIL(InitLsaString(&originName, "NTLM"));
|
||||
FAIL(InitLsaString(&authPckgName, "SSH-LSA"));
|
||||
|
||||
/*
|
||||
* Enable needed privilege to current running process.
|
||||
*/
|
||||
|
||||
EnablePrivilege("SeTcbPrivilege", 1);
|
||||
|
||||
/*
|
||||
* Register new logon process.
|
||||
*/
|
||||
|
||||
debug("LsaRegisterLogonProcess()...");
|
||||
|
||||
NTFAIL(LsaRegisterLogonProcess(&logonProcName, &hLsa, &securityMode));
|
||||
|
||||
/*
|
||||
* Retrieve Authenticated Package ID.
|
||||
*/
|
||||
|
||||
debug("Retrieving Authentification Package ID...");
|
||||
|
||||
NTFAIL(LsaLookupAuthenticationPackage(hLsa, &authPckgName, &authPckgId));
|
||||
|
||||
/*
|
||||
* Allocate LsaAuth struct.
|
||||
*/
|
||||
|
||||
debug("Allocating LsaAuth struct...");
|
||||
|
||||
FAIL(AllocLsaAuth(&lsaAuth, user, pkBlob, pkBlobSize,
|
||||
sign, signSize, data, dataSize, dataFellow));
|
||||
|
||||
lsaAuthSize = lsaAuth -> totalSize_;
|
||||
|
||||
/*
|
||||
* Create TOKEN_SOURCE part
|
||||
*/
|
||||
|
||||
debug("Setting up TOKEN_SOURCE...");
|
||||
|
||||
FAIL(AllocateLocallyUniqueId(&srcToken.SourceIdentifier) == FALSE);
|
||||
|
||||
memcpy(srcToken.SourceName, "**sshd**", 8);
|
||||
|
||||
/*
|
||||
* Try to login using LsaAuth struct.
|
||||
*/
|
||||
|
||||
debug("Login attemp...");
|
||||
|
||||
NTFAIL(LsaLogonUser(hLsa, &originName, Network,
|
||||
authPckgId, lsaAuth, lsaAuthSize, NULL,
|
||||
&srcToken, &profile, &profileSize,
|
||||
&logonId, &hWeakToken, "as, &loginStat));
|
||||
|
||||
debug("login status: %x...", loginStat);
|
||||
|
||||
|
||||
//FAIL(WideCharToMultiByte( CP_UTF8, 0, profile, -1, homeDir, MAX_PATH, NULL, NULL)==0);
|
||||
//memcpy(homeDir, profile, MAX_PATH*sizeof(wchar_t));
|
||||
|
||||
lstrcpyW(homeDir, profile);
|
||||
|
||||
debug("homedir = [%ls]", (char *) homeDir);
|
||||
|
||||
//strcpy(homeDir, profile);
|
||||
|
||||
//PrintToken(hToken);
|
||||
|
||||
/*
|
||||
* Duplicate 'weak' impersonation token into Primary Key token.
|
||||
* We can create process using duplicated token.
|
||||
*/
|
||||
|
||||
debug("Duplicating token...");
|
||||
|
||||
FAIL(DuplicateTokenEx(hWeakToken, MAXIMUM_ALLOWED,
|
||||
NULL, SecurityImpersonation,
|
||||
TokenPrimary, hToken) == 0);
|
||||
|
||||
exitCode = 0;
|
||||
|
||||
fail:
|
||||
|
||||
if (exitCode)
|
||||
{
|
||||
switch(ntStat)
|
||||
{
|
||||
case STATUS_LOGON_FAILURE:
|
||||
{
|
||||
debug("SSH-LSA authorization failed. "
|
||||
"(err = %u, ntStat = %x).", GetLastError(), ntStat);
|
||||
|
||||
exitCode = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case STATUS_NO_SUCH_PACKAGE:
|
||||
{
|
||||
debug("SSH-LSA package not found. "
|
||||
"(err = %u, ntStat = %x).", GetLastError(), ntStat);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
debug("Cannot logon using LSA package (err = %u, ntStat = %x).",
|
||||
GetLastError(), ntStat);
|
||||
}
|
||||
}
|
||||
|
||||
hToken = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
debug("LsaLogon : OK.");
|
||||
}
|
||||
|
||||
/*
|
||||
* Clean up.
|
||||
*/
|
||||
|
||||
CloseHandle(hWeakToken);
|
||||
|
||||
LsaFreeReturnBuffer(profile);
|
||||
|
||||
EnablePrivilege("SeTcbPrivilege", 0);
|
||||
|
||||
LsaDeregisterLogonProcess(hLsa);
|
||||
|
||||
ClearLsaString(&logonProcName);
|
||||
ClearLsaString(&originName);
|
||||
ClearLsaString(&authPckgName);
|
||||
|
||||
debug("<- LsaLogon()...");
|
||||
|
||||
return exitCode;
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Author: NoMachine <developers@nomachine.com>
|
||||
*
|
||||
* Copyright (c) 2009, 2011 NoMachine
|
||||
* All rights reserved
|
||||
*
|
||||
* Support functions and system calls' replacements needed to let the
|
||||
* software run on Win32 based operating systems.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef LsaLogon_H
|
||||
#define LsaLogon_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
|
||||
typedef struct _LsaAuth
|
||||
{
|
||||
DWORD totalSize_;
|
||||
DWORD dataFellow_;
|
||||
DWORD userSize_;
|
||||
DWORD signSize_;
|
||||
DWORD dataSize_;
|
||||
DWORD pkBlobSize_;
|
||||
DWORD authFilesCount_;
|
||||
|
||||
BYTE buf_[1];
|
||||
}
|
||||
LsaAuth;
|
||||
|
||||
int AllocLsaAuth(LsaAuth **lsaAuth, char *user, char *pkBlob,
|
||||
int pkBlobSize, char *sign, int signSize,
|
||||
char *data, int dataSize, int dataFellow);
|
||||
|
||||
int LsaLogon(HANDLE *hToken, char homeDir[MAX_PATH], char *user, char *pkBlob,
|
||||
int pkBlobSize, char *sign, int signSize,
|
||||
char *data, int dataSize, int dataFellow);
|
||||
|
||||
#endif
|
@ -236,7 +236,7 @@ wait_for_any_event(HANDLE* events, int num_events, DWORD milli_seconds)
|
||||
memcpy(all_events, children.handles, live_children * sizeof(HANDLE));
|
||||
memcpy(all_events + live_children, events, num_events * sizeof(HANDLE));
|
||||
|
||||
debug3("wait() on %d events and %d childres", num_events, live_children);
|
||||
debug3("wait() on %d events and %d children", num_events, live_children);
|
||||
/* TODO - implement signal catching and handling */
|
||||
if (num_all_events) {
|
||||
DWORD ret = WaitForMultipleObjectsEx(num_all_events, all_events, FALSE,
|
||||
|
@ -45,8 +45,8 @@ InitLsaString(LSA_STRING *lsa_string, const char *str)
|
||||
if (str == NULL)
|
||||
memset(lsa_string, 0, sizeof(LSA_STRING));
|
||||
else {
|
||||
lsa_string->Buffer = str;
|
||||
lsa_string->Length = strlen(str);
|
||||
lsa_string->Buffer = (char *)str;
|
||||
lsa_string->Length = strlen(str);
|
||||
lsa_string->MaximumLength = lsa_string->Length + 1;
|
||||
}
|
||||
}
|
||||
|
@ -650,9 +650,11 @@ int ReadConsoleForTermEmul(HANDLE hInput, char *destin, int destinlen)
|
||||
NetWriteString2(pParams->Socket, (char *)BACKSPACE_KEY, 1, 0);
|
||||
break;
|
||||
case VK_TAB:
|
||||
if (dwControlKeyState == SHIFT_PRESSED)
|
||||
NetWriteString2(pParams->Socket, (char *)SHIFT_TAB_KEY, 3, 0);
|
||||
break;
|
||||
if (dwControlKeyState == SHIFT_PRESSED)
|
||||
NetWriteString2(pParams->Socket, (char *)SHIFT_TAB_KEY, 3, 0);
|
||||
else
|
||||
NetWriteString2(pParams->Socket, (char *)octets, n, 0);
|
||||
break;
|
||||
case VK_ESCAPE:
|
||||
NetWriteString2(pParams->Socket, (char *)ESCAPE_KEY, 1, 0);
|
||||
break;
|
||||
|
@ -31,6 +31,7 @@
|
||||
*/
|
||||
#include "inc\w32posix.h"
|
||||
#include "w32fd.h"
|
||||
#include "signal_internal.h"
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
@ -303,8 +304,8 @@ w32_shutdown(int fd, int how) {
|
||||
}
|
||||
|
||||
int
|
||||
w32_socketpair(int domain, int type, int sv[2]) {
|
||||
errno = ENOTSUP;
|
||||
w32_socketpair(int domain, int type, int protocol, int sv[2]) {
|
||||
errno = ENOTSUP;
|
||||
debug("socketpair - ERROR not supported");
|
||||
return -1;
|
||||
}
|
||||
@ -362,8 +363,8 @@ w32_open(const char *pathname, int flags, ...) {
|
||||
}
|
||||
|
||||
int
|
||||
w32_read(int fd, void *dst, unsigned int max) {
|
||||
CHECK_FD(fd);
|
||||
w32_read(int fd, void *dst, size_t max) {
|
||||
CHECK_FD(fd);
|
||||
|
||||
if (fd_table.w32_ios[fd]->type == SOCK_FD)
|
||||
return socketio_recv(fd_table.w32_ios[fd], dst, max, 0);
|
||||
@ -645,7 +646,6 @@ w32_select(int fds, w32_fd_set* readfds, w32_fd_set* writefds, w32_fd_set* excep
|
||||
for (int i = 0; i < fds; i++) {
|
||||
|
||||
if (readfds && FD_ISSET(i, readfds)) {
|
||||
in_set_fds++;
|
||||
if (w32_io_is_io_available(fd_table.w32_ios[i], TRUE)) {
|
||||
FD_SET(i, &read_ready_fds);
|
||||
out_ready_fds++;
|
||||
@ -653,7 +653,6 @@ w32_select(int fds, w32_fd_set* readfds, w32_fd_set* writefds, w32_fd_set* excep
|
||||
}
|
||||
|
||||
if (writefds && FD_ISSET(i, writefds)) {
|
||||
in_set_fds++;
|
||||
if (w32_io_is_io_available(fd_table.w32_ios[i], FALSE)) {
|
||||
FD_SET(i, &write_ready_fds);
|
||||
out_ready_fds++;
|
||||
|
@ -20,13 +20,13 @@ enum w32_io_type {
|
||||
enum w32_io_sock_state {
|
||||
SOCK_INITIALIZED = 0,
|
||||
SOCK_LISTENING = 1, /*listen called on socket*/
|
||||
SOCK_ACCEPTED = 2, /*socket retruned from accept()*/
|
||||
SOCK_ACCEPTED = 2, /*socket returned from accept()*/
|
||||
SOCK_CONNECTING = 3, /*connect called on socket, connect is in progress*/
|
||||
SOCK_CONNECTED = 4 /*connect completed on socket*/
|
||||
};
|
||||
|
||||
/*
|
||||
* This sturcture encapsulates the state info needed to map a File Descriptor
|
||||
* This structure encapsulates the state info needed to map a File Descriptor
|
||||
* to Win32 Handle
|
||||
*/
|
||||
struct w32_io {
|
||||
|
5
misc.c
5
misc.c
@ -661,6 +661,7 @@ wchar_t *percent_expand_w(const wchar_t *string, ...)
|
||||
const wchar_t *repl;
|
||||
} keys[EXPAND_MAX_KEYS];
|
||||
wchar_t buf[4096];
|
||||
wchar_t *aptr = NULL;
|
||||
va_list ap;
|
||||
|
||||
/* Gather keys */
|
||||
@ -694,9 +695,9 @@ wchar_t *percent_expand_w(const wchar_t *string, ...)
|
||||
goto append;
|
||||
for (j = 0; j < num_keys; j++) {
|
||||
if (wcschr(keys[j].key, *string) != NULL) {
|
||||
i = wcsncat(buf, keys[j].repl, sizeof(buf));
|
||||
aptr = wcsncat(buf, keys[j].repl, sizeof(buf));
|
||||
buf[sizeof(buf)-1] = 0;
|
||||
if (i >= sizeof(buf))
|
||||
if (aptr == NULL)
|
||||
fatal("%s: string too long", __func__);
|
||||
break;
|
||||
}
|
||||
|
@ -59,6 +59,8 @@
|
||||
#include "digest.h"
|
||||
|
||||
#ifdef WIN32_FIXME
|
||||
#undef open
|
||||
#undef fdopen
|
||||
#define open(a,b,...) _open((a), (b), __VA_ARGS__)
|
||||
#define fdopen(a,b) _fdopen((a), (b))
|
||||
#endif
|
||||
|
19
sshd.c
19
sshd.c
@ -1584,8 +1584,9 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
|
||||
memset(&si, 0, sizeof(STARTUPINFO));
|
||||
|
||||
char remotesoc[64];
|
||||
snprintf(remotesoc, sizeof(remotesoc), "%d", sfd_to_handle(*newsock));
|
||||
SetEnvironmentVariable("SSHD_REMSOC", remotesoc);
|
||||
snprintf(remotesoc, sizeof(remotesoc), "%p", sfd_to_handle(*newsock));
|
||||
SetEnvironmentVariable("SSHD_REMSOC", remotesoc);
|
||||
debug("Remote Handle %s", remotesoc);
|
||||
|
||||
si.cb = sizeof(STARTUPINFO);
|
||||
si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
|
||||
@ -2515,14 +2516,16 @@ main(int ac, char **av)
|
||||
}
|
||||
else
|
||||
{
|
||||
int remotesochandle ;
|
||||
remotesochandle = atoi( getenv("SSHD_REMSOC") );
|
||||
char *stopstring;
|
||||
DWORD_PTR remotesochandle;
|
||||
remotesochandle = strtol(getenv("SSHD_REMSOC"), &stopstring, 16);
|
||||
debug("remote channel %d", remotesochandle);
|
||||
|
||||
sock_in = sock_out = newsock = w32_allocate_fd_for_handle(remotesochandle, TRUE) ;
|
||||
|
||||
// we have the socket handle, delete it for child processes we create like shell
|
||||
sock_in = sock_out = newsock = w32_allocate_fd_for_handle((HANDLE)remotesochandle, TRUE);
|
||||
|
||||
// we have the socket handle, delete it for child processes we create like shell
|
||||
SetEnvironmentVariable("SSHD_REMSOC", NULL);
|
||||
SetHandleInformation(remotesochandle, HANDLE_FLAG_INHERIT, 0); // make the handle not to be inherited
|
||||
SetHandleInformation((HANDLE)remotesochandle, HANDLE_FLAG_INHERIT, 0); // make the handle not to be inherited
|
||||
|
||||
/*
|
||||
* We don't have a startup_pipe
|
||||
|
3
sshpty.c
3
sshpty.c
@ -240,9 +240,6 @@ pty_change_window_size(int ptyfd, u_int row, u_int col,
|
||||
(void) ioctl(ptyfd, TIOCSWINSZ, &w);
|
||||
#else
|
||||
extern HANDLE hOutputConsole ;
|
||||
if (ptyfd != 0) {
|
||||
hOutputConsole = (HANDLE)ptyfd;
|
||||
}
|
||||
#ifndef WIN32_PRAGMA_REMCON
|
||||
if (hOutputConsole != NULL) {
|
||||
ConSetScreenSize(col, row);
|
||||
|
Loading…
x
Reference in New Issue
Block a user