Source snapshot from Powershell/openssh-portable:latestw_all

This commit is contained in:
bingbing8 2017-06-02 17:25:34 -07:00
parent 9fd0cdab04
commit 2c3a1a95d0
190 changed files with 6034 additions and 7615 deletions

50
.gitignore vendored
View File

@ -1,7 +1,31 @@
################################################################################
# This .gitignore file was automatically created by Microsoft(R) Visual Studio.
################################################################################
# Ignores in parent branch
Makefile
buildpkg.sh
config.h
config.h.in
config.status
configure
openbsd-compat/Makefile
openbsd-compat/regress/Makefile
openssh.xml
opensshd.init
survey.sh
**/*.o
**/*.out
**/*.a
autom4te.cache/
scp
sftp
sftp-server
ssh
ssh-add
ssh-agent
ssh-keygen
ssh-keyscan
ssh-keysign
ssh-pkcs11-helper
sshd
# Ignores in Windows fork
/bin/x64/Debug
/contrib/win32/openssh/.vs/Win32-OpenSSH/v14
/contrib/win32/openssh/lib
@ -33,31 +57,17 @@ bld/
[Bb]in/
[Oo]bj/
[Ll]og/
# Visual Studio 2015 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# DNX
project.lock.json
project.fragment.lock.json
artifacts/
Properties/launchSettings.json
*_i.c
*_p.c
*_i.h
@ -284,4 +294,6 @@ __pycache__/
# Cake - Uncomment if you are using it
# tools/
contrib/win32/win32compat/inc/crtheaders.h
contrib/win32/win32compat/inc/crtheaders.h
contrib/win32/openssh/LibreSSLSDK/

View File

@ -11,3 +11,8 @@ f6ae971186ba68d066cd102e57d5b0b2c211a5ee systrace is dead.
96c5054e3e1f170c6276902d5bc65bb3b87a2603 remove DEBUGLIBS from Makefile
6da9a37f74aef9f9cc639004345ad893cad582d8 Update moduli file
77bcb50e47b68c7209c7f0a5a020d73761e5143b unset REGRESS_FAIL_EARLY
38c2133817cbcae75c88c63599ac54228f0fa384 Change COMPILER_VERSION tests
30c20180c87cbc99fa1020489fe7fd8245b6420c resync integrity.sh shell
1e6b51ddf767cbad0a4e63eb08026c127e654308 integrity.sh reliability
fe5b31f69a60d47171836911f144acff77810217 Makefile.inc bits
5781670c0578fe89663c9085ed3ba477cf7e7913 Delete sshconnect1.c

23
LICENCE
View File

@ -75,27 +75,6 @@ OpenSSH contains no GPL code.
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
2)
The 32-bit CRC compensation attack detector in deattack.c was
contributed by CORE SDI S.A. under a BSD-style license.
* Cryptographic attack detector for ssh - source code
*
* Copyright (c) 1998 CORE SDI S.A., Buenos Aires, Argentina.
*
* All rights reserved. Redistribution and use in source and binary
* forms, with or without modification, are permitted provided that
* this copyright notice is retained.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES ARE DISCLAIMED. IN NO EVENT SHALL CORE SDI S.A. BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY OR
* CONSEQUENTIAL DAMAGES RESULTING FROM THE USE OR MISUSE OF THIS
* SOFTWARE.
*
* Ariel Futoransky <futo@core-sdi.com>
* <http://www.core-sdi.com>
3)
ssh-keyscan was contributed by David Mazieres under a BSD-style
license.
@ -337,4 +316,4 @@ OpenSSH contains no GPL code.
------
$OpenBSD: LICENCE,v 1.19 2004/08/30 09:18:08 markus Exp $
$OpenBSD: LICENCE,v 1.20 2017/04/30 23:26:16 djm Exp $

View File

@ -78,8 +78,8 @@ LIBOPENSSH_OBJS=\
LIBSSH_OBJS=${LIBOPENSSH_OBJS} \
authfd.o authfile.o bufaux.o bufbn.o bufec.o buffer.o \
canohost.o channels.o cipher.o cipher-aes.o cipher-aesctr.o \
cipher-bf1.o cipher-ctr.o cipher-3des1.o cleanup.o \
compat.o crc32.o deattack.o fatal.o hostfile.o \
cipher-ctr.o cleanup.o \
compat.o crc32.o fatal.o hostfile.o \
log.o match.o moduli.o nchan.o packet.o opacket.o \
readpass.o rsa.o ttymodes.o xmalloc.o addrmatch.o \
atomicio.o key.o dispatch.o mac.o uidswap.o uuencode.o misc.o utf8.o \
@ -95,7 +95,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \
platform-pledge.o platform-tracing.o
SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \
sshconnect.o sshconnect1.o sshconnect2.o mux.o
sshconnect.o sshconnect2.o mux.o
SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o \
audit.o audit-bsm.o audit-linux.o platform.o \
@ -228,26 +228,27 @@ umac128.o: umac.c
clean: regressclean
rm -f *.o *.a $(TARGETS) logintest config.cache config.log
rm -f *.out core survey
rm -f regress/check-perm$(EXEEXT)
rm -f regress/unittests/test_helper/*.a
rm -f regress/unittests/test_helper/*.o
rm -f regress/unittests/sshbuf/*.o
rm -f regress/unittests/sshbuf/test_sshbuf
rm -f regress/unittests/sshbuf/test_sshbuf$(EXEEXT)
rm -f regress/unittests/sshkey/*.o
rm -f regress/unittests/sshkey/test_sshkey
rm -f regress/unittests/sshkey/test_sshkey$(EXEEXT)
rm -f regress/unittests/bitmap/*.o
rm -f regress/unittests/bitmap/test_bitmap
rm -f regress/unittests/bitmap/test_bitmap$(EXEEXT)
rm -f regress/unittests/conversion/*.o
rm -f regress/unittests/conversion/test_conversion
rm -f regress/unittests/conversion/test_conversion$(EXEEXT)
rm -f regress/unittests/hostkeys/*.o
rm -f regress/unittests/hostkeys/test_hostkeys
rm -f regress/unittests/hostkeys/test_hostkeys$(EXEEXT)
rm -f regress/unittests/kex/*.o
rm -f regress/unittests/kex/test_kex
rm -f regress/unittests/kex/test_kex$(EXEEXT)
rm -f regress/unittests/match/*.o
rm -f regress/unittests/match/test_match
rm -f regress/unittests/match/test_match$(EXEEXT)
rm -f regress/unittests/utf8/*.o
rm -f regress/unittests/utf8/test_utf8
rm -f regress/unittests/utf8/test_utf8$(EXEEXT)
rm -f regress/misc/kexfuzz/*.o
rm -f regress/misc/kexfuzz/kexfuzz
rm -f regress/misc/kexfuzz/kexfuzz$(EXEEXT)
(cd openbsd-compat && $(MAKE) clean)
distclean: regressclean

View File

@ -192,12 +192,13 @@ compatibility.
The reserved field is currently unused and is ignored in this version of
the protocol.
signature key contains the CA key used to sign the certificate.
The valid key types for CA keys are ssh-rsa, ssh-dss and the ECDSA types
ecdsa-sha2-nistp256, ecdsa-sha2-nistp384, ecdsa-sha2-nistp521. "Chained"
certificates, where the signature key type is a certificate type itself
are NOT supported. Note that it is possible for a RSA certificate key to
be signed by a DSS or ECDSA CA key and vice-versa.
The signature key field contains the CA key used to sign the
certificate. The valid key types for CA keys are ssh-rsa,
ssh-dss, ssh-ed25519 and the ECDSA types ecdsa-sha2-nistp256,
ecdsa-sha2-nistp384, ecdsa-sha2-nistp521. "Chained" certificates, where
the signature key type is a certificate type itself are NOT supported.
Note that it is possible for a RSA certificate key to be signed by a
Ed25519 or ECDSA CA key and vice-versa.
signature is computed over all preceding fields from the initial string
up to, and including the signature key. Signatures are computed and
@ -284,4 +285,4 @@ permit-user-rc empty Flag indicating that execution of
of this script will not be permitted if
this option is not present.
$OpenBSD: PROTOCOL.certkeys,v 1.10 2016/05/03 10:27:59 djm Exp $
$OpenBSD: PROTOCOL.certkeys,v 1.11 2017/05/16 16:54:05 djm Exp $

View File

@ -1,4 +1,4 @@
version: 0.0.14.0.{build}
version: 0.0.15.0.{build}
image: Visual Studio 2015
branches:
@ -37,4 +37,4 @@ after_test:
on_finish:
- ps: |
Import-Module $env:APPVEYOR_BUILD_FOLDER\contrib\win32\openssh\AppveyorHelper.psm1 -DisableNameChecking
Publish-Artifact
Publish-Artifact

3
auth.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: auth.c,v 1.119 2016/12/15 21:29:05 dtucker Exp $ */
/* $OpenBSD: auth.c,v 1.120 2017/05/17 01:24:17 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@ -651,6 +651,7 @@ getpwnamallow(const char *user)
ci->user = user;
parse_server_match_config(&options, ci);
log_change_level(options.log_level);
#if defined(_AIX) && defined(HAVE_SETAUTHDB)
aix_setauthdb(user);

169
authfd.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: authfd.c,v 1.100 2015/12/04 16:41:28 markus Exp $ */
/* $OpenBSD: authfd.c,v 1.103 2017/05/05 10:42:49 naddy Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -204,43 +204,6 @@ ssh_lock_agent(int sock, int lock, const char *password)
return r;
}
#ifdef WITH_SSH1
static int
deserialise_identity1(struct sshbuf *ids, struct sshkey **keyp, char **commentp)
{
struct sshkey *key;
int r, keybits;
u_int32_t bits;
char *comment = NULL;
if ((key = sshkey_new(KEY_RSA1)) == NULL)
return SSH_ERR_ALLOC_FAIL;
if ((r = sshbuf_get_u32(ids, &bits)) != 0 ||
(r = sshbuf_get_bignum1(ids, key->rsa->e)) != 0 ||
(r = sshbuf_get_bignum1(ids, key->rsa->n)) != 0 ||
(r = sshbuf_get_cstring(ids, &comment, NULL)) != 0)
goto out;
keybits = BN_num_bits(key->rsa->n);
/* XXX previously we just warned here. I think we should be strict */
if (keybits < 0 || bits != (u_int)keybits) {
r = SSH_ERR_KEY_BITS_MISMATCH;
goto out;
}
if (keyp != NULL) {
*keyp = key;
key = NULL;
}
if (commentp != NULL) {
*commentp = comment;
comment = NULL;
}
r = 0;
out:
sshkey_free(key);
free(comment);
return r;
}
#endif
static int
deserialise_identity2(struct sshbuf *ids, struct sshkey **keyp, char **commentp)
@ -269,35 +232,21 @@ deserialise_identity2(struct sshbuf *ids, struct sshkey **keyp, char **commentp)
* Fetch list of identities held by the agent.
*/
int
ssh_fetch_identitylist(int sock, int version, struct ssh_identitylist **idlp)
ssh_fetch_identitylist(int sock, struct ssh_identitylist **idlp)
{
u_char type, code1 = 0, code2 = 0;
u_char type;
u_int32_t num, i;
struct sshbuf *msg;
struct ssh_identitylist *idl = NULL;
int r;
/* Determine request and expected response types */
switch (version) {
case 1:
code1 = SSH_AGENTC_REQUEST_RSA_IDENTITIES;
code2 = SSH_AGENT_RSA_IDENTITIES_ANSWER;
break;
case 2:
code1 = SSH2_AGENTC_REQUEST_IDENTITIES;
code2 = SSH2_AGENT_IDENTITIES_ANSWER;
break;
default:
return SSH_ERR_INVALID_ARGUMENT;
}
/*
* Send a message to the agent requesting for a list of the
* identities it can represent.
*/
if ((msg = sshbuf_new()) == NULL)
return SSH_ERR_ALLOC_FAIL;
if ((r = sshbuf_put_u8(msg, code1)) != 0)
if ((r = sshbuf_put_u8(msg, SSH2_AGENTC_REQUEST_IDENTITIES)) != 0)
goto out;
if ((r = ssh_request_reply(sock, msg, msg)) != 0)
@ -309,7 +258,7 @@ ssh_fetch_identitylist(int sock, int version, struct ssh_identitylist **idlp)
if (agent_failed(type)) {
r = SSH_ERR_AGENT_FAILURE;
goto out;
} else if (type != code2) {
} else if (type != SSH2_AGENT_IDENTITIES_ANSWER) {
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
@ -334,25 +283,14 @@ ssh_fetch_identitylist(int sock, int version, struct ssh_identitylist **idlp)
goto out;
}
for (i = 0; i < num;) {
switch (version) {
case 1:
#ifdef WITH_SSH1
if ((r = deserialise_identity1(msg,
&(idl->keys[i]), &(idl->comments[i]))) != 0)
if ((r = deserialise_identity2(msg, &(idl->keys[i]),
&(idl->comments[i]))) != 0) {
if (r == SSH_ERR_KEY_TYPE_UNKNOWN) {
/* Gracefully skip unknown key types */
num--;
continue;
} else
goto out;
#endif
break;
case 2:
if ((r = deserialise_identity2(msg,
&(idl->keys[i]), &(idl->comments[i]))) != 0) {
if (r == SSH_ERR_KEY_TYPE_UNKNOWN) {
/* Gracefully skip unknown key types */
num--;
continue;
} else
goto out;
}
break;
}
i++;
}
@ -390,46 +328,6 @@ ssh_free_identitylist(struct ssh_identitylist *idl)
* otherwise.
*/
#ifdef WITH_SSH1
int
ssh_decrypt_challenge(int sock, struct sshkey* key, BIGNUM *challenge,
u_char session_id[16], u_char response[16])
{
struct sshbuf *msg;
int r;
u_char type;
if (key->type != KEY_RSA1)
return SSH_ERR_INVALID_ARGUMENT;
if ((msg = sshbuf_new()) == NULL)
return SSH_ERR_ALLOC_FAIL;
if ((r = sshbuf_put_u8(msg, SSH_AGENTC_RSA_CHALLENGE)) != 0 ||
(r = sshbuf_put_u32(msg, BN_num_bits(key->rsa->n))) != 0 ||
(r = sshbuf_put_bignum1(msg, key->rsa->e)) != 0 ||
(r = sshbuf_put_bignum1(msg, key->rsa->n)) != 0 ||
(r = sshbuf_put_bignum1(msg, challenge)) != 0 ||
(r = sshbuf_put(msg, session_id, 16)) != 0 ||
(r = sshbuf_put_u32(msg, 1)) != 0) /* Response type for proto 1.1 */
goto out;
if ((r = ssh_request_reply(sock, msg, msg)) != 0)
goto out;
if ((r = sshbuf_get_u8(msg, &type)) != 0)
goto out;
if (agent_failed(type)) {
r = SSH_ERR_AGENT_FAILURE;
goto out;
} else if (type != SSH_AGENT_RSA_RESPONSE) {
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
if ((r = sshbuf_get(msg, response, 16)) != 0)
goto out;
r = 0;
out:
sshbuf_free(msg);
return r;
}
#endif
/* encode signature algoritm in flag bits, so we can keep the msg format */
static u_int
@ -499,25 +397,6 @@ ssh_agent_sign(int sock, struct sshkey *key,
/* Encode key for a message to the agent. */
#ifdef WITH_SSH1
static int
ssh_encode_identity_rsa1(struct sshbuf *b, RSA *key, const char *comment)
{
int r;
/* To keep within the protocol: p < q for ssh. in SSL p > q */
if ((r = sshbuf_put_u32(b, BN_num_bits(key->n))) != 0 ||
(r = sshbuf_put_bignum1(b, key->n)) != 0 ||
(r = sshbuf_put_bignum1(b, key->e)) != 0 ||
(r = sshbuf_put_bignum1(b, key->d)) != 0 ||
(r = sshbuf_put_bignum1(b, key->iqmp)) != 0 ||
(r = sshbuf_put_bignum1(b, key->q)) != 0 ||
(r = sshbuf_put_bignum1(b, key->p)) != 0 ||
(r = sshbuf_put_cstring(b, comment)) != 0)
return r;
return 0;
}
#endif
static int
ssh_encode_identity_ssh2(struct sshbuf *b, struct sshkey *key,
@ -566,16 +445,6 @@ ssh_add_identity_constrained(int sock, struct sshkey *key, const char *comment,
return SSH_ERR_ALLOC_FAIL;
switch (key->type) {
#ifdef WITH_SSH1
case KEY_RSA1:
type = constrained ?
SSH_AGENTC_ADD_RSA_ID_CONSTRAINED :
SSH_AGENTC_ADD_RSA_IDENTITY;
if ((r = sshbuf_put_u8(msg, type)) != 0 ||
(r = ssh_encode_identity_rsa1(msg, key->rsa, comment)) != 0)
goto out;
break;
#endif
#ifdef WITH_OPENSSL
case KEY_RSA:
case KEY_RSA_CERT:
@ -625,16 +494,6 @@ ssh_remove_identity(int sock, struct sshkey *key)
if ((msg = sshbuf_new()) == NULL)
return SSH_ERR_ALLOC_FAIL;
#ifdef WITH_SSH1
if (key->type == KEY_RSA1) {
if ((r = sshbuf_put_u8(msg,
SSH_AGENTC_REMOVE_RSA_IDENTITY)) != 0 ||
(r = sshbuf_put_u32(msg, BN_num_bits(key->rsa->n))) != 0 ||
(r = sshbuf_put_bignum1(msg, key->rsa->e)) != 0 ||
(r = sshbuf_put_bignum1(msg, key->rsa->n)) != 0)
goto out;
} else
#endif
if (key->type != KEY_UNSPEC) {
if ((r = sshkey_to_blob(key, &blob, &blen)) != 0)
goto out;
@ -701,6 +560,10 @@ ssh_update_card(int sock, int add, const char *reader_id, const char *pin,
/*
* Removes all identities from the agent.
* This call is intended only for use by ssh-add(1) and like applications.
*
* This supports the SSH protocol 1 message to because, when clearing all
* keys from an agent, we generally want to clear both protocol v1 and v2
* keys.
*/
int
ssh_remove_all_identities(int sock, int version)

View File

@ -1,4 +1,4 @@
/* $OpenBSD: authfd.h,v 1.39 2015/12/04 16:41:28 markus Exp $ */
/* $OpenBSD: authfd.h,v 1.40 2017/05/05 10:42:49 naddy Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -27,8 +27,7 @@ int ssh_get_authentication_socket(int *fdp);
void ssh_close_authentication_socket(int sock);
int ssh_lock_agent(int sock, int lock, const char *password);
int ssh_fetch_identitylist(int sock, int version,
struct ssh_identitylist **idlp);
int ssh_fetch_identitylist(int sock, struct ssh_identitylist **idlp);
void ssh_free_identitylist(struct ssh_identitylist *idl);
int ssh_add_identity_constrained(int sock, struct sshkey *key,
const char *comment, u_int life, u_int confirm);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: authfile.c,v 1.122 2016/11/25 23:24:45 djm Exp $ */
/* $OpenBSD: authfile.c,v 1.124 2017/04/30 23:10:43 djm Exp $ */
/*
* Copyright (c) 2000, 2013 Markus Friedl. All rights reserved.
*
@ -61,14 +61,6 @@ sshkey_save_private_blob(struct sshbuf *keybuf, const char *filename)
if ((fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600)) < 0)
return SSH_ERR_SYSTEM_ERROR;
#ifdef WINDOWS /* WINDOWS */
/*
Set the owner of the private key file to current user and only grant
current user the full control access
*/
if (set_secure_file_permission(filename, NULL) != 0)
return SSH_ERR_SYSTEM_ERROR;
#endif /* WINDOWS */
if (atomicio(vwrite, fd, (u_char *)sshbuf_ptr(keybuf),
sshbuf_len(keybuf)) != sshbuf_len(keybuf)) {
oerrno = errno;
@ -122,7 +114,7 @@ sshkey_load_file(int fd, struct sshbuf *blob)
* implicit realloc() in the sshbuf code.
*/
if ((st.st_mode & S_IFREG) == 0 || st.st_size <= 0) {
st.st_size = 64*1024; /* 64k should be enough for anyone :) */
st.st_size = 64*1024; /* 64k ought to be enough for anybody. :) */
dontmax = 1;
}
if ((r = sshbuf_allocate(blob, st.st_size)) != 0 ||
@ -156,35 +148,6 @@ sshkey_load_file(int fd, struct sshbuf *blob)
return r;
}
#ifdef WITH_SSH1
/*
* Loads the public part of the ssh v1 key file. Returns NULL if an error was
* encountered (the file does not exist or is not readable), and the key
* otherwise.
*/
static int
sshkey_load_public_rsa1(int fd, struct sshkey **keyp, char **commentp)
{
struct sshbuf *b = NULL;
int r;
if (keyp != NULL)
*keyp = NULL;
if (commentp != NULL)
*commentp = NULL;
if ((b = sshbuf_new()) == NULL)
return SSH_ERR_ALLOC_FAIL;
if ((r = sshkey_load_file(fd, b)) != 0)
goto out;
if ((r = sshkey_parse_public_rsa1_fileblob(b, keyp, commentp)) != 0)
goto out;
r = 0;
out:
sshbuf_free(b);
return r;
}
#endif /* WITH_SSH1 */
/* XXX remove error() calls from here? */
int
@ -380,21 +343,7 @@ sshkey_load_public(const char *filename, struct sshkey **keyp, char **commentp)
if ((fd = open(filename, O_RDONLY)) < 0)
goto skip;
#ifdef WITH_SSH1
/* try rsa1 private key */
r = sshkey_load_public_rsa1(fd, keyp, commentp);
close(fd);
switch (r) {
case SSH_ERR_INTERNAL_ERROR:
case SSH_ERR_ALLOC_FAIL:
case SSH_ERR_INVALID_ARGUMENT:
case SSH_ERR_SYSTEM_ERROR:
case 0:
return r;
}
#else /* WITH_SSH1 */
close(fd);
#endif /* WITH_SSH1 */
/* try ssh2 public key */
if ((pub = sshkey_new(KEY_UNSPEC)) == NULL)
@ -406,17 +355,6 @@ sshkey_load_public(const char *filename, struct sshkey **keyp, char **commentp)
}
sshkey_free(pub);
#ifdef WITH_SSH1
/* try rsa1 public key */
if ((pub = sshkey_new(KEY_RSA1)) == NULL)
return SSH_ERR_ALLOC_FAIL;
if ((r = sshkey_try_load_public(pub, filename, commentp)) == 0) {
if (keyp != NULL)
*keyp = pub;
return 0;
}
sshkey_free(pub);
#endif /* WITH_SSH1 */
skip:
/* try .pub suffix */

View File

@ -53,8 +53,9 @@ void
bitmap_free(struct bitmap *b)
{
if (b != NULL && b->d != NULL) {
explicit_bzero(b->d, b->len);
bitmap_zero(b);
free(b->d);
b->d = NULL;
}
free(b);
}

42
bufbn.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: bufbn.c,v 1.12 2014/04/30 05:29:56 djm Exp $ */
/* $OpenBSD: bufbn.c,v 1.13 2017/04/30 23:23:54 djm Exp $ */
/*
* Copyright (c) 2012 Damien Miller <djm@mindrot.org>
@ -28,46 +28,6 @@
#include "log.h"
#include "ssherr.h"
#ifdef WITH_SSH1
int
buffer_put_bignum_ret(Buffer *buffer, const BIGNUM *value)
{
int ret;
if ((ret = sshbuf_put_bignum1(buffer, value)) != 0) {
error("%s: %s", __func__, ssh_err(ret));
return -1;
}
return 0;
}
void
buffer_put_bignum(Buffer *buffer, const BIGNUM *value)
{
if (buffer_put_bignum_ret(buffer, value) == -1)
fatal("%s: buffer error", __func__);
}
int
buffer_get_bignum_ret(Buffer *buffer, BIGNUM *value)
{
int ret;
if ((ret = sshbuf_get_bignum1(buffer, value)) != 0) {
error("%s: %s", __func__, ssh_err(ret));
return -1;
}
return 0;
}
void
buffer_get_bignum(Buffer *buffer, BIGNUM *value)
{
if (buffer_get_bignum_ret(buffer, value) == -1)
fatal("%s: buffer error", __func__);
}
#endif /* WITH_SSH1 */
int
buffer_put_bignum2_ret(Buffer *buffer, const BIGNUM *value)
{

View File

@ -1,4 +1,4 @@
/* $OpenBSD: buffer.h,v 1.25 2014/04/30 05:29:56 djm Exp $ */
/* $OpenBSD: buffer.h,v 1.26 2017/04/30 23:23:54 djm Exp $ */
/*
* Copyright (c) 2012 Damien Miller <djm@mindrot.org>
@ -49,9 +49,7 @@ int buffer_consume_end_ret(Buffer *, u_int);
#include <openssl/objects.h>
#include <openssl/bn.h>
void buffer_put_bignum(Buffer *, const BIGNUM *);
void buffer_put_bignum2(Buffer *, const BIGNUM *);
void buffer_get_bignum(Buffer *, BIGNUM *);
void buffer_get_bignum2(Buffer *, BIGNUM *);
void buffer_put_bignum2_from_string(Buffer *, const u_char *, u_int);
@ -75,8 +73,6 @@ void buffer_put_cstring(Buffer *, const char *);
#define buffer_skip_string(b) (void)buffer_get_string_ptr(b, NULL);
int buffer_put_bignum_ret(Buffer *, const BIGNUM *);
int buffer_get_bignum_ret(Buffer *, BIGNUM *);
int buffer_put_bignum2_ret(Buffer *, const BIGNUM *);
int buffer_get_bignum2_ret(Buffer *, BIGNUM *);
int buffer_get_short_ret(u_short *, Buffer *);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: channels.c,v 1.357 2017/02/01 02:59:09 dtucker Exp $ */
/* $OpenBSD: channels.c,v 1.359 2017/04/30 23:28:41 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -69,7 +69,6 @@
#include "openbsd-compat/sys-queue.h"
#include "xmalloc.h"
#include "ssh.h"
#include "ssh1.h"
#include "ssh2.h"
#include "ssherr.h"
#include "packet.h"
@ -571,14 +570,6 @@ channel_not_very_much_buffered_data(void)
for (i = 0; i < channels_alloc; i++) {
c = channels[i];
if (c != NULL && c->type == SSH_CHANNEL_OPEN) {
#if 0
if (!compat20 &&
buffer_len(&c->input) > packet_get_maxsize()) {
debug2("channel %d: big input buffer %d",
c->self, buffer_len(&c->input));
return 0;
}
#endif
if (buffer_len(&c->output) > packet_get_maxsize()) {
debug2("channel %d: big output buffer %u > %u",
c->self, buffer_len(&c->output),
@ -616,8 +607,6 @@ channel_still_open(void)
case SSH_CHANNEL_RUNIX_LISTENER:
continue;
case SSH_CHANNEL_LARVAL:
if (!compat20)
fatal("cannot happen: SSH_CHANNEL_LARVAL");
continue;
case SSH_CHANNEL_OPENING:
case SSH_CHANNEL_OPEN:
@ -627,11 +616,9 @@ channel_still_open(void)
return 1;
case SSH_CHANNEL_INPUT_DRAINING:
case SSH_CHANNEL_OUTPUT_DRAINING:
if (!compat13)
fatal("cannot happen: OUT_DRAIN");
return 1;
fatal("cannot happen: OUT_DRAIN");
default:
fatal("channel_still_open: bad channel type %d", c->type);
fatal("%s: bad channel type %d", __func__, c->type);
/* NOTREACHED */
}
}
@ -672,11 +659,9 @@ channel_find_open(void)
return i;
case SSH_CHANNEL_INPUT_DRAINING:
case SSH_CHANNEL_OUTPUT_DRAINING:
if (!compat13)
fatal("cannot happen: OUT_DRAIN");
return i;
fatal("cannot happen: OUT_DRAIN");
default:
fatal("channel_find_open: bad channel type %d", c->type);
fatal("%s: bad channel type %d", __func__, c->type);
/* NOTREACHED */
}
}
@ -895,23 +880,12 @@ channel_pre_connecting(Channel *c, fd_set *readset, fd_set *writeset)
FD_SET(c->sock, writeset);
}
static void
channel_pre_open_13(Channel *c, fd_set *readset, fd_set *writeset)
{
if (buffer_len(&c->input) < packet_get_maxsize())
FD_SET(c->sock, readset);
if (buffer_len(&c->output) > 0)
FD_SET(c->sock, writeset);
}
static void
channel_pre_open(Channel *c, fd_set *readset, fd_set *writeset)
{
u_int limit = compat20 ? c->remote_window : packet_get_maxsize();
if (c->istate == CHAN_INPUT_OPEN &&
limit > 0 &&
buffer_len(&c->input) < limit &&
c->remote_window > 0 &&
buffer_len(&c->input) < c->remote_window &&
buffer_check_alloc(&c->input, CHAN_RBUF))
FD_SET(c->rfd, readset);
if (c->ostate == CHAN_OUTPUT_OPEN ||
@ -927,8 +901,8 @@ channel_pre_open(Channel *c, fd_set *readset, fd_set *writeset)
}
}
/** XXX check close conditions, too */
if (compat20 && c->efd != -1 &&
!(c->istate == CHAN_INPUT_CLOSED && c->ostate == CHAN_OUTPUT_CLOSED)) {
if (c->efd != -1 && !(c->istate == CHAN_INPUT_CLOSED &&
c->ostate == CHAN_OUTPUT_CLOSED)) {
if (c->extended_usage == CHAN_EXTENDED_WRITE &&
buffer_len(&c->extended) > 0)
FD_SET(c->efd, writeset);
@ -941,29 +915,6 @@ channel_pre_open(Channel *c, fd_set *readset, fd_set *writeset)
/* XXX: What about efd? races? */
}
/* ARGSUSED */
static void
channel_pre_input_draining(Channel *c, fd_set *readset, fd_set *writeset)
{
if (buffer_len(&c->input) == 0) {
packet_start(SSH_MSG_CHANNEL_CLOSE);
packet_put_int(c->remote_id);
packet_send();
c->type = SSH_CHANNEL_CLOSED;
debug2("channel %d: closing after input drain.", c->self);
}
}
/* ARGSUSED */
static void
channel_pre_output_draining(Channel *c, fd_set *readset, fd_set *writeset)
{
if (buffer_len(&c->output) == 0)
chan_mark_dead(c);
else
FD_SET(c->sock, writeset);
}
/*
* This is a special state for X11 authentication spoofing. An opened X11
* connection (when authentication spoofing is being done) remains in this
@ -1038,32 +989,6 @@ x11_open_helper(Buffer *b)
return 1;
}
static void
channel_pre_x11_open_13(Channel *c, fd_set *readset, fd_set *writeset)
{
int ret = x11_open_helper(&c->output);
if (ret == 1) {
/* Start normal processing for the channel. */
c->type = SSH_CHANNEL_OPEN;
channel_pre_open_13(c, readset, writeset);
} else if (ret == -1) {
/*
* We have received an X11 connection that has bad
* authentication information.
*/
logit("X11 connection rejected because of wrong authentication.");
buffer_clear(&c->input);
buffer_clear(&c->output);
channel_close_fd(&c->sock);
c->sock = -1;
c->type = SSH_CHANNEL_CLOSED;
packet_start(SSH_MSG_CHANNEL_CLOSE);
packet_put_int(c->remote_id);
packet_send();
}
}
static void
channel_pre_x11_open(Channel *c, fd_set *readset, fd_set *writeset)
{
@ -1081,11 +1006,7 @@ channel_pre_x11_open(Channel *c, fd_set *readset, fd_set *writeset)
buffer_clear(&c->input);
chan_ibuf_empty(c);
buffer_clear(&c->output);
/* for proto v1, the peer will send an IEOF */
if (compat20)
chan_write_failed(c);
else
c->type = SSH_CHANNEL_OPEN;
chan_write_failed(c);
debug2("X11 closed %d i%d/o%d", c->self, c->istate, c->ostate);
}
}
@ -1449,28 +1370,19 @@ channel_post_x11_listener(Channel *c, fd_set *readset, fd_set *writeset)
nc = channel_new("accepted x11 socket",
SSH_CHANNEL_OPENING, newsock, newsock, -1,
c->local_window_max, c->local_maxpacket, 0, buf, 1);
if (compat20) {
packet_start(SSH2_MSG_CHANNEL_OPEN);
packet_put_cstring("x11");
packet_put_int(nc->self);
packet_put_int(nc->local_window_max);
packet_put_int(nc->local_maxpacket);
/* originator ipaddr and port */
packet_put_cstring(remote_ipaddr);
if (datafellows & SSH_BUG_X11FWD) {
debug2("ssh2 x11 bug compat mode");
} else {
packet_put_int(remote_port);
}
packet_send();
packet_start(SSH2_MSG_CHANNEL_OPEN);
packet_put_cstring("x11");
packet_put_int(nc->self);
packet_put_int(nc->local_window_max);
packet_put_int(nc->local_maxpacket);
/* originator ipaddr and port */
packet_put_cstring(remote_ipaddr);
if (datafellows & SSH_BUG_X11FWD) {
debug2("ssh2 x11 bug compat mode");
} else {
packet_start(SSH_SMSG_X11_OPEN);
packet_put_int(nc->self);
if (packet_get_protocol_flags() &
SSH_PROTOFLAG_HOST_IN_FWD_OPEN)
packet_put_cstring(buf);
packet_send();
packet_put_int(remote_port);
}
packet_send();
free(remote_ipaddr);
}
}
@ -1500,46 +1412,35 @@ port_open_helper(Channel *c, char *rtype)
free(c->remote_name);
c->remote_name = xstrdup(buf);
if (compat20) {
packet_start(SSH2_MSG_CHANNEL_OPEN);
packet_put_cstring(rtype);
packet_put_int(c->self);
packet_put_int(c->local_window_max);
packet_put_int(c->local_maxpacket);
if (strcmp(rtype, "direct-tcpip") == 0) {
/* target host, port */
packet_put_cstring(c->path);
packet_put_int(c->host_port);
} else if (strcmp(rtype, "direct-streamlocal@openssh.com") == 0) {
/* target path */
packet_put_cstring(c->path);
} else if (strcmp(rtype, "forwarded-streamlocal@openssh.com") == 0) {
/* listen path */
packet_put_cstring(c->path);
} else {
/* listen address, port */
packet_put_cstring(c->path);
packet_put_int(local_port);
}
if (strcmp(rtype, "forwarded-streamlocal@openssh.com") == 0) {
/* reserved for future owner/mode info */
packet_put_cstring("");
} else {
/* originator host and port */
packet_put_cstring(remote_ipaddr);
packet_put_int((u_int)remote_port);
}
packet_send();
} else {
packet_start(SSH_MSG_PORT_OPEN);
packet_put_int(c->self);
packet_start(SSH2_MSG_CHANNEL_OPEN);
packet_put_cstring(rtype);
packet_put_int(c->self);
packet_put_int(c->local_window_max);
packet_put_int(c->local_maxpacket);
if (strcmp(rtype, "direct-tcpip") == 0) {
/* target host, port */
packet_put_cstring(c->path);
packet_put_int(c->host_port);
if (packet_get_protocol_flags() &
SSH_PROTOFLAG_HOST_IN_FWD_OPEN)
packet_put_cstring(c->remote_name);
packet_send();
} else if (strcmp(rtype, "direct-streamlocal@openssh.com") == 0) {
/* target path */
packet_put_cstring(c->path);
} else if (strcmp(rtype, "forwarded-streamlocal@openssh.com") == 0) {
/* listen path */
packet_put_cstring(c->path);
} else {
/* listen address, port */
packet_put_cstring(c->path);
packet_put_int(local_port);
}
if (strcmp(rtype, "forwarded-streamlocal@openssh.com") == 0) {
/* reserved for future owner/mode info */
packet_put_cstring("");
} else {
/* originator host and port */
packet_put_cstring(remote_ipaddr);
packet_put_int((u_int)remote_port);
}
packet_send();
free(remote_ipaddr);
free(local_ipaddr);
}
@ -1649,16 +1550,11 @@ channel_post_auth_listener(Channel *c, fd_set *readset, fd_set *writeset)
SSH_CHANNEL_OPENING, newsock, newsock, -1,
c->local_window_max, c->local_maxpacket,
0, "accepted auth socket", 1);
if (compat20) {
packet_start(SSH2_MSG_CHANNEL_OPEN);
packet_put_cstring("auth-agent@openssh.com");
packet_put_int(nc->self);
packet_put_int(c->local_window_max);
packet_put_int(c->local_maxpacket);
} else {
packet_start(SSH_SMSG_AGENT_OPEN);
packet_put_int(nc->self);
}
packet_start(SSH2_MSG_CHANNEL_OPEN);
packet_put_cstring("auth-agent@openssh.com");
packet_put_int(nc->self);
packet_put_int(c->local_window_max);
packet_put_int(c->local_maxpacket);
packet_send();
}
}
@ -1680,17 +1576,11 @@ channel_post_connecting(Channel *c, fd_set *readset, fd_set *writeset)
c->self, c->connect_ctx.host, c->connect_ctx.port);
channel_connect_ctx_free(&c->connect_ctx);
c->type = SSH_CHANNEL_OPEN;
if (compat20) {
packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION);
packet_put_int(c->remote_id);
packet_put_int(c->self);
packet_put_int(c->local_window);
packet_put_int(c->local_maxpacket);
} else {
packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
packet_put_int(c->remote_id);
packet_put_int(c->self);
}
packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION);
packet_put_int(c->remote_id);
packet_put_int(c->self);
packet_put_int(c->local_window);
packet_put_int(c->local_maxpacket);
} else {
debug("channel %d: connection failed: %s",
c->self, strerror(err));
@ -1705,17 +1595,12 @@ channel_post_connecting(Channel *c, fd_set *readset, fd_set *writeset)
error("connect_to %.100s port %d: failed.",
c->connect_ctx.host, c->connect_ctx.port);
channel_connect_ctx_free(&c->connect_ctx);
if (compat20) {
packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE);
packet_put_int(c->remote_id);
packet_put_int(SSH2_OPEN_CONNECT_FAILED);
if (!(datafellows & SSH_BUG_OPENFAILURE)) {
packet_put_cstring(strerror(err));
packet_put_cstring("");
}
} else {
packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
packet_put_int(c->remote_id);
packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE);
packet_put_int(c->remote_id);
packet_put_int(SSH2_OPEN_CONNECT_FAILED);
if (!(datafellows & SSH_BUG_OPENFAILURE)) {
packet_put_cstring(strerror(err));
packet_put_cstring("");
}
chan_mark_dead(c);
}
@ -1749,10 +1634,6 @@ channel_handle_rfd(Channel *c, fd_set *readset, fd_set *writeset)
debug2("channel %d: not open", c->self);
chan_mark_dead(c);
return -1;
} else if (compat13) {
buffer_clear(&c->output);
c->type = SSH_CHANNEL_INPUT_DRAINING;
debug2("channel %d: input draining.", c->self);
} else {
chan_read_failed(c);
}
@ -1820,7 +1701,7 @@ channel_handle_wfd(Channel *c, fd_set *readset, fd_set *writeset)
}
#ifdef _AIX
/* XXX: Later AIX versions can't push as much data to tty */
if (compat20 && c->wfd_isatty)
if (c->wfd_isatty)
dlen = MIN(dlen, 8*1024);
#endif
@ -1833,17 +1714,13 @@ channel_handle_wfd(Channel *c, fd_set *readset, fd_set *writeset)
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 BROKEN_TCGETATTR_ICANON
if (compat20 && c->isatty && dlen >= 1 && buf[0] != '\r') {
if (c->isatty && dlen >= 1 && buf[0] != '\r') {
if (tcgetattr(c->wfd, &tio) == 0 &&
!(tio.c_lflag & ECHO) && (tio.c_lflag & ICANON)) {
/*
@ -1860,7 +1737,7 @@ channel_handle_wfd(Channel *c, fd_set *readset, fd_set *writeset)
buffer_consume(&c->output, len);
}
out:
if (compat20 && olen > 0)
if (olen > 0)
c->local_consumed += olen - buffer_len(&c->output);
return 1;
}
@ -1944,8 +1821,6 @@ channel_post_open(Channel *c, fd_set *readset, fd_set *writeset)
{
channel_handle_rfd(c, readset, writeset);
channel_handle_wfd(c, readset, writeset);
if (!compat20)
return;
channel_handle_efd(c, readset, writeset);
channel_check_window(c);
}
@ -1979,9 +1854,6 @@ channel_post_mux_client(Channel *c, fd_set *readset, fd_set *writeset)
u_int need;
ssize_t len;
if (!compat20)
fatal("%s: entered with !compat20", __func__);
if (c->rfd != -1 && !c->mux_pause && FD_ISSET(c->rfd, readset) &&
(c->istate == CHAN_INPUT_OPEN ||
c->istate == CHAN_INPUT_WAIT_DRAIN)) {
@ -2076,26 +1948,15 @@ channel_post_mux_listener(Channel *c, fd_set *readset, fd_set *writeset)
nc->flags |= CHAN_LOCAL;
}
/* ARGSUSED */
static void
channel_post_output_drain_13(Channel *c, fd_set *readset, fd_set *writeset)
channel_handler_init(void)
{
int len;
int i;
/* Send buffered output data to the socket. */
if (FD_ISSET(c->sock, writeset) && buffer_len(&c->output) > 0) {
len = write(c->sock, buffer_ptr(&c->output),
buffer_len(&c->output));
if (len <= 0)
buffer_clear(&c->output);
else
buffer_consume(&c->output, len);
for (i = 0; i < SSH_CHANNEL_MAX_TYPE; i++) {
channel_pre[i] = NULL;
channel_post[i] = NULL;
}
}
static void
channel_handler_init_20(void)
{
channel_pre[SSH_CHANNEL_OPEN] = &channel_pre_open;
channel_pre[SSH_CHANNEL_X11_OPEN] = &channel_pre_x11_open;
channel_pre[SSH_CHANNEL_PORT_LISTENER] = &channel_pre_listener;
@ -2122,64 +1983,6 @@ channel_handler_init_20(void)
channel_post[SSH_CHANNEL_MUX_CLIENT] = &channel_post_mux_client;
}
static void
channel_handler_init_13(void)
{
channel_pre[SSH_CHANNEL_OPEN] = &channel_pre_open_13;
channel_pre[SSH_CHANNEL_X11_OPEN] = &channel_pre_x11_open_13;
channel_pre[SSH_CHANNEL_X11_LISTENER] = &channel_pre_listener;
channel_pre[SSH_CHANNEL_PORT_LISTENER] = &channel_pre_listener;
channel_pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener;
channel_pre[SSH_CHANNEL_INPUT_DRAINING] = &channel_pre_input_draining;
channel_pre[SSH_CHANNEL_OUTPUT_DRAINING] = &channel_pre_output_draining;
channel_pre[SSH_CHANNEL_CONNECTING] = &channel_pre_connecting;
channel_pre[SSH_CHANNEL_DYNAMIC] = &channel_pre_dynamic;
channel_post[SSH_CHANNEL_OPEN] = &channel_post_open;
channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener;
channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener;
channel_post[SSH_CHANNEL_AUTH_SOCKET] = &channel_post_auth_listener;
channel_post[SSH_CHANNEL_OUTPUT_DRAINING] = &channel_post_output_drain_13;
channel_post[SSH_CHANNEL_CONNECTING] = &channel_post_connecting;
channel_post[SSH_CHANNEL_DYNAMIC] = &channel_post_open;
}
static void
channel_handler_init_15(void)
{
channel_pre[SSH_CHANNEL_OPEN] = &channel_pre_open;
channel_pre[SSH_CHANNEL_X11_OPEN] = &channel_pre_x11_open;
channel_pre[SSH_CHANNEL_X11_LISTENER] = &channel_pre_listener;
channel_pre[SSH_CHANNEL_PORT_LISTENER] = &channel_pre_listener;
channel_pre[SSH_CHANNEL_AUTH_SOCKET] = &channel_pre_listener;
channel_pre[SSH_CHANNEL_CONNECTING] = &channel_pre_connecting;
channel_pre[SSH_CHANNEL_DYNAMIC] = &channel_pre_dynamic;
channel_post[SSH_CHANNEL_X11_LISTENER] = &channel_post_x11_listener;
channel_post[SSH_CHANNEL_PORT_LISTENER] = &channel_post_port_listener;
channel_post[SSH_CHANNEL_AUTH_SOCKET] = &channel_post_auth_listener;
channel_post[SSH_CHANNEL_OPEN] = &channel_post_open;
channel_post[SSH_CHANNEL_CONNECTING] = &channel_post_connecting;
channel_post[SSH_CHANNEL_DYNAMIC] = &channel_post_open;
}
static void
channel_handler_init(void)
{
int i;
for (i = 0; i < SSH_CHANNEL_MAX_TYPE; i++) {
channel_pre[i] = NULL;
channel_post[i] = NULL;
}
if (compat20)
channel_handler_init_20();
else if (compat13)
channel_handler_init_13();
else
channel_handler_init_15();
}
/* gc dead channels */
static void
channel_garbage_collect(Channel *c)
@ -2314,16 +2117,9 @@ channel_output_poll(void)
* We are only interested in channels that can have buffered
* incoming data.
*/
if (compat13) {
if (c->type != SSH_CHANNEL_OPEN &&
c->type != SSH_CHANNEL_INPUT_DRAINING)
continue;
} else {
if (c->type != SSH_CHANNEL_OPEN)
continue;
}
if (compat20 &&
(c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD))) {
if (c->type != SSH_CHANNEL_OPEN)
continue;
if ((c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD))) {
/* XXX is this true? */
debug3("channel %d: will not send data after close", c->self);
continue;
@ -2361,24 +2157,12 @@ channel_output_poll(void)
* Send some data for the other side over the secure
* connection.
*/
if (compat20) {
if (len > c->remote_window)
len = c->remote_window;
if (len > c->remote_maxpacket)
len = c->remote_maxpacket;
} else {
if (packet_is_interactive()) {
if (len > 1024)
len = 512;
} else {
/* Keep the packets at reasonable size. */
if (len > packet_get_maxsize()/2)
len = packet_get_maxsize()/2;
}
}
if (len > c->remote_window)
len = c->remote_window;
if (len > c->remote_maxpacket)
len = c->remote_maxpacket;
if (len > 0) {
packet_start(compat20 ?
SSH2_MSG_CHANNEL_DATA : SSH_MSG_CHANNEL_DATA);
packet_start(SSH2_MSG_CHANNEL_DATA);
packet_put_int(c->remote_id);
packet_put_string(buffer_ptr(&c->input), len);
packet_send();
@ -2386,8 +2170,6 @@ channel_output_poll(void)
c->remote_window -= len;
}
} else if (c->istate == CHAN_INPUT_WAIT_DRAIN) {
if (compat13)
fatal("cannot happen: istate == INPUT_WAIT_DRAIN for proto 1.3");
/*
* input-buffer is empty and read-socket shutdown:
* tell peer, that we will not send more data: send IEOF.
@ -2400,8 +2182,7 @@ channel_output_poll(void)
chan_ibuf_empty(c);
}
/* Send extended data, i.e. stderr */
if (compat20 &&
!(c->flags & CHAN_EOF_SENT) &&
if (!(c->flags & CHAN_EOF_SENT) &&
c->remote_window > 0 &&
(len = buffer_len(&c->extended)) > 0 &&
c->extended_usage == CHAN_EXTENDED_READ) {
@ -2740,26 +2521,23 @@ channel_input_data(int type, u_int32_t seq, void *ctxt)
* that window updates are sent back. Otherwise the connection might
* deadlock.
*/
if (!compat13 && c->ostate != CHAN_OUTPUT_OPEN) {
if (compat20) {
c->local_window -= win_len;
c->local_consumed += win_len;
}
if (c->ostate != CHAN_OUTPUT_OPEN) {
c->local_window -= win_len;
c->local_consumed += win_len;
return 0;
}
if (compat20) {
if (win_len > c->local_maxpacket) {
logit("channel %d: rcvd big packet %d, maxpack %d",
c->self, win_len, c->local_maxpacket);
}
if (win_len > c->local_window) {
logit("channel %d: rcvd too much data %d, win %d",
c->self, win_len, c->local_window);
return 0;
}
c->local_window -= win_len;
if (win_len > c->local_maxpacket) {
logit("channel %d: rcvd big packet %d, maxpack %d",
c->self, win_len, c->local_maxpacket);
}
if (win_len > c->local_window) {
logit("channel %d: rcvd too much data %d, win %d",
c->self, win_len, c->local_window);
return 0;
}
c->local_window -= win_len;
if (c->datagram)
buffer_put_string(&c->output, data, data_len);
else
@ -2844,46 +2622,6 @@ channel_input_ieof(int type, u_int32_t seq, void *ctxt)
return 0;
}
/* ARGSUSED */
int
channel_input_close(int type, u_int32_t seq, void *ctxt)
{
int id;
Channel *c;
id = packet_get_int();
packet_check_eom();
c = channel_lookup(id);
if (c == NULL)
packet_disconnect("Received close for nonexistent channel %d.", id);
if (channel_proxy_upstream(c, type, seq, ctxt))
return 0;
/*
* Send a confirmation that we have closed the channel and no more
* data is coming for it.
*/
packet_start(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION);
packet_put_int(c->remote_id);
packet_send();
/*
* If the channel is in closed state, we have sent a close request,
* and the other side will eventually respond with a confirmation.
* Thus, we cannot free the channel here, because then there would be
* no-one to receive the confirmation. The channel gets freed when
* the confirmation arrives.
*/
if (c->type != SSH_CHANNEL_CLOSED) {
/*
* Not a closed channel - mark it as draining, which will
* cause it to be freed later.
*/
buffer_clear(&c->input);
c->type = SSH_CHANNEL_OUTPUT_DRAINING;
}
return 0;
}
/* proto version 1.5 overloads CLOSE_CONFIRMATION with OCLOSE */
/* ARGSUSED */
int
@ -2944,17 +2682,15 @@ channel_input_open_confirmation(int type, u_int32_t seq, void *ctxt)
c->remote_id = remote_id;
c->type = SSH_CHANNEL_OPEN;
if (compat20) {
c->remote_window = packet_get_int();
c->remote_maxpacket = packet_get_int();
if (c->open_confirm) {
debug2("callback start");
c->open_confirm(c->self, 1, c->open_confirm_ctx);
debug2("callback done");
}
debug2("channel %d: open confirm rwindow %u rmax %u", c->self,
c->remote_window, c->remote_maxpacket);
c->remote_window = packet_get_int();
c->remote_maxpacket = packet_get_int();
if (c->open_confirm) {
debug2("callback start");
c->open_confirm(c->self, 1, c->open_confirm_ctx);
debug2("callback done");
}
debug2("channel %d: open confirm rwindow %u rmax %u", c->self,
c->remote_window, c->remote_maxpacket);
packet_check_eom();
return 0;
}
@ -2994,21 +2730,19 @@ channel_input_open_failure(int type, u_int32_t seq, void *ctxt)
if (c->type != SSH_CHANNEL_OPENING)
packet_disconnect("Received open failure for "
"non-opening channel %d.", id);
if (compat20) {
reason = packet_get_int();
if (!(datafellows & SSH_BUG_OPENFAILURE)) {
msg = packet_get_string(NULL);
lang = packet_get_string(NULL);
}
logit("channel %d: open failed: %s%s%s", id,
reason2txt(reason), msg ? ": ": "", msg ? msg : "");
free(msg);
free(lang);
if (c->open_confirm) {
debug2("callback start");
c->open_confirm(c->self, 0, c->open_confirm_ctx);
debug2("callback done");
}
reason = packet_get_int();
if (!(datafellows & SSH_BUG_OPENFAILURE)) {
msg = packet_get_string(NULL);
lang = packet_get_string(NULL);
}
logit("channel %d: open failed: %s%s%s", id,
reason2txt(reason), msg ? ": ": "", msg ? msg : "");
free(msg);
free(lang);
if (c->open_confirm) {
debug2("callback start");
c->open_confirm(c->self, 0, c->open_confirm_ctx);
debug2("callback done");
}
packet_check_eom();
/* Schedule the channel for cleanup/deletion. */
@ -3024,9 +2758,6 @@ channel_input_window_adjust(int type, u_int32_t seq, void *ctxt)
int id;
u_int adjust, tmp;
if (!compat20)
return 0;
/* Get the channel number and verify it. */
id = packet_get_int();
c = channel_lookup(id);
@ -3047,38 +2778,6 @@ channel_input_window_adjust(int type, u_int32_t seq, void *ctxt)
return 0;
}
/* ARGSUSED */
int
channel_input_port_open(int type, u_int32_t seq, void *ctxt)
{
Channel *c = NULL;
u_short host_port;
char *host, *originator_string;
int remote_id;
remote_id = packet_get_int();
host = packet_get_string(NULL);
host_port = packet_get_int();
if (packet_get_protocol_flags() & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) {
originator_string = packet_get_string(NULL);
} else {
originator_string = xstrdup("unknown (remote did not supply name)");
}
packet_check_eom();
c = channel_connect_to_port(host, host_port,
"connected socket", originator_string, NULL, NULL);
free(originator_string);
free(host);
if (c == NULL) {
packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
packet_put_int(remote_id);
packet_send();
} else
c->remote_id = remote_id;
return 0;
}
/* ARGSUSED */
int
channel_input_status_confirm(int type, u_int32_t seq, void *ctxt)
@ -3583,49 +3282,24 @@ channel_rfwd_bind_host(const char *listen_host)
int
channel_request_remote_forwarding(struct Forward *fwd)
{
int type, success = 0, idx = -1;
int success = 0, idx = -1;
/* Send the forward request to the remote side. */
if (compat20) {
packet_start(SSH2_MSG_GLOBAL_REQUEST);
if (fwd->listen_path != NULL) {
packet_put_cstring("streamlocal-forward@openssh.com");
packet_put_char(1); /* boolean: want reply */
packet_put_cstring(fwd->listen_path);
} else {
packet_put_cstring("tcpip-forward");
packet_put_char(1); /* boolean: want reply */
packet_put_cstring(channel_rfwd_bind_host(fwd->listen_host));
packet_put_int(fwd->listen_port);
}
packet_send();
packet_write_wait();
/* Assume that server accepts the request */
success = 1;
} else if (fwd->listen_path == NULL) {
packet_start(SSH_CMSG_PORT_FORWARD_REQUEST);
packet_put_int(fwd->listen_port);
packet_put_cstring(fwd->connect_host);
packet_put_int(fwd->connect_port);
packet_send();
packet_write_wait();
/* Wait for response from the remote side. */
type = packet_read();
switch (type) {
case SSH_SMSG_SUCCESS:
success = 1;
break;
case SSH_SMSG_FAILURE:
break;
default:
/* Unknown packet */
packet_disconnect("Protocol error for port forward request:"
"received packet type %d.", type);
}
packet_start(SSH2_MSG_GLOBAL_REQUEST);
if (fwd->listen_path != NULL) {
packet_put_cstring("streamlocal-forward@openssh.com");
packet_put_char(1); /* boolean: want reply */
packet_put_cstring(fwd->listen_path);
} else {
logit("Warning: Server does not support remote stream local forwarding.");
packet_put_cstring("tcpip-forward");
packet_put_char(1); /* boolean: want reply */
packet_put_cstring(channel_rfwd_bind_host(fwd->listen_host));
packet_put_int(fwd->listen_port);
}
packet_send();
packet_write_wait();
/* Assume that server accepts the request */
success = 1;
if (success) {
/* Record that connection to this host/port is permitted. */
permitted_opens = xreallocarray(permitted_opens,
@ -3724,9 +3398,6 @@ channel_request_rforward_cancel_tcpip(const char *host, u_short port)
{
int i;
if (!compat20)
return -1;
for (i = 0; i < num_permitted_opens; i++) {
if (open_listen_match_tcpip(&permitted_opens[i], host, port, 0))
break;
@ -3763,9 +3434,6 @@ channel_request_rforward_cancel_streamlocal(const char *path)
{
int i;
if (!compat20)
return -1;
for (i = 0; i < num_permitted_opens; i++) {
if (open_listen_match_streamlocal(&permitted_opens[i], path))
break;
@ -4516,81 +4184,6 @@ x11_connect_display(void)
return sock;
}
/*
* This is called when SSH_SMSG_X11_OPEN is received. The packet contains
* the remote channel number. We should do whatever we want, and respond
* with either SSH_MSG_OPEN_CONFIRMATION or SSH_MSG_OPEN_FAILURE.
*/
/* ARGSUSED */
int
x11_input_open(int type, u_int32_t seq, void *ctxt)
{
Channel *c = NULL;
int remote_id, sock = 0;
char *remote_host;
debug("Received X11 open request.");
remote_id = packet_get_int();
if (packet_get_protocol_flags() & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) {
remote_host = packet_get_string(NULL);
} else {
remote_host = xstrdup("unknown (remote did not supply name)");
}
packet_check_eom();
/* Obtain a connection to the real X display. */
sock = x11_connect_display();
if (sock != -1) {
/* Allocate a channel for this connection. */
c = channel_new("connected x11 socket",
SSH_CHANNEL_X11_OPEN, sock, sock, -1, 0, 0, 0,
remote_host, 1);
c->remote_id = remote_id;
c->force_drain = 1;
}
free(remote_host);
if (c == NULL) {
/* Send refusal to the remote host. */
packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
packet_put_int(remote_id);
} else {
/* Send a confirmation to the remote host. */
packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
packet_put_int(remote_id);
packet_put_int(c->self);
}
packet_send();
return 0;
}
/* dummy protocol handler that denies SSH-1 requests (agent/x11) */
/* ARGSUSED */
int
deny_input_open(int type, u_int32_t seq, void *ctxt)
{
int rchan = packet_get_int();
switch (type) {
case SSH_SMSG_AGENT_OPEN:
error("Warning: ssh server tried agent forwarding.");
break;
case SSH_SMSG_X11_OPEN:
error("Warning: ssh server tried X11 forwarding.");
break;
default:
error("deny_input_open: type %d", type);
break;
}
error("Warning: this is probably a break-in attempt by a malicious server.");
packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
packet_put_int(rchan);
packet_send();
return 0;
}
/*
* Requests forwarding of X11 connections, generates fake authentication
* data, and enables authentication spoofing.
@ -4646,12 +4239,8 @@ x11_request_forwarding_with_spoofing(int client_session_id, const char *disp,
new_data = tohex(x11_fake_data, data_len);
/* Send the request packet. */
if (compat20) {
channel_request_start(client_session_id, "x11-req", want_reply);
packet_put_char(0); /* XXX bool single connection */
} else {
packet_start(SSH_CMSG_X11_REQUEST_FORWARDING);
}
channel_request_start(client_session_id, "x11-req", want_reply);
packet_put_char(0); /* XXX bool single connection */
packet_put_cstring(proto);
packet_put_cstring(new_data);
packet_put_int(screen_number);
@ -4659,16 +4248,3 @@ x11_request_forwarding_with_spoofing(int client_session_id, const char *disp,
packet_write_wait();
free(new_data);
}
/* -- agent forwarding */
/* Sends a message to the server to request authentication fd forwarding. */
void
auth_request_forwarding(void)
{
packet_start(SSH_CMSG_AGENT_REQUEST_FORWARDING);
packet_send();
packet_write_wait();
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: channels.h,v 1.121 2017/02/01 02:59:09 dtucker Exp $ */
/* $OpenBSD: channels.h,v 1.123 2017/04/30 23:28:41 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -200,11 +200,11 @@ struct Channel {
/* check whether 'efd' is still in use */
#define CHANNEL_EFD_INPUT_ACTIVE(c) \
(compat20 && c->extended_usage == CHAN_EXTENDED_READ && \
(c->extended_usage == CHAN_EXTENDED_READ && \
(c->efd != -1 || \
buffer_len(&c->extended) > 0))
#define CHANNEL_EFD_OUTPUT_ACTIVE(c) \
(compat20 && c->extended_usage == CHAN_EXTENDED_WRITE && \
(c->extended_usage == CHAN_EXTENDED_WRITE && \
c->efd != -1 && (!(c->flags & (CHAN_EOF_RCVD|CHAN_CLOSE_RCVD)) || \
buffer_len(&c->extended) > 0))
@ -238,7 +238,6 @@ int channel_proxy_upstream(Channel *, int, u_int32_t, void *);
/* protocol handler */
int channel_input_close(int, u_int32_t, void *);
int channel_input_close_confirmation(int, u_int32_t, void *);
int channel_input_data(int, u_int32_t, void *);
int channel_input_extended_data(int, u_int32_t, void *);
@ -246,7 +245,6 @@ int channel_input_ieof(int, u_int32_t, void *);
int channel_input_oclose(int, u_int32_t, void *);
int channel_input_open_confirmation(int, u_int32_t, void *);
int channel_input_open_failure(int, u_int32_t, void *);
int channel_input_port_open(int, u_int32_t, void *);
int channel_input_window_adjust(int, u_int32_t, void *);
int channel_input_status_confirm(int, u_int32_t, void *);
@ -295,14 +293,8 @@ int permitopen_port(const char *);
void channel_set_x11_refuse_time(u_int);
int x11_connect_display(void);
int x11_create_display_inet(int, int, int, u_int *, int **);
int x11_input_open(int, u_int32_t, void *);
void x11_request_forwarding_with_spoofing(int, const char *, const char *,
const char *, int);
int deny_input_open(int, u_int32_t, void *);
/* agent forwarding */
void auth_request_forwarding(void);
/* channel close */

303
cipher.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: cipher.c,v 1.102 2016/08/03 05:41:57 djm Exp $ */
/* $OpenBSD: cipher.c,v 1.107 2017/05/07 23:12:57 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -51,11 +51,6 @@
#include "openbsd-compat/openssl-compat.h"
#ifdef WITH_SSH1
extern const EVP_CIPHER *evp_ssh1_bf(void);
extern const EVP_CIPHER *evp_ssh1_3des(void);
extern int ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int);
#endif
struct sshcipher_ctx {
int plaintext;
@ -68,17 +63,16 @@ struct sshcipher_ctx {
struct sshcipher {
char *name;
int number; /* for ssh1 only */
u_int block_size;
u_int key_len;
u_int iv_len; /* defaults to block_size */
u_int auth_len;
u_int discard_len;
u_int flags;
#define CFLAG_CBC (1<<0)
#define CFLAG_CHACHAPOLY (1<<1)
#define CFLAG_AESCTR (1<<2)
#define CFLAG_NONE (1<<3)
#define CFLAG_INTERNAL CFLAG_NONE /* Don't use "none" for packets */
#ifdef WITH_OPENSSL
const EVP_CIPHER *(*evptype)(void);
#else
@ -87,53 +81,32 @@ struct sshcipher {
};
static const struct sshcipher ciphers[] = {
#ifdef WITH_SSH1
{ "des", SSH_CIPHER_DES, 8, 8, 0, 0, 0, 1, EVP_des_cbc },
{ "3des", SSH_CIPHER_3DES, 8, 16, 0, 0, 0, 1, evp_ssh1_3des },
# ifndef OPENSSL_NO_BF
{ "blowfish", SSH_CIPHER_BLOWFISH, 8, 32, 0, 0, 0, 1, evp_ssh1_bf },
# endif /* OPENSSL_NO_BF */
#endif /* WITH_SSH1 */
#ifdef WITH_OPENSSL
{ "none", SSH_CIPHER_NONE, 8, 0, 0, 0, 0, 0, EVP_enc_null },
{ "3des-cbc", SSH_CIPHER_SSH2, 8, 24, 0, 0, 0, 1, EVP_des_ede3_cbc },
# ifndef OPENSSL_NO_BF
{ "blowfish-cbc",
SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 1, EVP_bf_cbc },
# endif /* OPENSSL_NO_BF */
# ifndef OPENSSL_NO_CAST
{ "cast128-cbc",
SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 1, EVP_cast5_cbc },
# endif /* OPENSSL_NO_CAST */
# ifndef OPENSSL_NO_RC4
{ "arcfour", SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 0, EVP_rc4 },
{ "arcfour128", SSH_CIPHER_SSH2, 8, 16, 0, 0, 1536, 0, EVP_rc4 },
{ "arcfour256", SSH_CIPHER_SSH2, 8, 32, 0, 0, 1536, 0, EVP_rc4 },
# endif /* OPENSSL_NO_RC4 */
{ "aes128-cbc", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 1, EVP_aes_128_cbc },
{ "aes192-cbc", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 1, EVP_aes_192_cbc },
{ "aes256-cbc", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 1, EVP_aes_256_cbc },
{ "3des-cbc", 8, 24, 0, 0, CFLAG_CBC, EVP_des_ede3_cbc },
{ "aes128-cbc", 16, 16, 0, 0, CFLAG_CBC, EVP_aes_128_cbc },
{ "aes192-cbc", 16, 24, 0, 0, CFLAG_CBC, EVP_aes_192_cbc },
{ "aes256-cbc", 16, 32, 0, 0, CFLAG_CBC, EVP_aes_256_cbc },
{ "rijndael-cbc@lysator.liu.se",
SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 1, EVP_aes_256_cbc },
{ "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, 0, EVP_aes_128_ctr },
{ "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, 0, EVP_aes_192_ctr },
{ "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, 0, EVP_aes_256_ctr },
16, 32, 0, 0, CFLAG_CBC, EVP_aes_256_cbc },
{ "aes128-ctr", 16, 16, 0, 0, 0, EVP_aes_128_ctr },
{ "aes192-ctr", 16, 24, 0, 0, 0, EVP_aes_192_ctr },
{ "aes256-ctr", 16, 32, 0, 0, 0, EVP_aes_256_ctr },
# ifdef OPENSSL_HAVE_EVPGCM
{ "aes128-gcm@openssh.com",
SSH_CIPHER_SSH2, 16, 16, 12, 16, 0, 0, EVP_aes_128_gcm },
16, 16, 12, 16, 0, EVP_aes_128_gcm },
{ "aes256-gcm@openssh.com",
SSH_CIPHER_SSH2, 16, 32, 12, 16, 0, 0, EVP_aes_256_gcm },
16, 32, 12, 16, 0, EVP_aes_256_gcm },
# endif /* OPENSSL_HAVE_EVPGCM */
#else /* WITH_OPENSSL */
{ "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, CFLAG_AESCTR, NULL },
{ "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, CFLAG_AESCTR, NULL },
{ "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, CFLAG_AESCTR, NULL },
{ "none", SSH_CIPHER_NONE, 8, 0, 0, 0, 0, CFLAG_NONE, NULL },
#endif /* WITH_OPENSSL */
#else
{ "aes128-ctr", 16, 16, 0, 0, CFLAG_AESCTR, NULL },
{ "aes192-ctr", 16, 24, 0, 0, CFLAG_AESCTR, NULL },
{ "aes256-ctr", 16, 32, 0, 0, CFLAG_AESCTR, NULL },
#endif
{ "chacha20-poly1305@openssh.com",
SSH_CIPHER_SSH2, 8, 64, 0, 16, 0, CFLAG_CHACHAPOLY, NULL },
8, 64, 0, 16, CFLAG_CHACHAPOLY, NULL },
{ "none", 8, 0, 0, 0, CFLAG_NONE, NULL },
{ NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL }
{ NULL, 0, 0, 0, 0, 0, NULL }
};
/*--*/
@ -147,7 +120,7 @@ cipher_alg_list(char sep, int auth_only)
const struct sshcipher *c;
for (c = ciphers; c->name != NULL; c++) {
if (c->number != SSH_CIPHER_SSH2)
if ((c->flags & CFLAG_INTERNAL) != 0)
continue;
if (auth_only && c->auth_len == 0)
continue;
@ -202,12 +175,6 @@ cipher_ivlen(const struct sshcipher *c)
c->iv_len : c->block_size;
}
u_int
cipher_get_number(const struct sshcipher *c)
{
return (c->number);
}
u_int
cipher_is_cbc(const struct sshcipher *c)
{
@ -220,24 +187,6 @@ cipher_ctx_is_plaintext(struct sshcipher_ctx *cc)
return cc->plaintext;
}
u_int
cipher_ctx_get_number(struct sshcipher_ctx *cc)
{
return cc->cipher->number;
}
u_int
cipher_mask_ssh1(int client)
{
u_int mask = 0;
mask |= 1 << SSH_CIPHER_3DES; /* Mandatory */
mask |= 1 << SSH_CIPHER_BLOWFISH;
if (client) {
mask |= 1 << SSH_CIPHER_DES;
}
return mask;
}
const struct sshcipher *
cipher_by_name(const char *name)
{
@ -248,16 +197,6 @@ cipher_by_name(const char *name)
return NULL;
}
const struct sshcipher *
cipher_by_number(int id)
{
const struct sshcipher *c;
for (c = ciphers; c->name != NULL; c++)
if (c->number == id)
return c;
return NULL;
}
#define CIPHER_SEP ","
int
ciphers_valid(const char *names)
@ -273,7 +212,7 @@ ciphers_valid(const char *names)
for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0';
(p = strsep(&cp, CIPHER_SEP))) {
c = cipher_by_name(p);
if (c == NULL || c->number != SSH_CIPHER_SSH2) {
if (c == NULL || (c->flags & CFLAG_INTERNAL) != 0) {
free(cipher_list);
return 0;
}
@ -282,38 +221,12 @@ ciphers_valid(const char *names)
return 1;
}
/*
* Parses the name of the cipher. Returns the number of the corresponding
* cipher, or -1 on error.
*/
int
cipher_number(const char *name)
{
const struct sshcipher *c;
if (name == NULL)
return -1;
for (c = ciphers; c->name != NULL; c++)
if (strcasecmp(c->name, name) == 0)
return c->number;
return -1;
}
char *
cipher_name(int id)
{
const struct sshcipher *c = cipher_by_number(id);
return (c==NULL) ? "<unknown>" : c->name;
}
const char *
cipher_warning_message(const struct sshcipher_ctx *cc)
{
if (cc == NULL || cc->cipher == NULL)
return NULL;
if (cc->cipher->number == SSH_CIPHER_DES)
return "use of DES is strongly discouraged due to "
"cryptographic weaknesses";
/* XXX repurpose for CBC warning */
return NULL;
}
@ -327,19 +240,13 @@ cipher_init(struct sshcipher_ctx **ccp, const struct sshcipher *cipher,
#ifdef WITH_OPENSSL
const EVP_CIPHER *type;
int klen;
u_char *junk, *discard;
#endif
*ccp = NULL;
if ((cc = calloc(sizeof(*cc), 1)) == NULL)
return SSH_ERR_ALLOC_FAIL;
if (cipher->number == SSH_CIPHER_DES) {
if (keylen > 8)
keylen = 8;
}
cc->plaintext = (cipher->number == SSH_CIPHER_NONE);
cc->plaintext = (cipher->flags & CFLAG_NONE) != 0;
cc->encrypt = do_encrypt;
if (keylen < cipher->key_len ||
@ -353,6 +260,10 @@ cipher_init(struct sshcipher_ctx **ccp, const struct sshcipher *cipher,
ret = chachapoly_init(&cc->cp_ctx, key, keylen);
goto out;
}
if ((cc->cipher->flags & CFLAG_NONE) != 0) {
ret = 0;
goto out;
}
#ifndef WITH_OPENSSL
if ((cc->cipher->flags & CFLAG_AESCTR) != 0) {
aesctr_keysetup(&cc->ac_ctx, key, 8 * keylen, 8 * ivlen);
@ -360,10 +271,6 @@ cipher_init(struct sshcipher_ctx **ccp, const struct sshcipher *cipher,
ret = 0;
goto out;
}
if ((cc->cipher->flags & CFLAG_NONE) != 0) {
ret = 0;
goto out;
}
ret = SSH_ERR_INVALID_ARGUMENT;
goto out;
#else /* WITH_OPENSSL */
@ -394,23 +301,6 @@ cipher_init(struct sshcipher_ctx **ccp, const struct sshcipher *cipher,
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
if (cipher->discard_len > 0) {
if ((junk = malloc(cipher->discard_len)) == NULL ||
(discard = malloc(cipher->discard_len)) == NULL) {
free(junk);
ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
ret = EVP_Cipher(cc->evp, discard, junk, cipher->discard_len);
explicit_bzero(discard, cipher->discard_len);
free(junk);
free(discard);
if (ret != 1) {
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
}
ret = 0;
#endif /* WITH_OPENSSL */
out:
@ -448,6 +338,10 @@ cipher_crypt(struct sshcipher_ctx *cc, u_int seqnr, u_char *dest,
return chachapoly_crypt(&cc->cp_ctx, seqnr, dest, src,
len, aadlen, authlen, cc->encrypt);
}
if ((cc->cipher->flags & CFLAG_NONE) != 0) {
memcpy(dest, src, aadlen + len);
return 0;
}
#ifndef WITH_OPENSSL
if ((cc->cipher->flags & CFLAG_AESCTR) != 0) {
if (aadlen)
@ -456,10 +350,6 @@ cipher_crypt(struct sshcipher_ctx *cc, u_int seqnr, u_char *dest,
dest + aadlen, len);
return 0;
}
if ((cc->cipher->flags & CFLAG_NONE) != 0) {
memcpy(dest, src, aadlen + len);
return 0;
}
return SSH_ERR_INVALID_ARGUMENT;
#else
if (authlen) {
@ -535,28 +425,6 @@ cipher_free(struct sshcipher_ctx *cc)
free(cc);
}
/*
* Selects the cipher, and keys if by computing the MD5 checksum of the
* passphrase and using the resulting 16 bytes as the key.
*/
int
cipher_set_key_string(struct sshcipher_ctx **ccp,
const struct sshcipher *cipher, const char *passphrase, int do_encrypt)
{
u_char digest[16];
int r = SSH_ERR_INTERNAL_ERROR;
if ((r = ssh_digest_memory(SSH_DIGEST_MD5,
passphrase, strlen(passphrase),
digest, sizeof(digest))) != 0)
goto out;
r = cipher_init(ccp, cipher, digest, 16, NULL, 0, do_encrypt);
out:
explicit_bzero(digest, sizeof(digest));
return r;
}
/*
* Exports an IV from the sshcipher_ctx required to export the key
* state back from the unprivileged child to the privileged parent
@ -566,19 +434,16 @@ int
cipher_get_keyiv_len(const struct sshcipher_ctx *cc)
{
const struct sshcipher *c = cc->cipher;
int ivlen = 0;
if (c->number == SSH_CIPHER_3DES)
ivlen = 24;
else if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0)
ivlen = 0;
else if ((cc->cipher->flags & CFLAG_AESCTR) != 0)
ivlen = sizeof(cc->ac_ctx.ctr);
if ((c->flags & CFLAG_CHACHAPOLY) != 0)
return 0;
else if ((c->flags & CFLAG_AESCTR) != 0)
return sizeof(cc->ac_ctx.ctr);
#ifdef WITH_OPENSSL
else
ivlen = EVP_CIPHER_CTX_iv_length(cc->evp);
#endif /* WITH_OPENSSL */
return (ivlen);
return EVP_CIPHER_CTX_iv_length(cc->evp);
#else
return 0;
#endif
}
int
@ -603,38 +468,26 @@ cipher_get_keyiv(struct sshcipher_ctx *cc, u_char *iv, u_int len)
if ((cc->cipher->flags & CFLAG_NONE) != 0)
return 0;
switch (c->number) {
#ifdef WITH_OPENSSL
case SSH_CIPHER_SSH2:
case SSH_CIPHER_DES:
case SSH_CIPHER_BLOWFISH:
evplen = EVP_CIPHER_CTX_iv_length(cc->evp);
if (evplen == 0)
return 0;
else if (evplen < 0)
return SSH_ERR_LIBCRYPTO_ERROR;
if ((u_int)evplen != len)
return SSH_ERR_INVALID_ARGUMENT;
#ifndef OPENSSL_HAVE_EVPCTR
if (c->evptype == evp_aes_128_ctr)
ssh_aes_ctr_iv(cc->evp, 0, iv, len);
else
#endif
if (cipher_authlen(c)) {
if (!EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_IV_GEN,
len, iv))
return SSH_ERR_LIBCRYPTO_ERROR;
} else
memcpy(iv, cc->evp->iv, len);
break;
#endif
#ifdef WITH_SSH1
case SSH_CIPHER_3DES:
return ssh1_3des_iv(cc->evp, 0, iv, 24);
#endif
default:
evplen = EVP_CIPHER_CTX_iv_length(cc->evp);
if (evplen == 0)
return 0;
else if (evplen < 0)
return SSH_ERR_LIBCRYPTO_ERROR;
if ((u_int)evplen != len)
return SSH_ERR_INVALID_ARGUMENT;
}
#ifndef OPENSSL_HAVE_EVPCTR
if (c->evptype == evp_aes_128_ctr)
ssh_aes_ctr_iv(cc->evp, 0, iv, len);
else
#endif
if (cipher_authlen(c)) {
if (!EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_IV_GEN,
len, iv))
return SSH_ERR_LIBCRYPTO_ERROR;
} else
memcpy(iv, cc->evp->iv, len);
#endif
return 0;
}
@ -651,36 +504,24 @@ cipher_set_keyiv(struct sshcipher_ctx *cc, const u_char *iv)
if ((cc->cipher->flags & CFLAG_NONE) != 0)
return 0;
switch (c->number) {
#ifdef WITH_OPENSSL
case SSH_CIPHER_SSH2:
case SSH_CIPHER_DES:
case SSH_CIPHER_BLOWFISH:
evplen = EVP_CIPHER_CTX_iv_length(cc->evp);
if (evplen <= 0)
return SSH_ERR_LIBCRYPTO_ERROR;
evplen = EVP_CIPHER_CTX_iv_length(cc->evp);
if (evplen <= 0)
return SSH_ERR_LIBCRYPTO_ERROR;
#ifndef OPENSSL_HAVE_EVPCTR
/* XXX iv arg is const, but ssh_aes_ctr_iv isn't */
if (c->evptype == evp_aes_128_ctr)
ssh_aes_ctr_iv(cc->evp, 1, (u_char *)iv, evplen);
else
/* XXX iv arg is const, but ssh_aes_ctr_iv isn't */
if (c->evptype == evp_aes_128_ctr)
ssh_aes_ctr_iv(cc->evp, 1, (u_char *)iv, evplen);
else
#endif
if (cipher_authlen(c)) {
/* XXX iv arg is const, but EVP_CIPHER_CTX_ctrl isn't */
if (!EVP_CIPHER_CTX_ctrl(cc->evp,
EVP_CTRL_GCM_SET_IV_FIXED, -1, (void *)iv))
return SSH_ERR_LIBCRYPTO_ERROR;
} else
memcpy(cc->evp->iv, iv, evplen);
break;
if (cipher_authlen(c)) {
/* XXX iv arg is const, but EVP_CIPHER_CTX_ctrl isn't */
if (!EVP_CIPHER_CTX_ctrl(cc->evp,
EVP_CTRL_GCM_SET_IV_FIXED, -1, (void *)iv))
return SSH_ERR_LIBCRYPTO_ERROR;
} else
memcpy(cc->evp->iv, iv, evplen);
#endif
#ifdef WITH_SSH1
case SSH_CIPHER_3DES:
return ssh1_3des_iv(cc->evp, 1, (u_char *)iv, 24);
#endif
default:
return SSH_ERR_INVALID_ARGUMENT;
}
return 0;
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: cipher.h,v 1.49 2016/08/03 05:41:57 djm Exp $ */
/* $OpenBSD: cipher.h,v 1.52 2017/05/07 23:12:57 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -42,34 +42,13 @@
#include "cipher-chachapoly.h"
#include "cipher-aesctr.h"
/*
* Cipher types for SSH-1. New types can be added, but old types should not
* be removed for compatibility. The maximum allowed value is 31.
*/
#define SSH_CIPHER_SSH2 -3
#define SSH_CIPHER_INVALID -2 /* No valid cipher selected. */
#define SSH_CIPHER_NOT_SET -1 /* None selected (invalid number). */
#define SSH_CIPHER_NONE 0 /* no encryption */
#define SSH_CIPHER_IDEA 1 /* IDEA CFB */
#define SSH_CIPHER_DES 2 /* DES CBC */
#define SSH_CIPHER_3DES 3 /* 3DES CBC */
#define SSH_CIPHER_BROKEN_TSS 4 /* TRI's Simple Stream encryption CBC */
#define SSH_CIPHER_BROKEN_RC4 5 /* Alleged RC4 */
#define SSH_CIPHER_BLOWFISH 6
#define SSH_CIPHER_RESERVED 7
#define SSH_CIPHER_MAX 31
#define CIPHER_ENCRYPT 1
#define CIPHER_DECRYPT 0
struct sshcipher;
struct sshcipher_ctx;
u_int cipher_mask_ssh1(int);
const struct sshcipher *cipher_by_name(const char *);
const struct sshcipher *cipher_by_number(int);
int cipher_number(const char *);
char *cipher_name(int);
const char *cipher_warning_message(const struct sshcipher_ctx *);
int ciphers_valid(const char *);
char *cipher_alg_list(char, int);
@ -80,8 +59,6 @@ int cipher_crypt(struct sshcipher_ctx *, u_int, u_char *, const u_char *,
int cipher_get_length(struct sshcipher_ctx *, u_int *, u_int,
const u_char *, u_int);
void cipher_free(struct sshcipher_ctx *);
int cipher_set_key_string(struct sshcipher_ctx **,
const struct sshcipher *, const char *, int);
u_int cipher_blocksize(const struct sshcipher *);
u_int cipher_keylen(const struct sshcipher *);
u_int cipher_seclen(const struct sshcipher *);
@ -90,13 +67,9 @@ u_int cipher_ivlen(const struct sshcipher *);
u_int cipher_is_cbc(const struct sshcipher *);
u_int cipher_ctx_is_plaintext(struct sshcipher_ctx *);
u_int cipher_ctx_get_number(struct sshcipher_ctx *);
u_int cipher_get_number(const struct sshcipher *);
int cipher_get_keyiv(struct sshcipher_ctx *, u_char *, u_int);
int cipher_set_keyiv(struct sshcipher_ctx *, const u_char *);
int cipher_get_keyiv_len(const struct sshcipher_ctx *);
int cipher_get_keycontext(const struct sshcipher_ctx *, u_char *);
void cipher_set_keycontext(struct sshcipher_ctx *, const u_char *);
#endif /* CIPHER_H */

View File

@ -1,4 +1,4 @@
/* $OpenBSD: clientloop.c,v 1.291 2017/03/10 05:01:13 djm Exp $ */
/* $OpenBSD: clientloop.c,v 1.296 2017/05/03 21:08:09 naddy Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -89,7 +89,6 @@
#include "openbsd-compat/sys-queue.h"
#include "xmalloc.h"
#include "ssh.h"
#include "ssh1.h"
#include "ssh2.h"
#include "packet.h"
#include "buffer.h"
@ -152,15 +151,9 @@ static time_t control_persist_exit_time = 0;
/* Common data for the client loop code. */
volatile sig_atomic_t quit_pending; /* Set non-zero to quit the loop. */
static int escape_char1; /* Escape character. (proto1 only) */
static int escape_pending1; /* Last character was an escape (proto1 only) */
static int last_was_cr; /* Last character was a newline. */
static int exit_status; /* Used to store the command exit status. */
static int stdin_eof; /* EOF has been encountered on stderr. */
static Buffer stdin_buffer; /* Buffer for stdin data. */
static Buffer stdout_buffer; /* Buffer for stdout data. */
static Buffer stderr_buffer; /* Buffer for stderr data. */
static u_int buffer_high; /* Soft max buffer size. */
static Buffer stderr_buffer; /* Used for final exit message. */
static int connection_in; /* Connection to server (input). */
static int connection_out; /* Connection to server (output). */
static int need_rekeying; /* Set to non-zero if rekeying is requested. */
@ -207,15 +200,6 @@ leave_non_blocking(void)
}
}
/* Puts stdin terminal in non-blocking mode. */
static void
enter_non_blocking(void)
{
in_non_blocking_mode = 1;
set_nonblock(fileno(stdin));
}
/*
* Signal handler for the window change signal (SIGWINCH). This just sets a
* flag indicating that the window has changed.
@ -454,91 +438,6 @@ client_x11_get_proto(const char *display, const char *xauth_path,
return 0;
}
/*
* This is called when the interactive is entered. This checks if there is
* an EOF coming on stdin. We must check this explicitly, as select() does
* not appear to wake up when redirecting from /dev/null.
*/
static void
client_check_initial_eof_on_stdin(void)
{
int len;
char buf[1];
/*
* If standard input is to be "redirected from /dev/null", we simply
* mark that we have seen an EOF and send an EOF message to the
* server. Otherwise, we try to read a single character; it appears
* that for some files, such /dev/null, select() never wakes up for
* read for this descriptor, which means that we never get EOF. This
* way we will get the EOF if stdin comes from /dev/null or similar.
*/
if (stdin_null_flag) {
/* Fake EOF on stdin. */
debug("Sending eof.");
stdin_eof = 1;
packet_start(SSH_CMSG_EOF);
packet_send();
} else {
enter_non_blocking();
/* Check for immediate EOF on stdin. */
len = read(fileno(stdin), buf, 1);
if (len == 0) {
/*
* EOF. Record that we have seen it and send
* EOF to server.
*/
debug("Sending eof.");
stdin_eof = 1;
packet_start(SSH_CMSG_EOF);
packet_send();
} else if (len > 0) {
/*
* Got data. We must store the data in the buffer,
* and also process it as an escape character if
* appropriate.
*/
if ((u_char) buf[0] == escape_char1)
escape_pending1 = 1;
else
buffer_append(&stdin_buffer, buf, 1);
}
leave_non_blocking();
}
}
/*
* Make packets from buffered stdin data, and buffer them for sending to the
* connection.
*/
static void
client_make_packets_from_stdin_data(void)
{
u_int len;
/* Send buffered stdin data to the server. */
while (buffer_len(&stdin_buffer) > 0 &&
packet_not_very_much_data_to_write()) {
len = buffer_len(&stdin_buffer);
/* Keep the packets at reasonable size. */
if (len > packet_get_maxsize())
len = packet_get_maxsize();
packet_start(SSH_CMSG_STDIN_DATA);
packet_put_string(buffer_ptr(&stdin_buffer), len);
packet_send();
buffer_consume(&stdin_buffer, len);
/* If we have a pending EOF, send it now. */
if (stdin_eof && buffer_len(&stdin_buffer) == 0) {
packet_start(SSH_CMSG_EOF);
packet_send();
}
}
}
/*
* Checks if the client window has changed, and sends a packet about it to
* the server if so. The actual change is detected elsewhere (by a software
@ -549,27 +448,14 @@ client_make_packets_from_stdin_data(void)
static void
client_check_window_change(void)
{
struct winsize ws;
if (! received_window_change_signal)
if (!received_window_change_signal)
return;
/** XXX race */
received_window_change_signal = 0;
debug2("client_check_window_change: changed");
debug2("%s: changed", __func__);
if (compat20) {
channel_send_window_changes();
} else {
if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0)
return;
packet_start(SSH_CMSG_WINDOW_SIZE);
packet_put_int((u_int)ws.ws_row);
packet_put_int((u_int)ws.ws_col);
packet_put_int((u_int)ws.ws_xpixel);
packet_put_int((u_int)ws.ws_ypixel);
packet_send();
}
channel_send_window_changes();
}
static int
@ -623,37 +509,17 @@ client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp,
channel_prepare_select(readsetp, writesetp, maxfdp, nallocp,
&minwait_secs, rekeying);
if (!compat20) {
/* Read from the connection, unless our buffers are full. */
if (buffer_len(&stdout_buffer) < buffer_high &&
buffer_len(&stderr_buffer) < buffer_high &&
channel_not_very_much_buffered_data())
FD_SET(connection_in, *readsetp);
/*
* Read from stdin, unless we have seen EOF or have very much
* buffered data to send to the server.
*/
if (!stdin_eof && packet_not_very_much_data_to_write())
FD_SET(fileno(stdin), *readsetp);
/* Select stdout/stderr if have data in buffer. */
if (buffer_len(&stdout_buffer) > 0)
FD_SET(fileno(stdout), *writesetp);
if (buffer_len(&stderr_buffer) > 0)
FD_SET(fileno(stderr), *writesetp);
} else {
/* channel_prepare_select could have closed the last channel */
if (session_closed && !channel_still_open() &&
!packet_have_data_to_write()) {
/* clear mask since we did not call select() */
memset(*readsetp, 0, *nallocp);
memset(*writesetp, 0, *nallocp);
return;
} else {
FD_SET(connection_in, *readsetp);
}
/* channel_prepare_select could have closed the last channel */
if (session_closed && !channel_still_open() &&
!packet_have_data_to_write()) {
/* clear mask since we did not call select() */
memset(*readsetp, 0, *nallocp);
memset(*writesetp, 0, *nallocp);
return;
}
FD_SET(connection_in, *readsetp);
/* Select server connection if have data to write to the server. */
if (packet_have_data_to_write())
FD_SET(connection_out, *writesetp);
@ -665,11 +531,11 @@ client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp,
*/
timeout_secs = INT_MAX; /* we use INT_MAX to mean no timeout */
if (options.server_alive_interval > 0 && compat20) {
if (options.server_alive_interval > 0) {
timeout_secs = options.server_alive_interval;
server_alive_time = now + options.server_alive_interval;
}
if (options.rekey_interval > 0 && compat20 && !rekeying)
if (options.rekey_interval > 0 && !rekeying)
timeout_secs = MINIMUM(timeout_secs, packet_get_rekey_timeout());
set_control_persist_exit_time();
if (control_persist_exit_time > 0) {
@ -966,11 +832,6 @@ process_cmdline(void)
goto out;
}
if (delete && !compat20) {
logit("Not supported for SSH protocol version 1.");
goto out;
}
while (isspace((u_char)*++s))
;
@ -1027,10 +888,9 @@ out:
/* reasons to suppress output of an escape command in help output */
#define SUPPRESS_NEVER 0 /* never suppress, always show */
#define SUPPRESS_PROTO1 1 /* don't show in protocol 1 sessions */
#define SUPPRESS_MUXCLIENT 2 /* don't show in mux client sessions */
#define SUPPRESS_MUXMASTER 4 /* don't show in mux master sessions */
#define SUPPRESS_SYSLOG 8 /* don't show when logging to syslog */
#define SUPPRESS_MUXCLIENT 1 /* don't show in mux client sessions */
#define SUPPRESS_MUXMASTER 2 /* don't show in mux master sessions */
#define SUPPRESS_SYSLOG 4 /* don't show when logging to syslog */
struct escape_help_text {
const char *cmd;
const char *text;
@ -1040,9 +900,9 @@ static struct escape_help_text esc_txt[] = {
{".", "terminate session", SUPPRESS_MUXMASTER},
{".", "terminate connection (and any multiplexed sessions)",
SUPPRESS_MUXCLIENT},
{"B", "send a BREAK to the remote system", SUPPRESS_PROTO1},
{"B", "send a BREAK to the remote system", SUPPRESS_NEVER},
{"C", "open a command line", SUPPRESS_MUXCLIENT},
{"R", "request rekey", SUPPRESS_PROTO1},
{"R", "request rekey", SUPPRESS_NEVER},
{"V/v", "decrease/increase verbosity (LogLevel)", SUPPRESS_MUXCLIENT},
{"^Z", "suspend ssh", SUPPRESS_MUXCLIENT},
{"#", "list forwarded connections", SUPPRESS_NEVER},
@ -1052,8 +912,7 @@ static struct escape_help_text esc_txt[] = {
};
static void
print_escape_help(Buffer *b, int escape_char, int protocol2, int mux_client,
int using_stderr)
print_escape_help(Buffer *b, int escape_char, int mux_client, int using_stderr)
{
unsigned int i, suppress_flags;
char string[1024];
@ -1062,7 +921,7 @@ print_escape_help(Buffer *b, int escape_char, int protocol2, int mux_client,
"Supported escape sequences:\r\n", escape_char);
buffer_append(b, string, strlen(string));
suppress_flags = (protocol2 ? 0 : SUPPRESS_PROTO1) |
suppress_flags =
(mux_client ? SUPPRESS_MUXCLIENT : 0) |
(mux_client ? 0 : SUPPRESS_MUXMASTER) |
(using_stderr ? 0 : SUPPRESS_SYSLOG);
@ -1083,7 +942,7 @@ print_escape_help(Buffer *b, int escape_char, int protocol2, int mux_client,
}
/*
* Process the characters one by one, call with c==NULL for proto1 case.
* Process the characters one by one.
*/
static int
process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
@ -1095,19 +954,11 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
u_int i;
u_char ch;
char *s;
int *escape_pendingp, escape_char;
struct escape_filter_ctx *efc;
struct escape_filter_ctx *efc = c->filter_ctx == NULL ?
NULL : (struct escape_filter_ctx *)c->filter_ctx;
if (c == NULL) {
escape_pendingp = &escape_pending1;
escape_char = escape_char1;
} else {
if (c->filter_ctx == NULL)
return 0;
efc = (struct escape_filter_ctx *)c->filter_ctx;
escape_pendingp = &efc->escape_pending;
escape_char = efc->escape_char;
}
if (c->filter_ctx == NULL)
return 0;
if (len <= 0)
return (0);
@ -1116,17 +967,17 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
/* Get one character at a time. */
ch = buf[i];
if (*escape_pendingp) {
if (efc->escape_pending) {
/* We have previously seen an escape character. */
/* Clear the flag now. */
*escape_pendingp = 0;
efc->escape_pending = 0;
/* Process the escaped character. */
switch (ch) {
case '.':
/* Terminate the connection. */
snprintf(string, sizeof string, "%c.\r\n",
escape_char);
efc->escape_char);
buffer_append(berr, string, strlen(string));
if (c && c->ctl_chan != -1) {
@ -1154,14 +1005,14 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
snprintf(string, sizeof string,
"%c%s escape not available to "
"multiplexed sessions\r\n",
escape_char, b);
efc->escape_char, b);
buffer_append(berr, string,
strlen(string));
continue;
}
/* Suspend the program. Inform the user */
snprintf(string, sizeof string,
"%c^Z [suspend ssh]\r\n", escape_char);
"%c^Z [suspend ssh]\r\n", efc->escape_char);
buffer_append(berr, string, strlen(string));
/* Restore terminal modes and suspend. */
@ -1171,26 +1022,20 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
continue;
case 'B':
if (compat20) {
snprintf(string, sizeof string,
"%cB\r\n", escape_char);
buffer_append(berr, string,
strlen(string));
channel_request_start(c->self,
"break", 0);
packet_put_int(1000);
packet_send();
}
snprintf(string, sizeof string,
"%cB\r\n", efc->escape_char);
buffer_append(berr, string, strlen(string));
channel_request_start(c->self, "break", 0);
packet_put_int(1000);
packet_send();
continue;
case 'R':
if (compat20) {
if (datafellows & SSH_BUG_NOREKEY)
logit("Server does not "
"support re-keying");
else
need_rekeying = 1;
}
if (datafellows & SSH_BUG_NOREKEY)
logit("Server does not "
"support re-keying");
else
need_rekeying = 1;
continue;
case 'V':
@ -1201,7 +1046,7 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
if (!log_is_on_stderr()) {
snprintf(string, sizeof string,
"%c%c [Logging to syslog]\r\n",
escape_char, ch);
efc->escape_char, ch);
buffer_append(berr, string,
strlen(string));
continue;
@ -1213,7 +1058,8 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
SYSLOG_LEVEL_DEBUG3)
log_change_level(++options.log_level);
snprintf(string, sizeof string,
"%c%c [LogLevel %s]\r\n", escape_char, ch,
"%c%c [LogLevel %s]\r\n",
efc->escape_char, ch,
log_level_name(options.log_level));
buffer_append(berr, string, strlen(string));
continue;
@ -1237,7 +1083,7 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
channel_stop_listening();
snprintf(string, sizeof string,
"%c& [backgrounded]\n", escape_char);
"%c& [backgrounded]\n", efc->escape_char);
buffer_append(berr, string, strlen(string));
/* Fork into background. */
@ -1251,38 +1097,19 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
exit(0);
}
/* The child continues serving connections. */
if (compat20) {
buffer_append(bin, "\004", 1);
/* fake EOF on stdin */
return -1;
} else if (!stdin_eof) {
/*
* Sending SSH_CMSG_EOF alone does not
* always appear to be enough. So we
* try to send an EOF character first.
*/
packet_start(SSH_CMSG_STDIN_DATA);
packet_put_string("\004", 1);
packet_send();
/* Close stdin. */
stdin_eof = 1;
if (buffer_len(bin) == 0) {
packet_start(SSH_CMSG_EOF);
packet_send();
}
}
continue;
buffer_append(bin, "\004", 1);
/* fake EOF on stdin */
return -1;
#endif /* !WINDOWS */
case '?':
print_escape_help(berr, escape_char, compat20,
print_escape_help(berr, efc->escape_char,
(c && c->ctl_chan != -1),
log_is_on_stderr());
continue;
case '#':
snprintf(string, sizeof string, "%c#\r\n",
escape_char);
efc->escape_char);
buffer_append(berr, string, strlen(string));
s = channel_open_message();
buffer_append(berr, s, strlen(s));
@ -1296,8 +1123,8 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
continue;
default:
if (ch != escape_char) {
buffer_put_char(bin, escape_char);
if (ch != efc->escape_char) {
buffer_put_char(bin, efc->escape_char);
bytes++;
}
/* Escaped characters fall through here */
@ -1308,12 +1135,12 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
* The previous character was not an escape char.
* Check if this is an escape.
*/
if (last_was_cr && ch == escape_char) {
if (last_was_cr && ch == efc->escape_char) {
/*
* It is. Set the flag and continue to
* next character.
*/
*escape_pendingp = 1;
efc->escape_pending = 1;
continue;
}
}
@ -1329,115 +1156,6 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
return bytes;
}
static void
client_process_input(fd_set *readset)
{
int len;
char buf[SSH_IOBUFSZ];
/* Read input from stdin. */
if (FD_ISSET(fileno(stdin), readset)) {
/* Read as much as possible. */
len = read(fileno(stdin), buf, sizeof(buf));
if (len < 0 &&
(errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK))
return; /* we'll try again later */
if (len <= 0) {
/*
* Received EOF or error. They are treated
* similarly, except that an error message is printed
* if it was an error condition.
*/
if (len < 0) {
snprintf(buf, sizeof buf, "read: %.100s\r\n",
strerror(errno));
buffer_append(&stderr_buffer, buf, strlen(buf));
}
/* Mark that we have seen EOF. */
stdin_eof = 1;
/*
* Send an EOF message to the server unless there is
* data in the buffer. If there is data in the
* buffer, no message will be sent now. Code
* elsewhere will send the EOF when the buffer
* becomes empty if stdin_eof is set.
*/
if (buffer_len(&stdin_buffer) == 0) {
packet_start(SSH_CMSG_EOF);
packet_send();
}
} else if (escape_char1 == SSH_ESCAPECHAR_NONE) {
/*
* Normal successful read, and no escape character.
* Just append the data to buffer.
*/
buffer_append(&stdin_buffer, buf, len);
} else {
/*
* Normal, successful read. But we have an escape
* character and have to process the characters one
* by one.
*/
if (process_escapes(NULL, &stdin_buffer,
&stdout_buffer, &stderr_buffer, buf, len) == -1)
return;
}
}
}
static void
client_process_output(fd_set *writeset)
{
int len;
char buf[100];
/* Write buffered output to stdout. */
if (FD_ISSET(fileno(stdout), writeset)) {
/* Write as much data as possible. */
len = write(fileno(stdout), buffer_ptr(&stdout_buffer),
buffer_len(&stdout_buffer));
if (len <= 0) {
if (errno == EINTR || errno == EAGAIN ||
errno == EWOULDBLOCK)
len = 0;
else {
/*
* An error or EOF was encountered. Put an
* error message to stderr buffer.
*/
snprintf(buf, sizeof buf,
"write stdout: %.50s\r\n", strerror(errno));
buffer_append(&stderr_buffer, buf, strlen(buf));
quit_pending = 1;
return;
}
}
/* Consume printed data from the buffer. */
buffer_consume(&stdout_buffer, len);
}
/* Write buffered output to stderr. */
if (FD_ISSET(fileno(stderr), writeset)) {
/* Write as much data as possible. */
len = write(fileno(stderr), buffer_ptr(&stderr_buffer),
buffer_len(&stderr_buffer));
if (len <= 0) {
if (errno == EINTR || errno == EAGAIN ||
errno == EWOULDBLOCK)
len = 0;
else {
/*
* EOF or error, but can't even print
* error message.
*/
quit_pending = 1;
return;
}
}
/* Consume printed characters from the buffer. */
buffer_consume(&stderr_buffer, len);
}
}
/*
* Get packets from the connection input buffer, and process them as long as
* there are packets available.
@ -1548,33 +1266,15 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
start_time = get_current_time();
/* Initialize variables. */
escape_pending1 = 0;
last_was_cr = 1;
exit_status = -1;
stdin_eof = 0;
buffer_high = 64 * 1024;
connection_in = packet_get_connection_in();
connection_out = packet_get_connection_out();
max_fd = MAXIMUM(connection_in, connection_out);
if (!compat20) {
/* enable nonblocking unless tty */
if (!isatty(fileno(stdin)))
set_nonblock(fileno(stdin));
if (!isatty(fileno(stdout)))
set_nonblock(fileno(stdout));
if (!isatty(fileno(stderr)))
set_nonblock(fileno(stderr));
max_fd = MAXIMUM(max_fd, fileno(stdin));
max_fd = MAXIMUM(max_fd, fileno(stdout));
max_fd = MAXIMUM(max_fd, fileno(stderr));
}
quit_pending = 0;
escape_char1 = escape_char_arg;
/* Initialize buffers. */
buffer_init(&stdin_buffer);
buffer_init(&stdout_buffer);
buffer_init(&stderr_buffer);
client_init_dispatch();
@ -1596,22 +1296,17 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
if (have_pty)
enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
if (compat20) {
session_ident = ssh2_chan_id;
if (session_ident != -1) {
if (escape_char_arg != SSH_ESCAPECHAR_NONE) {
channel_register_filter(session_ident,
client_simple_escape_filter, NULL,
client_filter_cleanup,
client_new_escape_filter_ctx(
escape_char_arg));
}
channel_register_cleanup(session_ident,
client_channel_closed, 0);
session_ident = ssh2_chan_id;
if (session_ident != -1) {
if (escape_char_arg != SSH_ESCAPECHAR_NONE) {
channel_register_filter(session_ident,
client_simple_escape_filter, NULL,
client_filter_cleanup,
client_new_escape_filter_ctx(
escape_char_arg));
}
} else {
/* Check if we should immediately send eof on stdin. */
client_check_initial_eof_on_stdin();
channel_register_cleanup(session_ident,
client_channel_closed, 0);
}
/* Main loop of the client for the interactive session mode. */
@ -1620,7 +1315,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
/* Process buffered packets sent by the server. */
client_process_buffered_input_packets();
if (compat20 && session_closed && !channel_still_open())
if (session_closed && !channel_still_open())
break;
if (ssh_packet_is_rekeying(active_state)) {
@ -1633,13 +1328,6 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
ssh_err(r));
need_rekeying = 0;
} else {
/*
* Make packets of buffered stdin data, and buffer
* them for sending to the server.
*/
if (!compat20)
client_make_packets_from_stdin_data();
/*
* Make packets from buffered channel data, and
* enqueue them for sending to the server.
@ -1677,16 +1365,6 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
if (quit_pending)
break;
if (!compat20) {
/* Buffer data from stdin */
client_process_input(readset);
/*
* Process output to stdout and stderr. Output to
* the connection is processed elsewhere (above).
*/
client_process_output(writeset);
}
/*
* Send as much buffered packet data as possible to the
* sender.
@ -1714,14 +1392,12 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
/* Stop watching for window change. */
signal(SIGWINCH, SIG_DFL);
if (compat20) {
packet_start(SSH2_MSG_DISCONNECT);
packet_put_int(SSH2_DISCONNECT_BY_APPLICATION);
packet_put_cstring("disconnected by user");
packet_put_cstring(""); /* language tag */
packet_send();
packet_write_wait();
}
packet_start(SSH2_MSG_DISCONNECT);
packet_put_int(SSH2_DISCONNECT_BY_APPLICATION);
packet_put_cstring("disconnected by user");
packet_put_cstring(""); /* language tag */
packet_send();
packet_write_wait();
channel_free_all();
@ -1759,16 +1435,6 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
buffer_append(&stderr_buffer, buf, strlen(buf));
}
/* Output any buffered data for stdout. */
if (buffer_len(&stdout_buffer) > 0) {
len = atomicio(vwrite, fileno(stdout),
buffer_ptr(&stdout_buffer), buffer_len(&stdout_buffer));
if (len < 0 || (u_int)len != buffer_len(&stdout_buffer))
error("Write failed flushing stdout buffer.");
else
buffer_consume(&stdout_buffer, len);
}
/* Output any buffered data for stderr. */
if (buffer_len(&stderr_buffer) > 0) {
len = atomicio(vwrite, fileno(stderr),
@ -1781,8 +1447,6 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
/* Clear and free any buffers. */
explicit_bzero(buf, sizeof(buf));
buffer_free(&stdin_buffer);
buffer_free(&stdout_buffer);
buffer_free(&stderr_buffer);
/* Report bytes transferred, and transfer rates. */
@ -1800,92 +1464,6 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
/*********/
static int
client_input_stdout_data(int type, u_int32_t seq, void *ctxt)
{
u_int data_len;
char *data = packet_get_string(&data_len);
packet_check_eom();
buffer_append(&stdout_buffer, data, data_len);
explicit_bzero(data, data_len);
free(data);
return 0;
}
static int
client_input_stderr_data(int type, u_int32_t seq, void *ctxt)
{
u_int data_len;
char *data = packet_get_string(&data_len);
packet_check_eom();
buffer_append(&stderr_buffer, data, data_len);
explicit_bzero(data, data_len);
free(data);
return 0;
}
static int
client_input_exit_status(int type, u_int32_t seq, void *ctxt)
{
exit_status = packet_get_int();
packet_check_eom();
/* Acknowledge the exit. */
packet_start(SSH_CMSG_EXIT_CONFIRMATION);
packet_send();
/*
* Must wait for packet to be sent since we are
* exiting the loop.
*/
packet_write_wait();
/* Flag that we want to exit. */
quit_pending = 1;
return 0;
}
static int
client_input_agent_open(int type, u_int32_t seq, void *ctxt)
{
Channel *c = NULL;
int r, remote_id, sock;
/* Read the remote channel number from the message. */
remote_id = packet_get_int();
packet_check_eom();
/*
* Get a connection to the local authentication agent (this may again
* get forwarded).
*/
if ((r = ssh_get_authentication_socket(&sock)) != 0 &&
r != SSH_ERR_AGENT_NOT_PRESENT)
debug("%s: ssh_get_authentication_socket: %s",
__func__, ssh_err(r));
/*
* If we could not connect the agent, send an error message back to
* the server. This should never happen unless the agent dies,
* because authentication forwarding is only enabled if we have an
* agent.
*/
if (sock >= 0) {
c = channel_new("", SSH_CHANNEL_OPEN, sock, sock,
-1, 0, 0, 0, "authentication agent connection", 1);
c->remote_id = remote_id;
c->force_drain = 1;
}
if (c == NULL) {
packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
packet_put_int(remote_id);
} else {
/* Send a confirmation to the remote host. */
debug("Forwarding authentication connection.");
packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
packet_put_int(remote_id);
packet_put_int(c->self);
}
packet_send();
return 0;
}
static Channel *
client_request_forwarded_tcpip(const char *request_type, int rchan,
u_int rwindow, u_int rmaxpack)
@ -2036,11 +1614,6 @@ client_request_tun_fwd(int tun_mode, int local_tun, int remote_tun)
if (tun_mode == SSH_TUNMODE_NO)
return 0;
if (!compat20) {
error("Tunnel forwarding is not supported for protocol 1");
return -1;
}
debug("Requesting tun unit %d in mode %d", local_tun, tun_mode);
/* Open local tunnel device */
@ -2191,9 +1764,7 @@ struct hostkeys_update_ctx {
*/
struct sshkey **keys;
int *keys_seen;
size_t nkeys;
size_t nnew;
size_t nkeys, nnew;
/*
* Keys that are in known_hosts, but were not present in the update
@ -2230,8 +1801,7 @@ hostkeys_find(struct hostkey_foreach_line *l, void *_ctx)
size_t i;
struct sshkey **tmp;
if (l->status != HKF_STATUS_MATCHED || l->key == NULL ||
l->key->type == KEY_RSA1)
if (l->status != HKF_STATUS_MATCHED || l->key == NULL)
return 0;
/* Mark off keys we've already seen for this host */
@ -2691,7 +2261,7 @@ client_session2_setup(int id, int want_tty, int want_subsystem,
}
static void
client_init_dispatch_20(void)
client_init_dispatch(void)
{
dispatch_init(&dispatch_protocol_error);
@ -2716,45 +2286,6 @@ client_init_dispatch_20(void)
dispatch_set(SSH2_MSG_REQUEST_SUCCESS, &client_global_request_reply);
}
static void
client_init_dispatch_13(void)
{
dispatch_init(NULL);
dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_close);
dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, &channel_input_close_confirmation);
dispatch_set(SSH_MSG_CHANNEL_DATA, &channel_input_data);
dispatch_set(SSH_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation);
dispatch_set(SSH_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure);
dispatch_set(SSH_MSG_PORT_OPEN, &channel_input_port_open);
dispatch_set(SSH_SMSG_EXITSTATUS, &client_input_exit_status);
dispatch_set(SSH_SMSG_STDERR_DATA, &client_input_stderr_data);
dispatch_set(SSH_SMSG_STDOUT_DATA, &client_input_stdout_data);
dispatch_set(SSH_SMSG_AGENT_OPEN, options.forward_agent ?
&client_input_agent_open : &deny_input_open);
dispatch_set(SSH_SMSG_X11_OPEN, options.forward_x11 ?
&x11_input_open : &deny_input_open);
}
static void
client_init_dispatch_15(void)
{
client_init_dispatch_13();
dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_ieof);
dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, & channel_input_oclose);
}
static void
client_init_dispatch(void)
{
if (compat20)
client_init_dispatch_20();
else if (compat13)
client_init_dispatch_13();
else
client_init_dispatch_15();
}
void
client_stop_mux(void)
{

View File

@ -1,4 +1,4 @@
/* $OpenBSD: compat.c,v 1.100 2017/02/03 23:01:19 djm Exp $ */
/* $OpenBSD: compat.c,v 1.103 2017/04/30 23:13:25 djm Exp $ */
/*
* Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved.
*
@ -39,24 +39,8 @@
#include "match.h"
#include "kex.h"
int compat13 = 0;
int compat20 = 0;
int datafellows = 0;
void
enable_compat20(void)
{
if (compat20)
return;
debug("Enabling compatibility mode for protocol 2.0");
compat20 = 1;
}
void
enable_compat13(void)
{
debug("Enabling compatibility mode for protocol 1.3");
compat13 = 1;
}
/* datafellows bug compatibility */
u_int
compat_datafellows(const char *version)
@ -232,13 +216,6 @@ proto_spec(const char *spec)
return ret;
for ((p = strsep(&q, SEP)); p && *p != '\0'; (p = strsep(&q, SEP))) {
switch (atoi(p)) {
case 1:
#ifdef WITH_SSH1
if (ret == SSH_PROTO_UNKNOWN)
ret |= SSH_PROTO_1_PREFERRED;
ret |= SSH_PROTO_1;
#endif
break;
case 2:
ret |= SSH_PROTO_2;
break;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: compat.h,v 1.48 2015/05/26 23:23:40 dtucker Exp $ */
/* $OpenBSD: compat.h,v 1.49 2017/04/30 23:13:25 djm Exp $ */
/*
* Copyright (c) 1999, 2000, 2001 Markus Friedl. All rights reserved.
@ -63,15 +63,11 @@
#define SSH_BUG_HOSTKEYS 0x20000000
#define SSH_BUG_DHGEX_LARGE 0x40000000
void enable_compat13(void);
void enable_compat20(void);
u_int compat_datafellows(const char *);
int proto_spec(const char *);
char *compat_cipher_proposal(char *);
char *compat_pkalg_proposal(char *);
char *compat_kex_proposal(char *);
extern int compat13;
extern int compat20;
extern int datafellows;
#endif

View File

@ -109,13 +109,10 @@ AC_CHECK_DECL([PR_SET_NO_NEW_PRIVS], [have_linux_no_new_privs=1], , [
])
openssl=yes
ssh1=no
COMMENT_OUT_RSA1="#no ssh1#"
AC_ARG_WITH([openssl],
[ --without-openssl Disable use of OpenSSL; use only limited internal crypto **EXPERIMENTAL** ],
[ if test "x$withval" = "xno" ; then
openssl=no
ssh1=no
fi
]
)
@ -127,31 +124,6 @@ else
AC_MSG_RESULT([no])
fi
AC_ARG_WITH([ssh1],
[ --with-ssh1 Enable support for SSH protocol 1],
[
if test "x$withval" = "xyes" ; then
if test "x$openssl" = "xno" ; then
AC_MSG_ERROR([Cannot enable SSH protocol 1 with OpenSSL disabled])
fi
ssh1=yes
COMMENT_OUT_RSA1=""
elif test "x$withval" = "xno" ; then
ssh1=no
else
AC_MSG_ERROR([unknown --with-ssh1 argument])
fi
]
)
AC_MSG_CHECKING([whether SSH protocol 1 support is enabled])
if test "x$ssh1" = "xyes" ; then
AC_MSG_RESULT([yes])
AC_DEFINE_UNQUOTED([WITH_SSH1], [1], [include SSH protocol version 1 support])
AC_SUBST([COMMENT_OUT_RSA1])
else
AC_MSG_RESULT([no])
fi
use_stack_protector=1
use_toolchain_hardening=1
AC_ARG_WITH([stackprotect],

View File

@ -0,0 +1,52 @@
param ([switch]$Quiet)
Import-Module $PSScriptRoot\OpenSSHUtils.psm1 -Force -DisableNameChecking
#check sshd config file
$sshdConfigPath = join-path $PSScriptRoot "sshd_config"
if(Test-Path $sshdConfigPath -PathType Leaf)
{
Fix-HostSSHDConfigPermissions -FilePath $sshdConfigPath @psBoundParameters
}
else
{
Write-host "$FilePath does not exist" -ForegroundColor Yellow
}
#check host keys
<#$result = 'n'
if (-not $Quiet) {
Do
{
$input = Read-Host -Prompt "Did you register host private keys with ssh-agent? [Yes] Y; [No] N"
} until ($input -match "^(y(es)?|N(o)?)$")
$result = $Matches[0]
}
if($result.ToLower().Startswith('n'))
{
$warning = @"
To keep the host private keys secure, it is recommended to register them with ssh-agent following
steps in link https://github.com/PowerShell/Win32-OpenSSH/wiki/Install-Win32-OpenSSH.
If you choose not to register the keys with ssh-agent, please grant sshd read access to the private host keys after run this script.
"@
Write-Warning $warning
Write-Host " "
}#>
Get-ChildItem $PSScriptRoot\ssh_host_*_key -ErrorAction Ignore | % {
Fix-HostKeyPermissions -FilePath $_.FullName @psBoundParameters
}
#check authorized_keys
Get-ChildItem "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList" -ErrorAction Ignore | % {
$userProfilePath = Get-ItemPropertyValue $_.pspath -Name ProfileImagePath -ErrorAction Ignore
$filePath = Join-Path $userProfilePath .ssh\authorized_keys
if(Test-Path $filePath -PathType Leaf)
{
Fix-AuthorizedKeyPermissions -FilePath $filePath @psBoundParameters
}
}
Write-Host " Done."
Write-Host " "

View File

@ -0,0 +1,14 @@
param ([switch]$Quiet)
Import-Module $PSScriptRoot\OpenSSHUtils.psm1 -Force -DisableNameChecking
if(Test-Path ~\.ssh\config -PathType Leaf)
{
Fix-UserSSHConfigPermissions -FilePath ~\.ssh\config @psBoundParameters
}
Get-ChildItem ~\.ssh\* -Include "id_rsa","id_dsa" -ErrorAction Ignore | % {
Fix-UserKeyPermissions -FilePath $_.FullName @psBoundParameters
}
Write-Host " Done."
Write-Host " "

View File

@ -300,8 +300,8 @@ function Package-OpenSSH
}
$buildDir = Join-Path $repositoryRoot ("bin\" + $folderName + "\" + $Configuration)
$payload = "sshd.exe", "ssh.exe", "ssh-agent.exe", "ssh-add.exe", "sftp.exe"
$payload += "sftp-server.exe", "scp.exe", "ssh-shellhost.exe", "ssh-keygen.exe"
$payload += "sshd_config", "install-sshd.ps1", "uninstall-sshd.ps1"
$payload += "sftp-server.exe", "scp.exe", "ssh-shellhost.exe", "ssh-keygen.exe", "ssh-keyscan.exe"
$payload += "sshd_config", "install-sshd.ps1", "uninstall-sshd.ps1", "FixHostFilePermissions.ps1", "FixUserFilePermissions.ps1", "OpenSSHUtils.psm1"
$packageName = "OpenSSH-Win64"
if ($NativeHostArch -eq 'x86') {
@ -339,7 +339,7 @@ function Package-OpenSSH
if ($DestinationPath -ne "") {
if (Test-Path $DestinationPath) {
Remove-Item $DestinationPath\* -Force -Recurse
Remove-Item $DestinationPath\* -Force -Recurse -ErrorAction SilentlyContinue
}
else {
New-Item -ItemType Directory $DestinationPath -Force | Out-Null
@ -503,7 +503,7 @@ function Install-OpenSSH
& "$OpenSSHDir\ssh-keygen.exe" -A
$keyFiles = Get-ChildItem "$OpenSSHDir\ssh_host_*_key*" | % {
Add-PermissionToFileACL -FilePath $_.FullName -User "NT Service\sshd" -Perm "Read"
Adjust-HostKeyFileACL -FilePath $_.FullName
}
@ -542,18 +542,22 @@ function UnInstall-OpenSSH
[string]$OpenSSHDir = "$env:SystemDrive\OpenSSH"
)
if (-not (Test-Path $OpenSSHDir))
{
return
}
Push-Location $OpenSSHDir
if((Get-Service ssh-agent -ErrorAction Ignore) -ne $null) {
Stop-Service ssh-agent -Force
}
&( "$OpenSSHDir\uninstall-sshd.ps1")
&( "$OpenSSHDir\uninstall-sshlsa.ps1")
$machinePath = [Environment]::GetEnvironmentVariable('Path', 'MACHINE')
$newMachineEnvironmentPath = $machinePath
if ($machinePath.ToLower().Contains($OpenSSHDir.ToLower()))
{
$newMachineEnvironmentPath.Replace("$OpenSSHDir;", '')
$newMachineEnvironmentPath = $newMachineEnvironmentPath.Replace("$OpenSSHDir;", '')
$env:Path = $env:Path.Replace("$OpenSSHDir;", '')
}

View File

@ -30,48 +30,141 @@ function Get-RepositoryRoot
<#
.Synopsis
Sets the Secure File ACL.
1. Removed all user acl except Administrators group, system, and current user
2. whether or not take the owner
Set owner of the file to by LOCALSYSTEM account
Set private host key be fully controlled by LOCALSYSTEM and Administrators
Set public host key be fully controlled by LOCALSYSTEM and Administrators, read access by everyone
.Outputs
N/A
.Inputs
FilePath - The path to the file
takeowner - if want to take the ownership
#>
function Cleanup-SecureFileACL
function Adjust-HostKeyFileACL
{
[CmdletBinding()]
param([string]$FilePath, [System.Security.Principal.NTAccount] $Owner)
param (
[parameter(Mandatory=$true)]
[string]$FilePath
)
$myACL = Get-ACL $filePath
$myACL.SetAccessRuleProtection($True, $True)
Set-Acl -Path $filePath -AclObject $myACL
$myACL = Get-ACL $FilePath
$myACL.SetAccessRuleProtection($True, $FALSE)
Set-Acl -Path $FilePath -AclObject $myACL
$systemAccount = New-Object System.Security.Principal.NTAccount("NT AUTHORITY", "SYSTEM")
$adminAccount = New-Object System.Security.Principal.NTAccount("BUILTIN","Administrators")
$everyoneAccount = New-Object System.Security.Principal.NTAccount("EveryOne")
$myACL = Get-ACL $FilePath
$myACL.SetOwner($systemAccount)
$myACL = Get-ACL $filePath
if($owner -ne $null)
{
$myACL.SetOwner($owner)
}
if($myACL.Access)
{
$myACL.Access | % {
if (($_ -ne $null) -and ($_.IdentityReference.Value -ine "BUILTIN\Administrators") -and
($_.IdentityReference.Value -ine "NT AUTHORITY\SYSTEM") -and
($_.IdentityReference.Value -ine "$(whoami)"))
if(-not ($myACL.RemoveAccessRule($_)))
{
if(-not ($myACL.RemoveAccessRule($_)))
{
throw "failed to remove access of $($_.IdentityReference.Value) rule in setup "
}
throw "failed to remove access of $($_.IdentityReference.Value) rule in setup "
}
}
}
$adminACE = New-Object System.Security.AccessControl.FileSystemAccessRule `
($adminAccount, "FullControl", "None", "None", "Allow")
$myACL.AddAccessRule($adminACE)
$systemACE = New-Object System.Security.AccessControl.FileSystemAccessRule `
($systemAccount, "FullControl", "None", "None", "Allow")
$myACL.AddAccessRule($systemACE)
if($FilePath.EndsWith(".pub"))
{
$everyoneAce = New-Object System.Security.AccessControl.FileSystemAccessRule `
("Everyone", "Read", "None", "None", "Allow")
$myACL.AddAccessRule($everyoneAce)
}
Set-Acl -Path $FilePath -AclObject $myACL
}
<#
.Synopsis
Set owner of the user key file
Set ACL to have private user key be fully controlled by LOCALSYSTEM and Administrators, Read, write access by owner
Set public user key be fully controlled by LOCALSYSTEM and Administrators, Read, write access by owner, read access by everyone
.Outputs
N/A
.Inputs
FilePath - The path to the file
Owner - owner of the file
OwnerPerms - the permissions grant to the owner
#>
function Adjust-UserKeyFileACL
{
param (
[parameter(Mandatory=$true)]
[string]$FilePath,
[System.Security.Principal.NTAccount] $Owner = $null,
[System.Security.AccessControl.FileSystemRights[]] $OwnerPerms = $null
)
$myACL = Get-ACL $FilePath
$myACL.SetAccessRuleProtection($True, $FALSE)
Set-Acl -Path $FilePath -AclObject $myACL
$systemAccount = New-Object System.Security.Principal.NTAccount("NT AUTHORITY", "SYSTEM")
$adminAccount = New-Object System.Security.Principal.NTAccount("BUILTIN","Administrators")
$everyoneAccount = New-Object System.Security.Principal.NTAccount("EveryOne")
$myACL = Get-ACL $FilePath
$actualOwner = $null
if($Owner -eq $null)
{
$actualOwner = New-Object System.Security.Principal.NTAccount($($env:USERDOMAIN), $($env:USERNAME))
}
else
{
$actualOwner = $Owner
}
$myACL.SetOwner($actualOwner)
if($myACL.Access)
{
$myACL.Access | % {
if(-not ($myACL.RemoveAccessRule($_)))
{
throw "failed to remove access of $($_.IdentityReference.Value) rule in setup "
}
}
}
$adminACE = New-Object System.Security.AccessControl.FileSystemAccessRule `
($adminAccount, "FullControl", "None", "None", "Allow")
$myACL.AddAccessRule($adminACE)
$systemACE = New-Object System.Security.AccessControl.FileSystemAccessRule `
($systemAccount, "FullControl", "None", "None", "Allow")
$myACL.AddAccessRule($systemACE)
if($OwnerPerms)
{
$OwnerPerms | % {
$ownerACE = New-Object System.Security.AccessControl.FileSystemAccessRule `
($actualOwner, $_, "None", "None", "Allow")
$myACL.AddAccessRule($ownerACE)
}
}
Set-Acl -Path $filePath -AclObject $myACL
if($FilePath.EndsWith(".pub"))
{
$everyoneAce = New-Object System.Security.AccessControl.FileSystemAccessRule `
("Everyone", "Read", "None", "None", "Allow")
$myACL.AddAccessRule($everyoneAce)
}
Set-Acl -Path $FilePath -AclObject $myACL
}
<#
@ -88,20 +181,27 @@ function Cleanup-SecureFileACL
#>
function Add-PermissionToFileACL
{
[CmdletBinding()]
param(
param (
[parameter(Mandatory=$true)]
[string]$FilePath,
[parameter(Mandatory=$true)]
[System.Security.Principal.NTAccount] $User,
[System.Security.AccessControl.FileSystemRights]$Perm
[parameter(Mandatory=$true)]
[System.Security.AccessControl.FileSystemRights[]]$Perms
)
$myACL = Get-ACL $filePath
$myACL = Get-ACL $FilePath
$objACE = New-Object System.Security.AccessControl.FileSystemAccessRule `
($User, $perm, "None", "None", "Allow")
$myACL.AddAccessRule($objACE)
if($Perms)
{
$Perms | % {
$userACE = New-Object System.Security.AccessControl.FileSystemAccessRule `
($User, $_, "None", "None", "Allow")
$myACL.AddAccessRule($userACE)
}
}
Set-Acl -Path $filePath -AclObject $myACL
Set-Acl -Path $FilePath -AclObject $myACL
}
Export-ModuleMember -Function Get-RepositoryRoot, Add-PermissionToFileACL, Cleanup-SecureFileACL
Export-ModuleMember -Function Get-RepositoryRoot, Add-PermissionToFileACL, Adjust-HostKeyFileACL, Adjust-UserKeyFileACL

View File

@ -1,5 +1,5 @@
$ErrorActionPreference = 'Stop'
Import-Module $PSScriptRoot\OpenSSHCommonUtils.psm1 -DisableNameChecking
Import-Module $PSScriptRoot\OpenSSHCommonUtils.psm1 -DisableNameChecking -Force
[System.IO.DirectoryInfo] $repositoryRoot = Get-RepositoryRoot
# test environment parameters initialized with defaults
@ -158,18 +158,24 @@ WARNING: Following changes will be made to OpenSSH configuration
# copy new sshd_config
Copy-Item (Join-Path $Script:E2ETestDirectory sshd_config) (Join-Path $script:OpenSSHBinPath sshd_config) -Force
#workaround for the cariggage new line added by git before copy them
Get-ChildItem "$($Script:E2ETestDirectory)\sshtest_*key*" | % {
#copy sshtest keys
Copy-Item "$($Script:E2ETestDirectory)\sshtest*hostkey*" $script:OpenSSHBinPath -Force
Get-ChildItem "$($script:OpenSSHBinPath)\sshtest*hostkey*"| % {
#workaround for the cariggage new line added by git before copy them
(Get-Content $_.FullName -Raw).Replace("`r`n","`n") | Set-Content $_.FullName -Force
Adjust-HostKeyFileACL -FilePath $_.FullName
if (-not ($_.Name.EndsWith(".pub"))) {
Add-PermissionToFileACL -FilePath $_.FullName -User "NT Service\sshd" -Perm "Read"
}
}
#copy sshtest keys
Copy-Item "$($Script:E2ETestDirectory)\sshtest*hostkey*" $script:OpenSSHBinPath -Force
$owner = New-Object System.Security.Principal.NTAccount($env:USERDOMAIN, $env:USERNAME)
Get-ChildItem "$($script:OpenSSHBinPath)\sshtest*hostkey*" -Exclude *.pub | % {
Cleanup-SecureFileACL -FilePath $_.FullName -Owner $owner
Add-PermissionToFileACL -FilePath $_.FullName -User "NT Service\sshd" -Perm "Read"
}
#register host keys with agent
<#Get-ChildItem "$($script:OpenSSHBinPath)\sshtest*hostkey*"| % {
if (-not ($_.Name.EndsWith(".pub"))) {
& "$env:ProgramData\chocolatey\lib\sysinternals\tools\psexec" -accepteula -nobanner -i -s -w $($script:OpenSSHBinPath) cmd.exe /c "ssh-add $_"
Add-PermissionToFileACL -FilePath $_.FullName -User "NT Service\sshd" -Perm "Read"
}
}#>
Restart-Service sshd -Force
#Backup existing known_hosts and replace with test version
@ -190,6 +196,7 @@ WARNING: Following changes will be made to OpenSSH configuration
Copy-Item $sshConfigFilePath (Join-Path $dotSshDirectoryPath config.ori) -Force
}
Copy-Item (Join-Path $Script:E2ETestDirectory ssh_config) $sshConfigFilePath -Force
Adjust-UserKeyFileACL -FilePath $sshConfigFilePath -OwnerPerms "Read,Write"
# create test accounts
#TODO - this is Windows specific. Need to be in PAL
@ -216,9 +223,12 @@ WARNING: Following changes will be made to OpenSSH configuration
$authorizedKeyPath = Join-Path $ssouserProfile .ssh\authorized_keys
$testPubKeyPath = Join-Path $Script:E2ETestDirectory sshtest_userssokey_ed25519.pub
Copy-Item $testPubKeyPath $authorizedKeyPath -Force -ErrorAction SilentlyContinue
$owner = New-Object System.Security.Principal.NTAccount($SSOUser)
Adjust-UserKeyFileACL -FilePath $authorizedKeyPath -Owner $owner -OwnerPerms "Read","Write"
Add-PermissionToFileACL -FilePath $authorizedKeyPath -User "NT Service\sshd" -Perm "Read"
$testPriKeypath = Join-Path $Script:E2ETestDirectory sshtest_userssokey_ed25519
Cleanup-SecureFileACL -FilePath $testPriKeypath -owner $owner
(Get-Content $testPriKeypath -Raw).Replace("`r`n","`n") | Set-Content $testPriKeypath -Force
Adjust-UserKeyFileACL -FilePath $testPriKeypath -OwnerPerms "Read, Write"
cmd /c "ssh-add $testPriKeypath 2>&1 >> $Script:TestSetupLogFile"
Backup-OpenSSHTestInfo
}
@ -306,6 +316,13 @@ function Cleanup-OpenSSHTestEnvironment
Throw "Cannot find OpenSSH binaries under $script:OpenSSHBinPath. "
}
#unregister test host keys from agent
Get-ChildItem "$($script:OpenSSHBinPath)\sshtest*hostkey*.pub"| % {
$cmd = "cmd /c `"$env:ProgramData\chocolatey\lib\sysinternals\tools\psexec -accepteula -nobanner -s -w $($script:OpenSSHBinPath) ssh-add -d $_ 2> tmp.txt`""
iex $cmd
}
#Restore sshd_config
$backupConfigPath = Join-Path $Script:OpenSSHBinPath sshd_config.ori
if (Test-Path $backupConfigPath -PathType Leaf) {

View File

@ -0,0 +1,474 @@
$systemAccount = New-Object System.Security.Principal.NTAccount("NT AUTHORITY", "SYSTEM")
$adminsAccount = New-Object System.Security.Principal.NTAccount("BUILTIN","Administrators")
$currentUser = New-Object System.Security.Principal.NTAccount($($env:USERDOMAIN), $($env:USERNAME))
$everyone = New-Object System.Security.Principal.NTAccount("EveryOne")
$sshdAccount = New-Object System.Security.Principal.NTAccount("NT SERVICE","sshd")
<#
.Synopsis
Fix-HostSSHDConfigPermissions
fix the file owner and permissions of sshd_config
#>
function Fix-HostSSHDConfigPermissions
{
param (
[parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]$FilePath,
[switch] $Quiet)
Fix-FilePermissions -Owners $systemAccount,$adminsAccount -ReadAccessNeeded $sshdAccount @psBoundParameters
}
<#
.Synopsis
Fix-HostKeyPermissions
fix the file owner and permissions of host private and public key
-FilePath: The path of the private host key
#>
function Fix-HostKeyPermissions
{
param (
[parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]$FilePath,
[switch] $Quiet)
$parameters = $PSBoundParameters
if($parameters["FilePath"].EndsWith(".pub"))
{
$parameters["FilePath"] = $parameters["FilePath"].Replace(".pub", "")
}
Fix-FilePermissions -Owners $systemAccount,$adminsAccount -ReadAccessNeeded $sshdAccount @psBoundParameters
$parameters["FilePath"] += ".pub"
Fix-FilePermissions -Owners $systemAccount,$adminsAccount -ReadAccessOK $everyone -ReadAccessNeeded $sshdAccount @parameters
}
<#
.Synopsis
Fix-AuthorizedKeyPermissions
fix the file owner and permissions of authorized_keys
#>
function Fix-AuthorizedKeyPermissions
{
param (
[parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]$FilePath,
[switch] $Quiet)
if(-not (Test-Path $FilePath -PathType Leaf))
{
Write-host "$FilePath not found" -ForegroundColor Yellow
return
}
$fullPath = (Resolve-Path $FilePath).Path
$profileListPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList"
$profileItem = Get-ChildItem $profileListPath -ErrorAction Ignore | ? {
$fullPath.ToLower().Contains((Get-ItemPropertyValue $_.PSPath -Name ProfileImagePath -ErrorAction Ignore).Tolower())
}
if($profileItem)
{
$userSid = $profileItem.PSChildName
$account = Get-UserAccount -UserSid $userSid
Fix-FilePermissions -Owners $account,$adminsAccount,$systemAccount -AnyAccessOK $account -ReadAccessNeeded $sshdAccount @psBoundParameters
}
else
{
Write-host "$fullPath is not in the profile folder of any user. Skip checking..." -ForegroundColor Yellow
}
}
<#
.Synopsis
Fix-UserKeyPermissions
fix the file owner and permissions of user config
-FilePath: The path of the private user key
#>
function Fix-UserKeyPermissions
{
param (
[parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]$FilePath,
[switch] $Quiet)
$parameters = $PSBoundParameters
if($parameters["FilePath"].EndsWith(".pub"))
{
$parameters["FilePath"] = $parameters["FilePath"].Replace(".pub", "")
}
Fix-FilePermissions -Owners $currentUser, $adminsAccount,$systemAccount -AnyAccessOK $currentUser @psBoundParameters
$parameters["FilePath"] += ".pub"
Fix-FilePermissions -Owners $currentUser, $adminsAccount,$systemAccount -AnyAccessOK $currentUser -ReadAccessOK $everyone @parameters
}
<#
.Synopsis
Fix-UserSSHConfigPermissions
fix the file owner and permissions of user config
#>
function Fix-UserSSHConfigPermissions
{
param (
[parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]$FilePath,
[switch] $Quiet)
Fix-FilePermissions -Owners $currentUser,$adminsAccount,$systemAccount -AnyAccessOK $currentUser @psBoundParameters
}
<#
.Synopsis
Fix-FilePermissionInternal
Only validate owner and ACEs of the file
#>
function Fix-FilePermissions
{
param (
[parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]$FilePath,
[ValidateNotNull()]
[System.Security.Principal.NTAccount[]] $Owners = $currentUser,
[System.Security.Principal.NTAccount[]] $AnyAccessOK,
[System.Security.Principal.NTAccount[]] $ReadAccessOK,
[System.Security.Principal.NTAccount[]] $ReadAccessNeeded,
[switch] $Quiet
)
if(-not (Test-Path $FilePath -PathType Leaf))
{
Write-host "$FilePath not found" -ForegroundColor Yellow
return
}
Write-host " [*] $FilePath"
$return = Fix-FilePermissionInternal @PSBoundParameters
if($return -contains $true)
{
#Write-host "Re-check the health of file $FilePath"
Fix-FilePermissionInternal @PSBoundParameters
}
}
<#
.Synopsis
Fix-FilePermissionInternal
#>
function Fix-FilePermissionInternal {
param (
[parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]$FilePath,
[ValidateNotNull()]
[System.Security.Principal.NTAccount[]] $Owners = $currentUser,
[System.Security.Principal.NTAccount[]] $AnyAccessOK,
[System.Security.Principal.NTAccount[]] $ReadAccessOK,
[System.Security.Principal.NTAccount[]] $ReadAccessNeeded,
[switch] $Quiet
)
$acl = Get-Acl $FilePath
$needChange = $false
$health = $true
if ($Quiet)
{
$result = 'Y'
}
if(-not $Owners.Contains([System.Security.Principal.NTAccount]$($acl.Owner)))
{
if (-not $Quiet) {
$warning = "Current owner: '$($acl.Owner)'. '$($Owners[0])' should own $FilePath."
Do {
Write-Warning $warning
$input = Read-Host -Prompt "Shall I set the file owner? [Yes] Y; [No] N (default is `"Y`")"
if([string]::IsNullOrEmpty($input))
{
$input = 'Y'
}
} until ($input -match "^(y(es)?|N(o)?)$")
$result = $Matches[0]
}
if($result.ToLower().Startswith('y'))
{
$needChange = $true
$acl.SetOwner($Owners[0])
Write-Host "'$($Owners[0])' now owns $FilePath. " -ForegroundColor Green
}
else
{
$health = $false
Write-Host "The owner is still set to '$($acl.Owner)'." -ForegroundColor Yellow
}
}
$ReadAccessPerm = ([System.UInt32] [System.Security.AccessControl.FileSystemRights]::Read.value__) -bor `
([System.UInt32] [System.Security.AccessControl.FileSystemRights]::Synchronize.value__)
#system and admin groups can have any access to the file; plus the account in the AnyAccessOK list
$realAnyAccessOKList = $AnyAccessOK + @($systemAccount, $adminsAccount)
#if accounts in the ReadAccessNeeded already part of dacl, they are okay; need to make sure they have read access only
$realReadAcessOKList = $ReadAccessOK + $ReadAccessNeeded
#this is orginal list requested by the user, the account will be removed from the list if they already part of the dacl
$realReadAccessNeeded = $ReadAccessNeeded
foreach($a in $acl.Access)
{
if(($realAnyAccessOKList -ne $null) -and $realAnyAccessOKList.Contains($a.IdentityReference))
{
#ignore those accounts listed in the AnyAccessOK list.
}
#If everyone is in the ReadAccessOK list, any user can have read access;
# below block make sure they are granted Read access only
elseif($realReadAcessOKList -and (($realReadAcessOKList.Contains($everyone)) -or `
($realReadAcessOKList.Contains($a.IdentityReference))))
{
if($realReadAccessNeeded -and ($a.IdentityReference.Equals($everyone)))
{
$realReadAccessNeeded.Clear()
}
elseif($realReadAccessNeeded -and $realReadAccessNeeded.Contains($a.IdentityReference))
{
$realReadAccessNeeded = $realReadAccessNeeded | ? { -not $_.Equals($a.IdentityReference) }
}
if (-not ($a.AccessControlType.Equals([System.Security.AccessControl.AccessControlType]::Allow)) -or `
(-not (([System.UInt32]$a.FileSystemRights.value__) -band (-bnot $ReadAccessPerm))))
{
continue;
}
$warning = "'$($a.IdentityReference)' has the following access to $($FilePath): '$($a.FileSystemRights)'."
if($a.IsInherited)
{
if($needChange)
{
Set-Acl -Path $FilePath -AclObject $acl
}
$message = @"
$warning
Need to remove inheritance to fix it.
"@
return Remove-RuleProtection -FilePath $FilePath -Message $message -Quiet:$Quiet
}
if (-not $Quiet) {
Do {
Write-Warning $warning
$input = Read-Host -Prompt "Shall I make it Read only? [Yes] Y; [No] N (default is `"Y`")"
if([string]::IsNullOrEmpty($input))
{
$input = 'Y'
}
} until ($input -match "^(y(es)?|N(o)?)$")
$result = $Matches[0]
}
if($result.ToLower().Startswith('y'))
{
$needChange = $true
$sshAce = New-Object System.Security.AccessControl.FileSystemAccessRule `
($a.IdentityReference, "Read", "None", "None", "Allow")
$acl.SetAccessRule($sshAce)
Write-Host "'$($a.IdentityReference)' now has Read access to $FilePath. " -ForegroundColor Green
}
else
{
$health = $false
Write-Host "'$($a.IdentityReference)' still has these access to $($FilePath): '$($a.FileSystemRights)'." -ForegroundColor Yellow
}
}
#other than AnyAccessOK and ReadAccessOK list, if any other account is allowed, they should be removed from the dacl
elseif($a.AccessControlType.Equals([System.Security.AccessControl.AccessControlType]::Allow))
{
$warning = "'$($a.IdentityReference)' should not have access to '$FilePath'. "
if($a.IsInherited)
{
if($needChange)
{
Set-Acl -Path $FilePath -AclObject $acl
}
$message = @"
$warning
Need to remove inheritance to fix it.
"@
return Remove-RuleProtection -FilePath $FilePath -Message $message -Quiet:$Quiet
}
if (-not $Quiet) {
Do {
Write-Warning $warning
$input = Read-Host -Prompt "Shall I remove this access? [Yes] Y; [No] N (default is `"Y`")"
if([string]::IsNullOrEmpty($input))
{
$input = 'Y'
}
} until ($input -match "^(y(es)?|N(o)?)$")
$result = $Matches[0]
}
if($result.ToLower().Startswith('y'))
{
$needChange = $true
if(-not ($acl.RemoveAccessRule($a)))
{
throw "failed to remove access of $($a.IdentityReference) rule to file $FilePath"
}
else
{
Write-Host "'$($a.IdentityReference)' has no more access to $FilePath." -ForegroundColor Green
}
}
else
{
$health = $false
Write-Host "'$($a.IdentityReference)' still has access to $FilePath." -ForegroundColor Yellow
}
}
}
#This is the real account list we need to add read access to the file
if($realReadAccessNeeded)
{
$realReadAccessNeeded | % {
if([string]::IsNullOrEmpty((Get-UserSID -User $_)))
{
Write-Warning "'$_' needs Read access to $FilePath', but it does not exit on the machine."
}
else
{
if (-not $Quiet) {
$warning = "'$_' needs Read access to $FilePath'."
Do {
Write-Warning $warning
$input = Read-Host -Prompt "Shall I make the above change? [Yes] Y; [No] N (default is `"Y`")"
if([string]::IsNullOrEmpty($input))
{
$input = 'Y'
}
} until ($input -match "^(y(es)?|N(o)?)$")
$result = $Matches[0]
}
if($result.ToLower().Startswith('y'))
{
$needChange = $true
$ace = New-Object System.Security.AccessControl.FileSystemAccessRule `
($_, "Read", "None", "None", "Allow")
$acl.AddAccessRule($ace)
Write-Host "'$_' now has Read access to $FilePath. " -ForegroundColor Green
}
else
{
$health = $false
Write-Host "'$_' does not have Read access to $FilePath." -ForegroundColor Yellow
}
}
}
}
if($needChange)
{
Set-Acl -Path $FilePath -AclObject $acl
}
if($health)
{
if ($needChange)
{
Write-Host " fixed permissions" -ForegroundColor Yellow
}
else
{
Write-Host " looks good" -ForegroundColor Green
}
}
Write-host " "
}
<#
.Synopsis
Remove-RuleProtection
#>
function Remove-RuleProtection
{
param (
[parameter(Mandatory=$true)]
[string]$FilePath,
[string]$Message,
[switch] $Quiet
)
if (-not $Quiet) {
Do
{
Write-Warning $Message
$input = Read-Host -Prompt "Shall I remove the inheritace? [Yes] Y; [No] N (default is `"Y`")"
if([string]::IsNullOrEmpty($input))
{
$input = 'Y'
}
} until ($input -match "^(y(es)?|N(o)?)$")
$result = $Matches[0]
}
if($result.ToLower().Startswith('y'))
{
$acl = Get-ACL $FilePath
$acl.SetAccessRuleProtection($True, $True)
Set-Acl -Path $FilePath -AclObject $acl
Write-Host "inheritance is removed from $FilePath. " -ForegroundColor Green
return $true
}
else
{
Write-Host "inheritance is not removed from $FilePath. Skip Checking FilePath." -ForegroundColor Yellow
return $false
}
}
<#
.Synopsis
Get-UserAccount
#>
function Get-UserAccount
{
param
( [parameter(Mandatory=$true)]
[string]$UserSid
)
try
{
$objSID = New-Object System.Security.Principal.SecurityIdentifier($UserSid)
$objUser = $objSID.Translate( [System.Security.Principal.NTAccount])
$objUser
}
catch {
}
}
<#
.Synopsis
Get-UserSID
#>
function Get-UserSID
{
param ([System.Security.Principal.NTAccount]$User)
try
{
$strSID = $User.Translate([System.Security.Principal.SecurityIdentifier])
$strSID.Value
}
catch {
}
}
Export-ModuleMember -Function Fix-HostSSHDConfigPermissions, Fix-HostKeyPermissions, Fix-AuthorizedKeyPermissions, Fix-UserKeyPermissions, Fix-UserSSHConfigPermissions

View File

@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.23107.0
VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ssh", "ssh.vcxproj", "{74E69D5E-A1EF-46EA-9173-19A412774104}"
ProjectSection(ProjectDependencies) = postProject
@ -149,6 +149,14 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unittest-match", "unittest-
{0D02F0F0-013B-4EE3-906D-86517F3822C0} = {0D02F0F0-013B-4EE3-906D-86517F3822C0}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ssh-keyscan", "ssh-keyscan.vcxproj", "{7D0A75FC-F366-4B60-B72F-B37C3EA07CCA}"
ProjectSection(ProjectDependencies) = postProject
{05E1115F-8529-46D0-AAAF-52A404CE79A7} = {05E1115F-8529-46D0-AAAF-52A404CE79A7}
{8F9D3B74-8D33-448E-9762-26E8DCC6B2F4} = {8F9D3B74-8D33-448E-9762-26E8DCC6B2F4}
{DD483F7D-C553-4740-BC1A-903805AD0174} = {DD483F7D-C553-4740-BC1A-903805AD0174}
{0D02F0F0-013B-4EE3-906D-86517F3822C0} = {0D02F0F0-013B-4EE3-906D-86517F3822C0}
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
@ -317,6 +325,14 @@ Global
{484A8CDE-B949-4BDA-B447-74685C8E032F}.Release|x64.Build.0 = Release|x64
{484A8CDE-B949-4BDA-B447-74685C8E032F}.Release|x86.ActiveCfg = Release|Win32
{484A8CDE-B949-4BDA-B447-74685C8E032F}.Release|x86.Build.0 = Release|Win32
{7D0A75FC-F366-4B60-B72F-B37C3EA07CCA}.Debug|x64.ActiveCfg = Debug|x64
{7D0A75FC-F366-4B60-B72F-B37C3EA07CCA}.Debug|x64.Build.0 = Debug|x64
{7D0A75FC-F366-4B60-B72F-B37C3EA07CCA}.Debug|x86.ActiveCfg = Debug|Win32
{7D0A75FC-F366-4B60-B72F-B37C3EA07CCA}.Debug|x86.Build.0 = Debug|Win32
{7D0A75FC-F366-4B60-B72F-B37C3EA07CCA}.Release|x64.ActiveCfg = Release|x64
{7D0A75FC-F366-4B60-B72F-B37C3EA07CCA}.Release|x64.Build.0 = Release|x64
{7D0A75FC-F366-4B60-B72F-B37C3EA07CCA}.Release|x86.ActiveCfg = Release|Win32
{7D0A75FC-F366-4B60-B72F-B37C3EA07CCA}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -342,5 +358,6 @@ Global
{890C6129-286F-4CD8-8252-FB8D3B4E6E1B} = {A8096E32-E084-4FA0-AE01-A8D909EB2BB4}
{FC568FF0-60F2-4B2E-AF62-FD392EDBA1B9} = {A8096E32-E084-4FA0-AE01-A8D909EB2BB4}
{484A8CDE-B949-4BDA-B447-74685C8E032F} = {A8096E32-E084-4FA0-AE01-A8D909EB2BB4}
{7D0A75FC-F366-4B60-B72F-B37C3EA07CCA} = {17322AAF-808F-4646-AD37-5B0EDDCB8F3E}
EndGlobalSection
EndGlobal

View File

@ -118,8 +118,12 @@
<Message>Generate crtheaders.h and config.h</Message>
</PreBuildEvent>
<PostBuildEvent>
<Command>copy /Y $(SolutionDir)install-ssh*ps1 $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\ &amp; copy /Y $(SolutionDir)uninstall-ssh*ps1 $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\ &amp; If NOT exist $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\sshd_config (copy $(SolutionDir)sshd_config $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\)</Command>
<Message>Copy install-sshd.ps1, uninstall-sshd.ps1 and sshd_config (if not already present) to build directory</Message>
<Command>copy /Y $(SolutionDir)install-ssh*ps1 $(OutDir)
copy /Y $(SolutionDir)uninstall-ssh*ps1 $(OutDir)
copy /Y $(SolutionDir)OpenSSHUtils.psm1 $(OutDir)
copy /Y $(SolutionDir)Fix*FilePermissions.ps1 $(OutDir)
If NOT exist $(OutDir)\sshd_config (copy $(SolutionDir)sshd_config $(OutDir))</Command>
<Message>Copy install-sshd.ps1, uninstall-sshd.ps1, OpenSSHUtils.psm1, FixHostFilePermissions.ps1, FixUserFilePermissions.ps1, and sshd_config (if not already present) to build directory</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@ -146,8 +150,12 @@
<Message>Generate crtheaders.h and config.h</Message>
</PreBuildEvent>
<PostBuildEvent>
<Command>copy /Y $(SolutionDir)install-ssh*ps1 $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\ &amp; copy /Y $(SolutionDir)uninstall-ssh*ps1 $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\ &amp; If NOT exist $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\sshd_config (copy $(SolutionDir)sshd_config $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\)</Command>
<Message>Copy install-sshd.ps1, uninstall-sshd.ps1 and sshd_config (if not already present) to build directory</Message>
<Command>copy /Y $(SolutionDir)install-ssh*ps1 $(OutDir)
copy /Y $(SolutionDir)uninstall-ssh*ps1 $(OutDir)
copy /Y $(SolutionDir)OpenSSHUtils.psm1 $(OutDir)
copy /Y $(SolutionDir)Fix*FilePermissions.ps1 $(OutDir)
If NOT exist $(OutDir)\sshd_config (copy $(SolutionDir)sshd_config $(OutDir))</Command>
<Message>Copy install-sshd.ps1, uninstall-sshd.ps1, OpenSSHUtils.psm1, FixHostFilePermissions.ps1, FixUserFilePermissions.ps1, and sshd_config (if not already present) to build directory</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@ -178,8 +186,12 @@
<Message>Generate crtheaders.h and config.h</Message>
</PreBuildEvent>
<PostBuildEvent>
<Command>copy /Y $(SolutionDir)install-ssh*ps1 $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\ &amp; copy /Y $(SolutionDir)uninstall-ssh*ps1 $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\ &amp; If NOT exist $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\sshd_config (copy $(SolutionDir)sshd_config $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\)</Command>
<Message>Copy install-sshd.ps1, uninstall-sshd.ps1 and sshd_config (if not already present) to build directory</Message>
<Command>copy /Y $(SolutionDir)install-ssh*ps1 $(OutDir)
copy /Y $(SolutionDir)uninstall-ssh*ps1 $(OutDir)
copy /Y $(SolutionDir)OpenSSHUtils.psm1 $(OutDir)
copy /Y $(SolutionDir)Fix*FilePermissions.ps1 $(OutDir)
If NOT exist $(OutDir)\sshd_config (copy $(SolutionDir)sshd_config $(OutDir))</Command>
<Message>Copy install-sshd.ps1, uninstall-sshd.ps1, OpenSSHUtils.psm1, FixHostFilePermissions.ps1, FixUserFilePermissions.ps1, and sshd_config (if not already present) to build directory</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@ -210,8 +222,12 @@
<Message>Generate crtheaders.h and config.h</Message>
</PreBuildEvent>
<PostBuildEvent>
<Command>copy /Y $(SolutionDir)install-ssh*ps1 $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\ &amp; copy /Y $(SolutionDir)uninstall-ssh*ps1 $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\ &amp; If NOT exist $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\sshd_config (copy $(SolutionDir)sshd_config $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\)</Command>
<Message>Copy install-sshd.ps1, uninstall-sshd.ps1 and sshd_config (if not already present) to build directory</Message>
<Command>copy /Y $(SolutionDir)install-ssh*ps1 $(OutDir)
copy /Y $(SolutionDir)uninstall-ssh*ps1 $(OutDir)
copy /Y $(SolutionDir)OpenSSHUtils.psm1 $(OutDir)
copy /Y $(SolutionDir)Fix*FilePermissions.ps1 $(OutDir)
If NOT exist $(OutDir)\sshd_config (copy $(SolutionDir)sshd_config $(OutDir))</Command>
<Message>Copy install-sshd.ps1, uninstall-sshd.ps1, OpenSSHUtils.psm1, FixHostFilePermissions.ps1, FixUserFilePermissions.ps1, and sshd_config (if not already present) to build directory</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

View File

@ -96,9 +96,9 @@ cmd.exe /c 'sc.exe sdset ssh-agent D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPW
New-Service -Name sshd -BinaryPathName $sshdpath -Description "SSH Daemon" -StartupType Manual -DependsOn ssh-agent | Out-Null
sc.exe config sshd obj= $sshdAccount
sc.exe privs sshd SeAssignPrimaryTokenPrivilege
Add-Privilege -Account $sshdAccount -Privilege SeAssignPrimaryTokenPrivilege
Add-Privilege -Account $sshdAccount -Privilege SeServiceLogonRight
if(-not (test-path $logsdir -PathType Container))
{

View File

@ -179,17 +179,14 @@
<ClCompile Include="$(OpenSSH-Src-Path)canohost.c" />
<ClCompile Include="$(OpenSSH-Src-Path)chacha.c" />
<ClCompile Include="$(OpenSSH-Src-Path)channels.c" />
<ClCompile Include="$(OpenSSH-Src-Path)cipher-3des1.c" />
<ClCompile Include="$(OpenSSH-Src-Path)cipher-aes.c" />
<ClCompile Include="$(OpenSSH-Src-Path)cipher-aesctr.c" />
<ClCompile Include="$(OpenSSH-Src-Path)cipher-bf1.c" />
<ClCompile Include="$(OpenSSH-Src-Path)cipher-chachapoly.c" />
<ClCompile Include="$(OpenSSH-Src-Path)cipher-ctr.c" />
<ClCompile Include="$(OpenSSH-Src-Path)cipher.c" />
<ClCompile Include="$(OpenSSH-Src-Path)cleanup.c" />
<ClCompile Include="$(OpenSSH-Src-Path)compat.c" />
<ClCompile Include="$(OpenSSH-Src-Path)crc32.c" />
<ClCompile Include="$(OpenSSH-Src-Path)deattack.c" />
<ClCompile Include="$(OpenSSH-Src-Path)dh.c">
<ExcludedFromBuild Condition="$(UseOpenSSL)==false">true</ExcludedFromBuild>
</ClCompile>
@ -287,6 +284,7 @@
<ClCompile Include="$(OpenSSH-Src-Path)digest-openssl.c">
<ExcludedFromBuild Condition="$(UseOpenSSL)==false">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)kexgexs.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="$(OpenSSH-Src-Path)crypto-wrap.h" />

View File

@ -1,300 +1,92 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<ClCompile Include="$(OpenSSH-Src-Path)addrmatch.c" />
<ClCompile Include="$(OpenSSH-Src-Path)atomicio.c" />
<ClCompile Include="$(OpenSSH-Src-Path)authfd.c" />
<ClCompile Include="$(OpenSSH-Src-Path)authfile.c" />
<ClCompile Include="$(OpenSSH-Src-Path)bitmap.c" />
<ClCompile Include="$(OpenSSH-Src-Path)blocks.c" />
<ClCompile Include="$(OpenSSH-Src-Path)bufaux.c" />
<ClCompile Include="$(OpenSSH-Src-Path)bufbn.c" />
<ClCompile Include="$(OpenSSH-Src-Path)bufec.c" />
<ClCompile Include="$(OpenSSH-Src-Path)buffer.c" />
<ClCompile Include="$(OpenSSH-Src-Path)canohost.c" />
<ClCompile Include="$(OpenSSH-Src-Path)chacha.c" />
<ClCompile Include="$(OpenSSH-Src-Path)channels.c" />
<ClCompile Include="$(OpenSSH-Src-Path)cipher-3des1.c" />
<ClCompile Include="$(OpenSSH-Src-Path)cipher-aes.c" />
<ClCompile Include="$(OpenSSH-Src-Path)cipher-aesctr.c" />
<ClCompile Include="$(OpenSSH-Src-Path)cipher-bf1.c" />
<ClCompile Include="$(OpenSSH-Src-Path)cipher-chachapoly.c" />
<ClCompile Include="$(OpenSSH-Src-Path)cipher-ctr.c" />
<ClCompile Include="$(OpenSSH-Src-Path)cipher.c" />
<ClCompile Include="$(OpenSSH-Src-Path)cleanup.c" />
<ClCompile Include="$(OpenSSH-Src-Path)compat.c" />
<ClCompile Include="$(OpenSSH-Src-Path)crc32.c" />
<ClCompile Include="$(OpenSSH-Src-Path)deattack.c" />
<ClCompile Include="$(OpenSSH-Src-Path)dh.c" />
<ClCompile Include="$(OpenSSH-Src-Path)digest-libc.c" />
<ClCompile Include="$(OpenSSH-Src-Path)dispatch.c" />
<ClCompile Include="$(OpenSSH-Src-Path)dns.c" />
<ClCompile Include="$(OpenSSH-Src-Path)ed25519.c" />
<ClCompile Include="$(OpenSSH-Src-Path)entropy.c" />
<ClCompile Include="$(OpenSSH-Src-Path)fatal.c" />
<ClCompile Include="$(OpenSSH-Src-Path)fe25519.c" />
<ClCompile Include="$(OpenSSH-Src-Path)ge25519.c" />
<ClCompile Include="$(OpenSSH-Src-Path)gss-genr.c" />
<ClCompile Include="$(OpenSSH-Src-Path)hash.c" />
<ClCompile Include="$(OpenSSH-Src-Path)hmac.c" />
<ClCompile Include="$(OpenSSH-Src-Path)hostfile.c" />
<ClCompile Include="$(OpenSSH-Src-Path)kex.c" />
<ClCompile Include="$(OpenSSH-Src-Path)kexc25519.c" />
<ClCompile Include="$(OpenSSH-Src-Path)kexc25519c.c" />
<ClCompile Include="$(OpenSSH-Src-Path)kexc25519s.c" />
<ClCompile Include="$(OpenSSH-Src-Path)kexdh.c" />
<ClCompile Include="$(OpenSSH-Src-Path)kexdhc.c" />
<ClCompile Include="$(OpenSSH-Src-Path)kexdhs.c" />
<ClCompile Include="$(OpenSSH-Src-Path)kexecdh.c" />
<ClCompile Include="$(OpenSSH-Src-Path)kexecdhc.c" />
<ClCompile Include="$(OpenSSH-Src-Path)kexecdhs.c" />
<ClCompile Include="$(OpenSSH-Src-Path)kexgex.c" />
<ClCompile Include="$(OpenSSH-Src-Path)kexgexc.c" />
<ClCompile Include="$(OpenSSH-Src-Path)key.c" />
<ClCompile Include="$(OpenSSH-Src-Path)krl.c" />
<ClCompile Include="$(OpenSSH-Src-Path)log.c" />
<ClCompile Include="$(OpenSSH-Src-Path)mac.c" />
<ClCompile Include="$(OpenSSH-Src-Path)monitor_fdpass.c" />
<ClCompile Include="$(OpenSSH-Src-Path)msg.c" />
<ClCompile Include="$(OpenSSH-Src-Path)nchan.c" />
<ClCompile Include="$(OpenSSH-Src-Path)opacket.c" />
<ClCompile Include="$(OpenSSH-Src-Path)packet.c" />
<ClCompile Include="$(OpenSSH-Src-Path)poly1305.c" />
<ClCompile Include="$(OpenSSH-Src-Path)rsa.c" />
<ClCompile Include="$(OpenSSH-Src-Path)sc25519.c" />
<ClCompile Include="$(OpenSSH-Src-Path)smult_curve25519_ref.c" />
<ClCompile Include="$(OpenSSH-Src-Path)ssh-dss.c" />
<ClCompile Include="$(OpenSSH-Src-Path)ssh-ecdsa.c" />
<ClCompile Include="$(OpenSSH-Src-Path)ssh-ed25519.c" />
<ClCompile Include="$(OpenSSH-Src-Path)ssh-pkcs11.c" />
<ClCompile Include="$(OpenSSH-Src-Path)ssh-rsa.c" />
<ClCompile Include="$(OpenSSH-Src-Path)sshbuf-getput-basic.c" />
<ClCompile Include="$(OpenSSH-Src-Path)sshbuf-getput-crypto.c" />
<ClCompile Include="$(OpenSSH-Src-Path)sshbuf-misc.c" />
<ClCompile Include="$(OpenSSH-Src-Path)sshbuf.c" />
<ClCompile Include="$(OpenSSH-Src-Path)ssherr.c" />
<ClCompile Include="$(OpenSSH-Src-Path)sshkey.c" />
<ClCompile Include="$(OpenSSH-Src-Path)ssh_api.c" />
<ClCompile Include="$(OpenSSH-Src-Path)umac.c" />
<ClCompile Include="$(OpenSSH-Src-Path)platform-pledge.c" />
<ClCompile Include="$(OpenSSH-Src-Path)platform-tracing.c" />
<ClCompile Include="$(OpenSSH-Src-Path)platform.c" />
<ClCompile Include="$(OpenSSH-Src-Path)sandbox-pledge.c" />
<ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\ttymodes_windows.c" />
<ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\w32-sshfileperm.c" />
<ClCompile Include="$(OpenSSH-Src-Path)digest-openssl.c" />
<ClCompile Include="..\..\..\kexgexs.c" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="$(OpenSSH-Src-Path)addrmatch.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)atomicio.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)authfd.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)authfile.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)bitmap.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)blocks.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)bufaux.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)bufbn.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)bufec.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)buffer.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)canohost.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)chacha.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)channels.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)cipher-3des1.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)cipher-aes.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)cipher-aesctr.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)cipher-bf1.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)cipher-chachapoly.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)cipher-ctr.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)cipher.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)cleanup.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)compat.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)crc32.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)deattack.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)dh.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)digest-libc.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)dispatch.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)dns.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)ed25519.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)entropy.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)fatal.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)fe25519.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)ge25519.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)gss-genr.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)hash.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)hmac.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)hostfile.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)kex.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)kexc25519.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)kexc25519c.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)kexc25519s.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)kexdh.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)kexdhc.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)kexdhs.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)kexecdh.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)kexecdhc.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)kexecdhs.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)kexgex.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)kexgexc.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)key.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)krl.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)log.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)mac.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)match.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)misc.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)moduli.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)monitor_fdpass.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)msg.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)nchan.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)opacket.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)packet.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)poly1305.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)progressmeter.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)readpass.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)rijndael.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)rsa.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)sc25519.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)smult_curve25519_ref.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)ssh-dss.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)ssh-ecdsa.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)ssh-ed25519.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)ssh-pkcs11.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)ssh-rsa.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)sshbuf-getput-basic.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)sshbuf-getput-crypto.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)sshbuf-misc.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)sshbuf.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)ssherr.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)sshkey.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)ssh_api.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)umac.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)uuencode.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)verify.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)xmalloc.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)platform-pledge.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)platform-tracing.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)platform.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)sandbox-pledge.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\ttymodes_windows.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)digest-openssl.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\w32-sshfileperm.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="$(OpenSSH-Src-Path)crypto-wrap.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="$(OpenSSH-Src-Path)sshfileperm.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="$(OpenSSH-Src-Path)crypto-wrap.h" />
<ClInclude Include="$(OpenSSH-Src-Path)sshfileperm.h" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,205 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="paths.targets" />
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{7D0A75FC-F366-4B60-B72F-B37C3EA07CCA}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>sshkeyscan</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
<ProjectName>ssh-keyscan</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\$(TargetName)\</IntDir>
<IncludePath>$(OpenSSH-Src-Path)contrib\win32\win32compat\inc;$(VC_IncludePath);$(WindowsSDK_IncludePath);</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\$(TargetName)\</IntDir>
<IncludePath>$(OpenSSH-Src-Path)contrib\win32\win32compat\inc;$(VC_IncludePath);$(WindowsSDK_IncludePath);</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\$(TargetName)\</IntDir>
<IncludePath>$(OpenSSH-Src-Path)contrib\win32\win32compat\inc;$(VC_IncludePath);$(WindowsSDK_IncludePath);</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\$(TargetName)\</IntDir>
<IncludePath>$(OpenSSH-Src-Path)contrib\win32\win32compat\inc;$(VC_IncludePath);$(WindowsSDK_IncludePath);</IncludePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level1</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_WIN32_WINNT=0x600;WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>false</SDLCheck>
<AdditionalIncludeDirectories>$(SolutionDir);$(OpenSSL-Win32-Debug-Path)include;$(OpenSSH-Src-Path)includes;$(OpenSSH-Src-Path);$(OpenSSH-Src-Path)contrib\win32\win32compat;$(OpenSSH-Src-Path)libkrb;$(OpenSSH-Src-Path)libkrb\libKrb5;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>Netapi32.lib;posix_compat.lib;bcrypt.lib;Userenv.lib;Ws2_32.lib;Secur32.lib;Shlwapi.lib;openbsd_compat.lib;libssh.lib;libeay32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-Win32-Debug-Path)lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<EntryPointSymbol>wmainCRTStartup</EntryPointSymbol>
</Link>
<Manifest>
<AdditionalManifestFiles>targetos.manifest</AdditionalManifestFiles>
</Manifest>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level1</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_WIN32_WINNT=0x600;WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>false</SDLCheck>
<AdditionalIncludeDirectories>$(SolutionDir);$(OpenSSL-x64-Debug-Path)include;$(OpenSSH-Src-Path)includes;$(OpenSSH-Src-Path);$(OpenSSH-Src-Path)contrib\win32\win32compat;$(OpenSSH-Src-Path)libkrb;$(OpenSSH-Src-Path)libkrb\libKrb5;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>Netapi32.lib;posix_compat.lib;bcrypt.lib;Userenv.lib;Ws2_32.lib;Secur32.lib;Shlwapi.lib;openbsd_compat.lib;libssh.lib;libeay32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-x64-Debug-Path)lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<EntryPointSymbol>wmainCRTStartup</EntryPointSymbol>
</Link>
<Manifest>
<AdditionalManifestFiles>targetos.manifest</AdditionalManifestFiles>
</Manifest>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level1</WarningLevel>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>_WIN32_WINNT=0x600;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>false</SDLCheck>
<AdditionalIncludeDirectories>$(SolutionDir);$(OpenSSL-Win32-Release-Path)include;$(OpenSSH-Src-Path)includes;$(OpenSSH-Src-Path);$(OpenSSH-Src-Path)contrib\win32\win32compat;$(OpenSSH-Src-Path)libkrb;$(OpenSSH-Src-Path)libkrb\libKrb5;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>Netapi32.lib;posix_compat.lib;bcrypt.lib;Userenv.lib;Ws2_32.lib;Secur32.lib;Shlwapi.lib;openbsd_compat.lib;libssh.lib;libeay32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-Win32-Release-Path)lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<EntryPointSymbol>wmainCRTStartup</EntryPointSymbol>
<FullProgramDatabaseFile>true</FullProgramDatabaseFile>
</Link>
<Manifest>
<AdditionalManifestFiles>targetos.manifest</AdditionalManifestFiles>
</Manifest>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level1</WarningLevel>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<Optimization>Disabled</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>_WIN32_WINNT=0x600;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>false</SDLCheck>
<AdditionalIncludeDirectories>$(SolutionDir);$(OpenSSL-x64-Release-Path)include;$(OpenSSH-Src-Path)includes;$(OpenSSH-Src-Path);$(OpenSSH-Src-Path)contrib\win32\win32compat;$(OpenSSH-Src-Path)libkrb;$(OpenSSH-Src-Path)libkrb\libKrb5;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<WholeProgramOptimization>false</WholeProgramOptimization>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>Netapi32.lib;posix_compat.lib;bcrypt.lib;Userenv.lib;Ws2_32.lib;Secur32.lib;Shlwapi.lib;openbsd_compat.lib;libssh.lib;libeay32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-x64-Release-Path)lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<EntryPointSymbol>wmainCRTStartup</EntryPointSymbol>
<FullProgramDatabaseFile>true</FullProgramDatabaseFile>
</Link>
<Manifest>
<AdditionalManifestFiles>targetos.manifest</AdditionalManifestFiles>
</Manifest>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="$(OpenSSH-Src-Path)ssh-keyscan.c" />
<ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\wmain_common.c" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="version.rc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="$(OpenSSH-Src-Path)ssh-keyscan.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\wmain_common.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="version.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project>

View File

@ -122,7 +122,7 @@
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level1</WarningLevel>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_WIN32_WINNT=0x600;WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>false</SDLCheck>
@ -164,7 +164,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level1</WarningLevel>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="paths.targets" />
<ItemGroup Label="ProjectConfigurations">
@ -296,7 +296,6 @@
<ClCompile Include="$(OpenSSH-Src-Path)readconf.c" />
<ClCompile Include="$(OpenSSH-Src-Path)ssh.c" />
<ClCompile Include="$(OpenSSH-Src-Path)sshconnect.c" />
<ClCompile Include="$(OpenSSH-Src-Path)sshconnect1.c" />
<ClCompile Include="$(OpenSSH-Src-Path)sshconnect2.c" />
<ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\wmain_common.c" />
<ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\win32_sshtty.c" />
@ -308,4 +307,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
@ -299,9 +299,6 @@
<ClCompile Include="$(OpenSSH-Src-Path)sshconnect.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)sshconnect1.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)sshconnect2.c">
<Filter>Source Files</Filter>
</ClCompile>
@ -320,4 +317,4 @@
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project>
</Project>

View File

@ -110,7 +110,7 @@
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>Netapi32.lib;posix_compat.lib;bcrypt.lib;Userenv.lib;Ws2_32.lib;Secur32.lib;Shlwapi.lib;openbsd_compat.lib;libssh.lib;libeay32.lib;Netapi32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>Netapi32.lib;posix_compat.lib;bcrypt.lib;Userenv.lib;Ws2_32.lib;Secur32.lib;Shlwapi.lib;openbsd_compat.lib;libssh.lib;libeay32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-Win32-Debug-Path)lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<ForceFileOutput>MultiplyDefinedSymbolOnly</ForceFileOutput>
<EntryPointSymbol>wmainCRTStartup</EntryPointSymbol>
@ -134,7 +134,7 @@
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>Netapi32.lib;posix_compat.lib;bcrypt.lib;Userenv.lib;Ws2_32.lib;Secur32.lib;Shlwapi.lib;openbsd_compat.lib;libssh.lib;libeay32.lib;Netapi32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>Netapi32.lib;posix_compat.lib;bcrypt.lib;Userenv.lib;Ws2_32.lib;Secur32.lib;Shlwapi.lib;openbsd_compat.lib;libssh.lib;libeay32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-x64-Debug-Path)lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<ForceFileOutput>MultiplyDefinedSymbolOnly</ForceFileOutput>
<EntryPointSymbol>wmainCRTStartup</EntryPointSymbol>
@ -161,7 +161,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>Netapi32.lib;posix_compat.lib;bcrypt.lib;Userenv.lib;Ws2_32.lib;Secur32.lib;Shlwapi.lib;openbsd_compat.lib;libssh.lib;libeay32.lib;Netapi32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>Netapi32.lib;posix_compat.lib;bcrypt.lib;Userenv.lib;Ws2_32.lib;Secur32.lib;Shlwapi.lib;openbsd_compat.lib;libssh.lib;libeay32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-Win32-Release-Path)lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<ForceFileOutput>MultiplyDefinedSymbolOnly</ForceFileOutput>
<EntryPointSymbol>wmainCRTStartup</EntryPointSymbol>
@ -190,7 +190,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>Netapi32.lib;posix_compat.lib;bcrypt.lib;Userenv.lib;Ws2_32.lib;Secur32.lib;Shlwapi.lib;openbsd_compat.lib;libssh.lib;libeay32.lib;Netapi32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>Netapi32.lib;posix_compat.lib;bcrypt.lib;Userenv.lib;Ws2_32.lib;Secur32.lib;Shlwapi.lib;openbsd_compat.lib;libssh.lib;libeay32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(OpenSSL-x64-Release-Path)lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<ForceFileOutput>MultiplyDefinedSymbolOnly</ForceFileOutput>
<EntryPointSymbol>wmainCRTStartup</EntryPointSymbol>
@ -227,7 +227,6 @@
<ClCompile Include="$(OpenSSH-Src-Path)gss-serv.c" />
<ClCompile Include="$(OpenSSH-Src-Path)kexdhs.c" />
<ClCompile Include="$(OpenSSH-Src-Path)kexecdhs.c" />
<ClCompile Include="$(OpenSSH-Src-Path)kexgexs.c" />
<ClCompile Include="$(OpenSSH-Src-Path)loginrec.c" />
<ClCompile Include="$(OpenSSH-Src-Path)md5crypt.c" />
<ClCompile Include="$(OpenSSH-Src-Path)monitor.c" />

View File

@ -90,9 +90,6 @@
<ClCompile Include="$(OpenSSH-Src-Path)kexecdhs.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)kexgexs.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="$(OpenSSH-Src-Path)loginrec.c">
<Filter>Source Files</Filter>
</ClCompile>

View File

@ -198,7 +198,6 @@
</Manifest>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="$(OpenSSH-Src-Path)kexgexs.c" />
<ClCompile Include="$(OpenSSH-Src-Path)regress\unittests\kex\tests.c" />
<ClCompile Include="$(OpenSSH-Src-Path)regress\unittests\kex\test_kex.c" />
<ClCompile Include="$(OpenSSH-Src-Path)regress\unittests\test_helper\test_helper.c" />

View File

@ -25,6 +25,12 @@
<ClCompile Include="$(OpenSSH-Src-Path)regress\unittests\win32compat\tests.c" />
<ClCompile Include="$(OpenSSH-Src-Path)regress\unittests\test_helper\test_helper.c" />
<ClCompile Include="$(OpenSSH-Src-Path)contrib\win32\win32compat\wmain_common.c" />
<ClCompile Include="$(OpenSSH-Src-Path)regress\unittests\win32compat\dir_tests.c" />
<ClCompile Include="$(OpenSSH-Src-Path)regress\unittests\win32compat\miscellaneous_tests.c" />
<ClCompile Include="$(OpenSSH-Src-Path)regress\unittests\win32compat\string_tests.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="$(OpenSSH-Src-Path)regress\unittests\win32compat\tests.h" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{BF295BA9-4BF8-43F8-8CBF-FAE84815466C}</ProjectGuid>

Binary file not shown.

View File

@ -176,7 +176,6 @@
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\inc\dlfcn.h" />
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\inc\syslog.h" />
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\signal_internal.h" />
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\inc\sys\param.h" />
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\inc\utf.h" />
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\inc\arpa\inet.h" />
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\inc\arpa\nameser.h" />

View File

@ -53,9 +53,6 @@
<Filter>inc\sys</Filter>
</ClInclude>
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\signal_internal.h" />
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\inc\sys\param.h">
<Filter>inc\sys</Filter>
</ClInclude>
<ClInclude Include="$(OpenSSH-Src-Path)\contrib\win32\win32compat\inc\utf.h">
<Filter>inc</Filter>
</ClInclude>

View File

@ -34,17 +34,37 @@
#include <io.h>
#include <errno.h>
#include <stddef.h>
#include <direct.h>
#include "w32fd.h"
#include "inc\utf.h"
#include "inc\fcntl.h"
#include "inc\pwd.h"
#include "misc_internal.h"
#include "debug.h"
#include <Sddl.h>
/* internal read buffer size */
#define READ_BUFFER_SIZE 100*1024
/* internal write buffer size */
#define WRITE_BUFFER_SIZE 100*1024
/*
* A ACE is a binary data structure of changeable length
* https://msdn.microsoft.com/en-us/library/windows/desktop/aa374928(v=vs.85).aspx
* The value is calculated based on current need: max sid string (184) plus the enough spaces for other fields in ACEs
*/
#define MAX_ACE_LENGTH 225
/*
* A security descriptor is a binary data structure of changeable length
* https://msdn.microsoft.com/en-us/library/windows/desktop/aa379570(v=vs.85).aspx
* The value is calculated based on current need: 4 ACEs plus the enough spaces for owner sid and dcal flag
*/
#define SDDL_LENGTH 5* MAX_ACE_LENGTH
/*MAX length attribute string looks like 0xffffffff*/
#define MAX_ATTRIBUTE_LENGTH 10
#define errno_from_Win32LastError() errno_from_Win32Error(GetLastError())
struct createFile_flags {
@ -241,13 +261,48 @@ error:
return -1;
}
static int
st_mode_to_file_att(int mode, wchar_t * attributes)
{
DWORD att = 0;
switch (mode) {
case S_IRWXO:
swprintf_s(attributes, MAX_ATTRIBUTE_LENGTH, L"FA");
break;
case S_IXOTH:
swprintf_s(attributes, MAX_ATTRIBUTE_LENGTH, L"FX");
break;
case S_IWOTH:
swprintf_s(attributes, MAX_ATTRIBUTE_LENGTH, L"FW");
break;
case S_IROTH:
swprintf_s(attributes, MAX_ATTRIBUTE_LENGTH, L"FR");
break;
default:
if((mode & S_IROTH) != 0)
att |= FILE_GENERIC_READ;
if ((mode & S_IWOTH) != 0)
att |= FILE_GENERIC_WRITE;
if ((mode & S_IXOTH) != 0)
att |= FILE_GENERIC_EXECUTE;
swprintf_s(attributes, MAX_ATTRIBUTE_LENGTH, L"%#lx", att);
break;
}
return 0;
}
/* maps open() file modes and flags to ones needed by CreateFile */
static int
createFile_flags_setup(int flags, int mode, struct createFile_flags* cf_flags)
createFile_flags_setup(int flags, u_short mode, struct createFile_flags* cf_flags)
{
/* check flags */
int rwflags = flags & 0x3;
int c_s_flags = flags & 0xfffffff0;
int rwflags = flags & 0x3, c_s_flags = flags & 0xfffffff0, ret = -1;
PSECURITY_DESCRIPTOR pSD = NULL;
wchar_t sddl[SDDL_LENGTH + 1] = { 0 }, owner_ace[MAX_ACE_LENGTH + 1] = {0}, everyone_ace[MAX_ACE_LENGTH + 1] = {0};
wchar_t owner_access[MAX_ATTRIBUTE_LENGTH + 1] = {0}, everyone_access[MAX_ATTRIBUTE_LENGTH + 1] = {0}, *sid_utf16;
PACL dacl = NULL;
struct passwd * pwd;
PSID owner_sid = NULL;
/*
* should be one of one of the following access modes:
@ -267,7 +322,7 @@ createFile_flags_setup(int flags, int mode, struct createFile_flags* cf_flags)
}
/*validate mode*/
if (mode &~(S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) {
if (mode & ~(S_IRWXU | S_IRWXG | S_IRWXO)) {
debug3("open - ERROR: unsupported mode: %d", mode);
errno = ENOTSUP;
return -1;
@ -286,12 +341,7 @@ createFile_flags_setup(int flags, int mode, struct createFile_flags* cf_flags)
case O_RDWR:
cf_flags->dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
break;
}
cf_flags->securityAttributes.lpSecurityDescriptor = NULL;
cf_flags->securityAttributes.bInheritHandle = TRUE;
cf_flags->securityAttributes.nLength = 0;
}
cf_flags->dwCreationDisposition = OPEN_EXISTING;
if (c_s_flags & O_TRUNC)
cf_flags->dwCreationDisposition = TRUNCATE_EXISTING;
@ -307,16 +357,65 @@ createFile_flags_setup(int flags, int mode, struct createFile_flags* cf_flags)
cf_flags->dwFlagsAndAttributes = FILE_FLAG_OVERLAPPED | SECURITY_IMPERSONATION | FILE_FLAG_BACKUP_SEMANTICS;
/*TODO - map mode */
/*map mode*/
if ((pwd = getpwuid(0)) == NULL)
fatal("getpwuid failed.");
return 0;
if ((sid_utf16 = utf8_to_utf16(pwd->pw_sid)) == NULL) {
debug3("Failed to get utf16 of the sid string");
errno = ENOMEM;
goto cleanup;
}
if (ConvertStringSidToSid(pwd->pw_sid, &owner_sid) == FALSE ||
(IsValidSid(owner_sid) == FALSE)) {
debug3("cannot retrieve SID of user %s", pwd->pw_name);
goto cleanup;
}
if (!IsWellKnownSid(owner_sid, WinLocalSystemSid) && ((mode & S_IRWXU) != 0)) {
if (st_mode_to_file_att((mode & S_IRWXU) >> 6, owner_access) != 0) {
debug3("st_mode_to_file_att()");
goto cleanup;
}
swprintf_s(owner_ace, MAX_ACE_LENGTH, L"(A;;%s;;;%s)", owner_access, sid_utf16);
}
if (mode & S_IRWXO) {
if (st_mode_to_file_att(mode & S_IRWXO, everyone_access) != 0) {
debug3("st_mode_to_file_att()");
goto cleanup;
}
swprintf_s(everyone_ace, MAX_ACE_LENGTH, L"(A;;%s;;;WD)", everyone_access);
}
swprintf_s(sddl, SDDL_LENGTH, L"O:%sD:PAI(A;;FA;;;BA)(A;;FA;;;SY)%s%s", sid_utf16, owner_ace, everyone_ace);
if (ConvertStringSecurityDescriptorToSecurityDescriptorW(sddl, SDDL_REVISION, &pSD, NULL) == FALSE) {
debug3("ConvertStringSecurityDescriptorToSecurityDescriptorW failed with error code %d", GetLastError());
goto cleanup;
}
if (IsValidSecurityDescriptor(pSD) == FALSE) {
debug3("IsValidSecurityDescriptor return FALSE");
goto cleanup;
}
cf_flags->securityAttributes.lpSecurityDescriptor = pSD;
cf_flags->securityAttributes.bInheritHandle = TRUE;
cf_flags->securityAttributes.nLength = sizeof(cf_flags->securityAttributes);
ret = 0;
cleanup:
if (owner_sid)
LocalFree(owner_sid);
if (sid_utf16)
free(sid_utf16);
return ret;
}
#define NULL_DEVICE "/dev/null"
/* open() implementation. Uses CreateFile to open file, console, device, etc */
struct w32_io*
fileio_open(const char *path_utf8, int flags, int mode)
fileio_open(const char *path_utf8, int flags, u_short mode)
{
struct w32_io* pio = NULL;
struct createFile_flags cf_flags;
@ -332,7 +431,7 @@ fileio_open(const char *path_utf8, int flags, int mode)
}
/* if opening null device, point to Windows equivalent */
if (strncmp(path_utf8, NULL_DEVICE, strlen(NULL_DEVICE)) == 0)
if (strncmp(path_utf8, NULL_DEVICE, strlen(NULL_DEVICE)+1) == 0)
path_utf8 = "NUL";
if ((path_utf16 = utf8_to_utf16(path_utf8)) == NULL) {
@ -341,27 +440,28 @@ fileio_open(const char *path_utf8, int flags, int mode)
return NULL;
}
if (createFile_flags_setup(flags, mode, &cf_flags) == -1)
return NULL;
if (createFile_flags_setup(flags, mode, &cf_flags) == -1) {
debug3("createFile_flags_setup() failed.");
goto cleanup;
}
handle = CreateFileW(path_utf16, cf_flags.dwDesiredAccess, cf_flags.dwShareMode,
&cf_flags.securityAttributes, cf_flags.dwCreationDisposition,
cf_flags.dwFlagsAndAttributes, NULL);
cf_flags.dwFlagsAndAttributes, NULL);
if (handle == INVALID_HANDLE_VALUE) {
errno = errno_from_Win32LastError();
debug3("failed to open file:%s error:%d", path_utf8, GetLastError());
free(path_utf16);
return NULL;
goto cleanup;
}
free(path_utf16);
pio = (struct w32_io*)malloc(sizeof(struct w32_io));
if (pio == NULL) {
CloseHandle(handle);
errno = ENOMEM;
debug3("fileio_open(), failed to allocate memory error:%d", errno);
return NULL;
goto cleanup;
}
memset(pio, 0, sizeof(struct w32_io));
@ -370,6 +470,11 @@ fileio_open(const char *path_utf8, int flags, int mode)
pio->fd_status_flags = O_NONBLOCK;
pio->handle = handle;
cleanup:
if ((&cf_flags.securityAttributes != NULL) && (&cf_flags.securityAttributes.lpSecurityDescriptor != NULL))
LocalFree(cf_flags.securityAttributes.lpSecurityDescriptor);
if(path_utf16)
free(path_utf16);
return pio;
}
@ -638,22 +743,62 @@ int
fileio_stat(const char *path, struct _stat64 *buf)
{
wchar_t* wpath = NULL;
int r = -1;
WIN32_FILE_ATTRIBUTE_DATA attributes = { 0 };
int ret = -1, len = 0;
if ((wpath = utf8_to_utf16(path)) == NULL)
fatal("failed to covert input arguments");
memset(buf, 0, sizeof(struct _stat64));
r = _wstat64(wpath, buf);
/* Detect root dir */
if (path && strcmp(path, "/") == 0) {
buf->st_mode = _S_IFDIR | _S_IREAD | 0xFF;
buf->st_dev = USHRT_MAX; // rootdir flag
return 0;
}
/*
* If we doesn't have sufficient permissions then _wstat64() is returning "file not found"
* TODO - Replace the above call with GetFileAttributesEx
*/
if ((wpath = utf8_to_utf16(path)) == NULL) {
errno = errno_from_Win32LastError();
debug3("utf8_to_utf16 failed for file:%s error:%d", path, GetLastError());
return -1;
}
if (GetFileAttributesExW(wpath, GetFileExInfoStandard, &attributes) == FALSE) {
errno = errno_from_Win32LastError();
debug3("GetFileAttributesExW with last error %d", GetLastError());
goto cleanup;
}
len = wcslen(wpath);
buf->st_ino = 0; /* Has no meaning in the FAT, HPFS, or NTFS file systems*/
buf->st_gid = 0; /* UNIX - specific; has no meaning on windows */
buf->st_uid = 0; /* UNIX - specific; has no meaning on windows */
buf->st_nlink = 1; /* number of hard links. Always 1 on non - NTFS file systems.*/
buf->st_mode |= file_attr_to_st_mode(wpath, attributes.dwFileAttributes);
buf->st_size = attributes.nFileSizeLow | (((off_t)attributes.nFileSizeHigh) << 32);
if (len > 1 && __ascii_iswalpha(*wpath) && (*(wpath + 1) == ':'))
buf->st_dev = buf->st_rdev = towupper(*wpath) - L'A'; /* drive num */
else
buf->st_dev = buf->st_rdev = _getdrive() - 1;
file_time_to_unix_time(&(attributes.ftLastAccessTime), &(buf->st_atime));
file_time_to_unix_time(&(attributes.ftLastWriteTime), &(buf->st_mtime));
file_time_to_unix_time(&(attributes.ftCreationTime), &(buf->st_ctime));
if (attributes.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
WIN32_FIND_DATAW findbuf = { 0 };
HANDLE handle = FindFirstFileW(wpath, &findbuf);
if (handle != INVALID_HANDLE_VALUE) {
if ((findbuf.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) &&
(findbuf.dwReserved0 == IO_REPARSE_TAG_SYMLINK)) {
buf->st_mode |= S_IFLNK;
}
FindClose(handle);
}
}
ret = 0;
cleanup:
if (wpath)
free(wpath);
return r;
free(wpath);
return ret;
}
long

View File

@ -16,11 +16,11 @@
int w32_fcntl(int fd, int cmd, ... /* arg */);
#define fcntl(a,b,...) w32_fcntl((a), (b), __VA_ARGS__)
#define open w32_open
int w32_open(const char *pathname, int flags, ...);
#define open(a,b,...) w32_open((a), (b), __VA_ARGS__)
int w32_open(const char *pathname, int flags, ... /* arg */);
void* w32_fd_to_handle(int fd);
int w32_allocate_fd_for_handle(void* h, int is_sock);
int w32_allocate_fd_for_handle(HANDLE, BOOL);
#define O_RDONLY _O_RDONLY
#define O_WRONLY _O_WRONLY

View File

@ -4,6 +4,6 @@
#define utimes w32_utimes
int usleep(unsigned int);
int gettimeofday(struct timeval *tv, void *tz);
int nanosleep(const struct timespec *req, struct timespec *rem);
int w32_utimes(const char *filename, struct timeval *tvp);
int gettimeofday(struct timeval *, void *);
int nanosleep(const struct timespec *, struct timespec *);
int w32_utimes(const char *, struct timeval *);

View File

@ -74,15 +74,11 @@ int w32_chdir(const char *dirname);
char *w32_getcwd(char *buffer, int maxlen);
#define getcwd w32_getcwd
int daemon(int nochdir, int noclose);
char *crypt(const char *key, const char *salt);
int link(const char *oldpath, const char *newpath);
int readlink(const char *path, char *link, int linklen);
int spawn_child(char* cmd, char** argv, int in, int out, int err, unsigned long flags);
int spawn_child(char*, char**, int, int, int, DWORD);
/*
* readpassphrase.h definitions

View File

@ -3,6 +3,7 @@
*
* UTF-16 <--> UTF-8 definitions
*/
#pragma once
#ifndef UTF_H
#define UTF_H 1

View File

@ -59,6 +59,10 @@ static char* s_programdir = NULL;
#define IO_REPARSE_TAG_SIS (0x80000007L) /* winnt ntifs */
#define REPARSE_MOUNTPOINT_HEADER_SIZE 8
/* Difference in us between UNIX Epoch and Win32 Epoch */
#define EPOCH_DELTA_US 116444736000000000ULL
#define RATE_DIFF 10000000ULL /* 1000 nsecs */
typedef struct _REPARSE_DATA_BUFFER {
ULONG ReparseTag;
USHORT ReparseDataLength;
@ -174,9 +178,6 @@ nanosleep(const struct timespec *req, struct timespec *rem)
}
}
/* Difference in us between UNIX Epoch and Win32 Epoch */
#define EPOCH_DELTA_US 11644473600000000ULL
/* This routine is contributed by * Author: NoMachine <developers@nomachine.com>
* Copyright (c) 2009, 2010 NoMachine
* All rights reserved
@ -191,17 +192,14 @@ gettimeofday(struct timeval *tv, void *tz)
unsigned long long us;
/* Fetch time since Jan 1, 1601 in 100ns increments */
GetSystemTimeAsFileTime(&timehelper.ft);
/* Convert to microseconds from 100 ns units */
us = timehelper.ns / 10;
GetSystemTimeAsFileTime(&timehelper.ft);
/* Remove the epoch difference */
us -= EPOCH_DELTA_US;
us = timehelper.ns - EPOCH_DELTA_US;
/* Stuff result into the timeval */
tv->tv_sec = (long)(us / 1000000ULL);
tv->tv_usec = (long)(us % 1000000ULL);
tv->tv_sec = (long)(us / RATE_DIFF);
tv->tv_usec = (long)(us % RATE_DIFF);
return 0;
}
@ -242,14 +240,27 @@ w32_fopen_utf8(const char *path, const char *mode)
FILE* f;
char utf8_bom[] = { 0xEF,0xBB,0xBF };
char first3_bytes[3];
int status = 1;
if (mode[1] != '\0') {
errno = ENOTSUP;
return NULL;
}
if (MultiByteToWideChar(CP_UTF8, 0, path, -1, wpath, PATH_MAX) == 0 ||
MultiByteToWideChar(CP_UTF8, 0, mode, -1, wmode, 5) == 0) {
if(NULL == path) {
errno = EINVAL;
debug3("fopen - ERROR:%d", errno);
return NULL;
}
/* if opening null device, point to Windows equivalent */
if (0 == strncmp(path, NULL_DEVICE, strlen(NULL_DEVICE)+1))
wcsncpy_s(wpath, PATH_MAX, L"NUL", 3);
else
status = MultiByteToWideChar(CP_UTF8, 0, path, -1, wpath, PATH_MAX);
if ((0 == status) ||
(0 == MultiByteToWideChar(CP_UTF8, 0, mode, -1, wmode, 5))) {
errno = EFAULT;
debug3("WideCharToMultiByte failed for %c - ERROR:%d", path, GetLastError());
return NULL;
@ -286,6 +297,8 @@ w32_fopen_utf8(const char *path, const char *mode)
*/
char*
w32_fgets(char *str, int n, FILE *stream) {
if (!str || !n || !stream) return NULL;
HANDLE h = (HANDLE)_get_osfhandle(_fileno(stream));
wchar_t* str_w = NULL;
char *ret = NULL, *str_tmp = NULL, *cp = NULL;
@ -550,16 +563,83 @@ w32_chown(const char *pathname, unsigned int owner, unsigned int group)
return -1;
}
static void
/* Convert a UNIX time into a Windows file time */
void
unix_time_to_file_time(ULONG t, LPFILETIME pft)
{
ULONGLONG ull;
ull = UInt32x32To64(t, 10000000) + 116444736000000000;
ull = UInt32x32To64(t, RATE_DIFF) + EPOCH_DELTA_US;
pft->dwLowDateTime = (DWORD)ull;
pft->dwHighDateTime = (DWORD)(ull >> 32);
}
/* Convert a Windows file time into a UNIX time_t */
void
file_time_to_unix_time(const LPFILETIME pft, time_t * winTime)
{
*winTime = ((long long)pft->dwHighDateTime << 32) + pft->dwLowDateTime;
*winTime -= EPOCH_DELTA_US;
*winTime /= RATE_DIFF; /* Nano to seconds resolution */
}
static BOOL
is_root_or_empty(wchar_t * path)
{
wchar_t * path_start;
BOOL has_drive_letter_and_colon;
int len;
if (!path)
return FALSE;
len = wcslen(path);
if((len > 1) && __ascii_iswalpha(path[0]) && path[1] == L':')
path_start = path + 2;
else
path_start = path;
/*path like c:\, /, \ are root directory*/
if ((*path_start == L'\0') || ((*path_start == L'\\' || *path_start == L'/' ) && path_start[1] == L'\0'))
return TRUE;
return FALSE;
}
static BOOL
has_executable_extension(wchar_t * path)
{
wchar_t * last_dot;
if (!path)
return FALSE;
last_dot = wcsrchr(path, L'.');
if (!last_dot)
return FALSE;
if (_wcsnicmp(last_dot, L".exe", 4) != 0 && _wcsnicmp(last_dot, L".cmd", 4) != 0 &&
_wcsnicmp(last_dot, L".bat", 4) != 0 && _wcsnicmp(last_dot, L".com", 4) != 0)
return FALSE;
return TRUE;
}
int
file_attr_to_st_mode(wchar_t * path, DWORD attributes)
{
int mode = S_IREAD;
if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0 || is_root_or_empty(path))
mode |= S_IFDIR | _S_IEXEC;
else {
mode |= S_IFREG;
/* See if file appears to be an executable by checking its extension */
if (has_executable_extension(path))
mode |= _S_IEXEC;
}
if (!(attributes & FILE_ATTRIBUTE_READONLY))
mode |= S_IWRITE;
// propagate owner read/write/execute bits to group/other fields.
mode |= (mode & 0700) >> 3;
mode |= (mode & 0700) >> 6;
return mode;
}
static int
settimes(wchar_t * path, FILETIME *cretime, FILETIME *acttime, FILETIME *modtime)
{
@ -708,6 +788,8 @@ w32_chdir(const char *dirname_utf8)
char *
w32_getcwd(char *buffer, int maxlen)
{
if(!buffer) return NULL;
wchar_t wdirname[PATH_MAX];
char* putf8 = NULL;
@ -769,6 +851,16 @@ convertToBackslash(char *str)
}
}
void
convertToBackslashW(wchar_t *str)
{
while (*str) {
if (*str == L'/')
*str = L'\\';
str++;
}
}
/* convert back slash to forward slash */
void
convertToForwardslash(char *str)
@ -787,12 +879,14 @@ convertToForwardslash(char *str)
char *
realpath(const char *path, char resolved[PATH_MAX])
{
if (!path || !resolved) return NULL;
char tempPath[PATH_MAX];
if ((path[0] == '/') && path[1] && (path[2] == ':'))
strncpy(resolved, path + 1, strlen(path)); /* skip the first '/' */
strncpy(resolved, path + 1, PATH_MAX); /* skip the first '/' */
else
strncpy(resolved, path, strlen(path) + 1);
strncpy(resolved, path, PATH_MAX);
if ((resolved[0]) && (resolved[1] == ':') && (resolved[2] == '\0')) { /* make "x:" as "x:\\" */
resolved[2] = '\\';
@ -805,13 +899,15 @@ realpath(const char *path, char resolved[PATH_MAX])
convertToForwardslash(tempPath);
resolved[0] = '/'; /* will be our first slash in /x:/users/test1 format */
strncpy(resolved + 1, tempPath, sizeof(tempPath) - 1);
strncpy(resolved + 1, tempPath, PATH_MAX - 1);
return resolved;
}
char*
sanitized_path(const char *path)
{
if(!path) return NULL;
static char newPath[PATH_MAX] = { '\0', };
if (path[0] == '/' && path[1]) {
@ -903,8 +999,8 @@ statvfs(const char *path, struct statvfs *buf)
DWORD totalClusters;
wchar_t* path_utf16 = utf8_to_utf16(sanitized_path(path));
if (GetDiskFreeSpaceW(path_utf16, &sectorsPerCluster, &bytesPerSector,
&freeClusters, &totalClusters) == TRUE) {
if (path_utf16 && (GetDiskFreeSpaceW(path_utf16, &sectorsPerCluster, &bytesPerSector,
&freeClusters, &totalClusters) == TRUE)) {
debug5("path : [%s]", path);
debug5("sectorsPerCluster : [%lu]", sectorsPerCluster);
debug5("bytesPerSector : [%lu]", bytesPerSector);

View File

@ -4,6 +4,16 @@
#define SSH_ASYNC_STDOUT "SSH_ASYNC_STDOUT"
#define SSH_ASYNC_STDERR "SSH_ASYNC_STDERR"
#define GOTO_CLEANUP_IF(_cond_,_err_) do { \
if ((_cond_)) { \
hr = _err_; \
goto cleanup; \
} \
} while(0)
#define NULL_DEVICE "/dev/null"
#define IS_INVALID_HANDLE(h) ( ((NULL == h) || (INVALID_HANDLE_VALUE == h)) ? 1 : 0 )
/* removes first '/' for Windows paths that are unix styled. Ex: /c:/ab.cd */
char * sanitized_path(const char *);
@ -13,4 +23,8 @@ void w32posix_done();
char* w32_programdir();
void convertToBackslash(char *str);
void convertToBackslashW(wchar_t *str);
void convertToForwardslash(char *str);
void unix_time_to_file_time(ULONG, LPFILETIME);
void file_time_unix_time(const LPFILETIME, time_t *);

View File

@ -223,7 +223,7 @@ SendKeyStroke(HANDLE hInput, int keyStroke, char character)
void
ProcessIncomingKeys(char * ansikey)
{
int keylen = strlen(ansikey);
int keylen = (int)strlen(ansikey);
if (!keylen)
return;
@ -407,7 +407,7 @@ SendCharacter(HANDLE hInput, WORD attributes, wchar_t character)
StringCbPrintfExA(Next, SizeLeft, &Next, &SizeLeft, 0, "m", Color);
if (bUseAnsiEmulation && attributes != pattributes)
WriteFile(hInput, formatted_output, (Next - formatted_output), &wr, NULL);
WriteFile(hInput, formatted_output, (DWORD)(Next - formatted_output), &wr, NULL);
/* East asian languages have 2 bytes for each character, only use the first */
if (!(attributes & COMMON_LVB_TRAILING_BYTE)) {
@ -481,8 +481,8 @@ SizeWindow(HANDLE hInput)
inputSi.dwYCountChars = 25;
}
srWindowRect.Right = (SHORT)(min(inputSi.dwXCountChars, coordScreen.X) - 1);
srWindowRect.Bottom = (SHORT)(min(inputSi.dwYCountChars, coordScreen.Y) - 1);
srWindowRect.Right = (SHORT)(min(inputSi.dwXCountChars, (DWORD)coordScreen.X) - 1);
srWindowRect.Bottom = (SHORT)(min(inputSi.dwYCountChars, (DWORD)coordScreen.Y) - 1);
srWindowRect.Left = srWindowRect.Top = (SHORT)0;
/* Define the new console buffer size to be the maximum possible */
@ -511,14 +511,12 @@ MonitorChild(_In_ LPVOID lpParameter)
DWORD
ProcessEvent(void *p)
{
char f[255];
wchar_t chUpdate;
WORD wAttributes;
WORD wX;
WORD wY;
DWORD dwProcessId;
DWORD wr = 0;
DWORD dwMode;
DWORD event;
HWND hwnd;
LONG idObject;
@ -640,8 +638,8 @@ ProcessEvent(void *p)
return dwError;
}
if (readRect.Top > currentLine)
for (SHORT n = currentLine; n < readRect.Top; n++)
if ((DWORD)readRect.Top > currentLine)
for (DWORD n = currentLine; n < (DWORD)readRect.Top; n++)
SendLF(pipe_out);
/* Set cursor location based on the reported location from the message */
@ -779,8 +777,6 @@ ProcessEventQueue(LPVOID p)
if (child_in != INVALID_HANDLE_VALUE && child_in != NULL &&
child_out != INVALID_HANDLE_VALUE && child_out != NULL) {
DWORD dwInputMode;
DWORD dwOutputMode;
ZeroMemory(&consoleInfo, sizeof(consoleInfo));
consoleInfo.cbSize = sizeof(consoleInfo);
@ -908,8 +904,6 @@ ConsoleEventProc(HWINEVENTHOOK hWinEventHook,
DWORD
ProcessMessages(void* p)
{
BOOL ret;
DWORD dwMode;
DWORD dwStatus;
SECURITY_ATTRIBUTES sa;
MSG msg;
@ -966,8 +960,6 @@ start_with_pty(wchar_t *command)
wchar_t cmd[MAX_CMD_LEN];
SECURITY_ATTRIBUTES sa;
BOOL ret;
DWORD dwThreadId;
DWORD dwMode;
DWORD dwStatus;
HANDLE hEventHook = NULL;
HMODULE hm_kernel32 = NULL, hm_user32 = NULL;
@ -1040,18 +1032,18 @@ start_with_pty(wchar_t *command)
/* monitor child exist */
child = pi.hProcess;
monitor_thread = CreateThread(NULL, 0, MonitorChild, NULL, 0, NULL);
if (monitor_thread == INVALID_HANDLE_VALUE)
if (IS_INVALID_HANDLE(monitor_thread))
goto cleanup;
/* disable Ctrl+C hander in this process*/
SetConsoleCtrlHandler(NULL, TRUE);
io_thread = CreateThread(NULL, 0, ProcessPipes, NULL, 0, NULL);
if (io_thread == INVALID_HANDLE_VALUE)
if (IS_INVALID_HANDLE(io_thread))
goto cleanup;
ux_thread = CreateThread(NULL, 0, ProcessEventQueue, NULL, 0, NULL);
if (ux_thread == INVALID_HANDLE_VALUE)
if (IS_INVALID_HANDLE(ux_thread))
goto cleanup;
ProcessMessages(NULL);
@ -1059,15 +1051,15 @@ cleanup:
dwStatus = GetLastError();
if (child != INVALID_HANDLE_VALUE)
TerminateProcess(child, 0);
if (monitor_thread != INVALID_HANDLE_VALUE) {
if (!IS_INVALID_HANDLE(monitor_thread)) {
WaitForSingleObject(monitor_thread, INFINITE);
CloseHandle(monitor_thread);
}
if (ux_thread != INVALID_HANDLE_VALUE) {
if (!IS_INVALID_HANDLE(ux_thread)) {
TerminateThread(ux_thread, S_OK);
CloseHandle(ux_thread);
}
if (io_thread != INVALID_HANDLE_VALUE) {
if (!IS_INVALID_HANDLE(io_thread)) {
TerminateThread(io_thread, 0);
CloseHandle(io_thread);
}
@ -1103,7 +1095,10 @@ start_withno_pty(wchar_t *command)
PROCESS_INFORMATION pi;
wchar_t cmd[MAX_CMD_LEN];
SECURITY_ATTRIBUTES sa;
BOOL ret;
BOOL ret, process_input = FALSE, run_under_cmd = FALSE;
size_t command_len;
char buf[128];
DWORD rd = 0, wr = 0, i = 0;
pipe_in = GetStdHandle(STD_INPUT_HANDLE);
pipe_out = GetStdHandle(STD_OUTPUT_HANDLE);
@ -1130,24 +1125,68 @@ start_withno_pty(wchar_t *command)
GOTO_CLEANUP_ON_FALSE(SetHandleInformation(pipe_in, HANDLE_FLAG_INHERIT, 0));
GOTO_CLEANUP_ON_FALSE(SetHandleInformation(child_pipe_write, HANDLE_FLAG_INHERIT, 0));
/*TODO - pick this up from system32*/
cmd[0] = L'\0';
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_CMD_LEN, L"cmd.exe"));
if (command) {
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_CMD_LEN, L" /c"));
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_CMD_LEN, L" "));
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_CMD_LEN, command));
/*
* check if the input needs to be processed (ex for CRLF translation)
* input stream needs to be processed when running the command
* within shell processor. This is needed when
* - launching a interactive shell (-nopty)
* ssh -T user@target
* - launching cmd explicity
* ssh user@target cmd
* - executing a cmd command
* ssh user@target dir
* - executing a cmd command within a cmd
* ssh user@target cmd /c dir
*/
if (!command)
process_input = TRUE;
else {
command_len = wcsnlen_s(command, MAX_CMD_LEN);
if ((command_len >= 3 && wcsncmp(command, L"cmd", 4) == 0) ||
(command_len >= 7 && wcsncmp(command, L"cmd.exe", 8) == 0) ||
(command_len >= 4 && wcsncmp(command, L"cmd ", 4) == 0) ||
(command_len >= 8 && wcsncmp(command, L"cmd.exe ", 8) == 0))
process_input = TRUE;
}
GOTO_CLEANUP_ON_FALSE(CreateProcess(NULL, cmd, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi));
/* Try launching command as is first */
if (command) {
ret = CreateProcessW(NULL, command, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
if (ret == FALSE) {
/* it was probably this case - ssh user@target dir */
if (GetLastError() == ERROR_FILE_NOT_FOUND)
run_under_cmd = TRUE;
else
goto cleanup;
}
}
else
run_under_cmd = TRUE;
/* if above failed with FILE_NOT_FOUND, try running the provided command under cmd*/
if (run_under_cmd) {
/*TODO - pick this up from system32*/
cmd[0] = L'\0';
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_CMD_LEN, L"cmd.exe"));
if (command) {
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_CMD_LEN, L" /c"));
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_CMD_LEN, L" "));
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_CMD_LEN, command));
}
GOTO_CLEANUP_ON_FALSE(CreateProcessW(NULL, cmd, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi));
/* Create process succeeded when running under cmd. input stream needs to be processed */
process_input = TRUE;
}
/* close unwanted handles*/
CloseHandle(child_pipe_read);
child_pipe_read = INVALID_HANDLE_VALUE;
child = pi.hProcess;
/* monitor child exist */
monitor_thread = CreateThread(NULL, 0, MonitorChild_nopty, NULL, 0, NULL);
if (monitor_thread == INVALID_HANDLE_VALUE)
if (IS_INVALID_HANDLE(monitor_thread))
goto cleanup;
/* disable Ctrl+C hander in this process*/
@ -1155,10 +1194,15 @@ start_withno_pty(wchar_t *command)
/* process data from pipe_in and route appropriately */
while (1) {
char buf[128];
DWORD rd = 0, wr = 0, i = 0;
GOTO_CLEANUP_ON_FALSE(ReadFile(pipe_in, buf, 128, &rd, NULL));
rd = wr = i = 0;
GOTO_CLEANUP_ON_FALSE(ReadFile(pipe_in, buf, sizeof(buf)-1, &rd, NULL));
if (process_input == FALSE) {
/* write stream directly to child stdin */
GOTO_CLEANUP_ON_FALSE(WriteFile(child_pipe_write, buf, rd, &wr, NULL));
continue;
}
/* else - process input before routing it to child */
while (i < rd) {
/* skip arrow keys */
if ((rd - i >= 3) && (buf[i] == '\033') && (buf[i + 1] == '[') &&
@ -1218,14 +1262,116 @@ start_withno_pty(wchar_t *command)
}
}
cleanup:
if (child != INVALID_HANDLE_VALUE)
TerminateProcess(child, 0);
if (monitor_thread != INVALID_HANDLE_VALUE)
/* close child's stdin first */
if(!IS_INVALID_HANDLE(child_pipe_write))
CloseHandle(child_pipe_write);
if (!IS_INVALID_HANDLE(monitor_thread)) {
WaitForSingleObject(monitor_thread, INFINITE);
CloseHandle(monitor_thread);
}
if (!IS_INVALID_HANDLE(child))
TerminateProcess(child, 0);
return child_exit_code;
}
#include <Shlobj.h>
#include <Sddl.h>
static void* xmalloc(size_t size) {
void* ptr;
if ((ptr = malloc(size)) == NULL) {
printf("out of memory");
exit(EXIT_FAILURE);
}
return ptr;
}
#define SET_USER_ENV(folder_id, evn_variable) do { \
if (SHGetKnownFolderPath(&folder_id,0,NULL,&path) == S_OK) \
{ \
SetEnvironmentVariableW(evn_variable, path); \
CoTaskMemFree(path); \
} \
} while (0)
/* set user environment variables from user profile */
static void setup_session_user_vars()
{
/* retrieve and set env variables. */
HKEY reg_key = 0;
wchar_t *path;
wchar_t name[256];
wchar_t *data = NULL, *data_expanded = NULL, *path_value = NULL, *to_apply;
DWORD type, name_chars = 256, data_chars = 0, data_expanded_chars = 0, required, i = 0;
LONG ret;
SET_USER_ENV(FOLDERID_LocalAppData, L"LOCALAPPDATA");
SET_USER_ENV(FOLDERID_Profile, L"USERPROFILE");
SET_USER_ENV(FOLDERID_RoamingAppData, L"APPDATA");
ret = RegOpenKeyExW(HKEY_CURRENT_USER, L"Environment", 0, KEY_QUERY_VALUE, &reg_key);
if (ret != ERROR_SUCCESS)
//error("Error retrieving user environment variables. RegOpenKeyExW returned %d", ret);
return;
else while (1) {
to_apply = NULL;
required = data_chars * 2;
name_chars = 256;
ret = RegEnumValueW(reg_key, i++, name, &name_chars, 0, &type, (LPBYTE)data, &required);
if (ret == ERROR_NO_MORE_ITEMS)
break;
else if (ret == ERROR_MORE_DATA || required > data_chars * 2) {
if (data != NULL)
free(data);
data = xmalloc(required);
data_chars = required / 2;
i--;
continue;
}
else if (ret != ERROR_SUCCESS)
break;
if (type == REG_SZ)
to_apply = data;
else if (type == REG_EXPAND_SZ) {
required = ExpandEnvironmentStringsW(data, data_expanded, data_expanded_chars);
if (required > data_expanded_chars) {
if (data_expanded)
free(data_expanded);
data_expanded = xmalloc(required * 2);
data_expanded_chars = required;
ExpandEnvironmentStringsW(data, data_expanded, data_expanded_chars);
}
to_apply = data_expanded;
}
if (wcsicmp(name, L"PATH") == 0) {
if ((required = GetEnvironmentVariableW(L"PATH", NULL, 0)) != 0) {
/* "required" includes null term */
path_value = xmalloc((wcslen(to_apply) + 1 + required) * 2);
GetEnvironmentVariableW(L"PATH", path_value, required);
path_value[required - 1] = L';';
memcpy(path_value + required, to_apply, (wcslen(to_apply) + 1) * 2);
to_apply = path_value;
}
}
if (to_apply)
SetEnvironmentVariableW(name, to_apply);
}
if (reg_key)
RegCloseKey(reg_key);
if (data)
free(data);
if (data_expanded)
free(data_expanded);
if (path_value)
free(path_value);
RevertToSelf();
}
int b64_pton(char const *src, u_char *target, size_t targsize);
int
@ -1254,6 +1400,8 @@ wmain(int ac, wchar_t **av)
return -1;
}
setup_session_user_vars();
/* decode cmd_b64*/
if (cmd_b64) {
char *cmd_b64_utf8, *cmd_utf8;
@ -1279,4 +1427,4 @@ wmain(int ac, wchar_t **av)
return start_with_pty(cmd);
else
return start_withno_pty(cmd);
}
}

View File

@ -112,7 +112,7 @@ socketio_acceptEx(struct w32_io* pio)
if (getsockname(pio->sock, (struct sockaddr*)&addr, &addrlen) == SOCKET_ERROR) {
errno = errno_from_WSALastError();
debug("acceptEx - getsockname() ERROR:%d, io:%p", errno, pio);
debug("acceptEx - getsockname() ERROR:%d, io:%p", WSAGetLastError(), pio);
return -1;
}
@ -120,7 +120,7 @@ socketio_acceptEx(struct w32_io* pio)
context->accept_socket = socket(addr.ss_family, SOCK_STREAM, IPPROTO_TCP);
if (context->accept_socket == INVALID_SOCKET) {
errno = errno_from_WSALastError();
debug3("acceptEx - socket() ERROR:%d, io:%p", errno, pio);
debug3("acceptEx - socket() ERROR:%d, io:%p", WSAGetLastError(), pio);
return -1;
}
@ -139,7 +139,7 @@ socketio_acceptEx(struct w32_io* pio)
/* if overlapped io is in progress, we are good */
if (WSAGetLastError() != ERROR_IO_PENDING) {
errno = errno_from_WSALastError();
debug3("acceptEx - AcceptEx() ERROR:%d, io:%p", errno, pio);
debug3("acceptEx - AcceptEx() ERROR:%d, io:%p", WSAGetLastError(), pio);
return -1;
}
}
@ -208,7 +208,7 @@ socketio_WSARecv(struct w32_io* pio, BOOL* completed)
pio->read_details.pending = TRUE;
} else {
errno = errno_from_WSALastError();
debug3("WSARecv - WSARecv() ERROR: io:%p %d", pio, errno);
debug3("WSARecv - WSARecv() ERROR: io:%p %d", pio, WSAGetLastError());
return -1;
}
}
@ -231,8 +231,8 @@ socketio_socket(int domain, int type, int protocol)
pio->sock = socket(domain, type, protocol);
if (pio->sock == INVALID_SOCKET) {
errno = errno_from_WSALastError();
debug3("socket - socket() ERROR:%d, io:%p", WSAGetLastError(), pio);
free(pio);
debug3("socket - socket() ERROR:%d, io:%p", errno, pio);
return NULL;
}
@ -240,13 +240,13 @@ socketio_socket(int domain, int type, int protocol)
return pio;
}
#define SET_ERRNO_ON_ERROR(expr) do { \
int ret = (expr); \
if (ret == SOCKET_ERROR) { \
errno = errno_from_WSALastError(); \
debug3("%s - ERROR:%d", __FUNCTION__, errno); \
} \
return ret; \
#define SET_ERRNO_ON_ERROR(expr) do { \
int ret = (expr); \
if (ret == SOCKET_ERROR) { \
errno = errno_from_WSALastError(); \
debug3("%s - ERROR:%d", __FUNCTION__, WSAGetLastError()); \
} \
return ret; \
} while (0)
/* implements setsockopt() */
@ -292,7 +292,7 @@ socketio_listen(struct w32_io* pio, int backlog)
if (SOCKET_ERROR == listen(pio->sock, backlog)) {
errno = errno_from_WSALastError();
debug3("listen - listen() ERROR:%d io:%p", errno, pio);
debug3("listen - listen() ERROR:%d io:%p", WSAGetLastError(), pio);
return -1;
}
@ -316,7 +316,7 @@ socketio_listen(struct w32_io* pio, int backlog)
&dwBytes, NULL, NULL)) {
free(context);
errno = errno_from_WSALastError();
debug3("listen - Ioctl1 ERROR:%d, io:%p", errno, pio);
debug3("listen - Ioctl1 ERROR:%d, io:%p", WSAGetLastError(), pio);
return -1;
}
@ -327,7 +327,7 @@ socketio_listen(struct w32_io* pio, int backlog)
&dwBytes, NULL, NULL)) {
free(context);
errno = errno_from_WSALastError();
debug3("listen - Ioctl2 ERROR:%d, io:%p", errno, pio);
debug3("listen - Ioctl2 ERROR:%d, io:%p", WSAGetLastError(), pio);
return -1;
}
@ -359,7 +359,8 @@ int
socketio_recv(struct w32_io* pio, void *buf, size_t len, int flags)
{
BOOL completed = FALSE;
debug5("recv - io:%p", pio);
debug5("recv - io:%p state:%d", pio, pio->internal.state);
if ((buf == NULL) || (len == 0)) {
errno = EINVAL;
debug3("recv - ERROR: invalid arguments, buf:%p, len:%d, io:%p", buf, len, pio);
@ -396,7 +397,7 @@ socketio_recv(struct w32_io* pio, void *buf, size_t len, int flags)
num_bytes_copied);
pio->read_details.remaining -= num_bytes_copied;
pio->read_details.completed += num_bytes_copied;
debug4("recv - returning %d bytes from prior completed IO, remaining:%d, io:%p",
debug5("recv - returning %d bytes from prior completed IO, remaining:%d, io:%p",
num_bytes_copied, pio->read_details.remaining, pio);
return num_bytes_copied;
}
@ -505,8 +506,9 @@ socketio_send(struct w32_io* pio, const void *buf, size_t len, int flags)
{
int ret = 0;
WSABUF wsabuf;
debug5("send - io:%p state:%d", pio, pio->internal.state);
debug4("send - io:%p", pio);
if ((buf == NULL) || (len == 0)) {
errno = EINVAL;
debug3("send - ERROR invalid arguments, buf:%p, len:%d, io:%p", buf, len, pio);
@ -536,7 +538,7 @@ socketio_send(struct w32_io* pio, const void *buf, size_t len, int flags)
if (pio->write_details.error) {
errno = errno_from_WSAError(pio->write_details.error);
debug3("ERROR:%d, io:%p", errno, pio);
debug3("ERROR:%d, io:%p", pio->write_details.error, pio);
return -1;
}
@ -597,7 +599,7 @@ socketio_send(struct w32_io* pio, const void *buf, size_t len, int flags)
return wsabuf.len;
} else {
errno = errno_from_WSALastError();
debug3("send - WSASend() ERROR:%d, io:%p", errno, pio);
debug3("send - WSASend() ERROR:%d, io:%p", WSAGetLastError(), pio);
return -1;
}
}
@ -618,7 +620,7 @@ socketio_close(struct w32_io* pio)
closesocket(pio->sock);
/* wait for pending io to abort */
SleepEx(0, TRUE);
if (((pio->internal.state == SOCK_CONNECTED) || (pio->internal.state == SOCK_ACCEPTED)) &&
if ((pio->internal.state == SOCK_READY) &&
(pio->read_details.pending || pio->write_details.pending)) {
debug4("close - IO is still pending on closed socket. read:%d, write:%d, io:%p",
pio->read_details.pending, pio->write_details.pending, pio);
@ -686,14 +688,14 @@ socketio_accept(struct w32_io* pio, struct sockaddr* addr, int* addrlen)
if (pio->read_details.error) {
errno = errno_from_WSAError(pio->read_details.error);
debug3("accept - ERROR: async io completed with error: %d, io:%p", errno, pio);
debug3("accept - ERROR: async io completed with error: %d, io:%p", pio->read_details.error, pio);
goto on_error;
}
if (0 != setsockopt(context->accept_socket, SOL_SOCKET,
SO_UPDATE_ACCEPT_CONTEXT, (char*)&pio->sock, sizeof(pio->sock))) {
errno = errno_from_WSALastError();
debug3("accept - ERROR: setsockopt failed:%d, io:%p", errno, pio);
debug3("accept - ERROR: setsockopt failed:%d, io:%p", WSAGetLastError(), pio);
goto on_error;
}
@ -706,7 +708,7 @@ socketio_accept(struct w32_io* pio, struct sockaddr* addr, int* addrlen)
memset(accept_io, 0, sizeof(struct w32_io));
accept_io->sock = context->accept_socket;
accept_io->internal.state = SOCK_ACCEPTED;
accept_io->internal.state = SOCK_READY;
context->accept_socket = INVALID_SOCKET;
debug4("accept io:%p", accept_io);
@ -795,7 +797,7 @@ socketio_connectex(struct w32_io* pio, const struct sockaddr* name, int namelen)
CloseHandle(pio->write_overlapped.hEvent);
pio->write_overlapped.hEvent = 0;
errno = errno_from_WSALastError();
debug3("connectex - ERROR ConnectEx() :%d, io:%p", errno, pio);
debug3("connectex - ERROR ConnectEx() :%d, io:%p", WSAGetLastError(), pio);
return -1;
}
}
@ -837,25 +839,35 @@ socketio_connect(struct w32_io* pio, const struct sockaddr* name, int namelen)
int
socketio_finish_connect(struct w32_io* pio)
{
DWORD wsa_error = 0;
debug5("finish_connect, io:%p", pio);
if (pio->write_details.error) {
errno = errno_from_WSAError(pio->write_details.error);
debug3("finish_connect - ERROR: async io completed with error: %d, io:%p", errno, pio);
return -1;
wsa_error = pio->write_details.error;
debug3("finish_connect - ERROR: async io completed with error: %d, io:%p", wsa_error, pio);
goto done;
}
if (0 != setsockopt(pio->sock, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0)) {
errno = errno_from_WSALastError();
debug3("finish_connect - ERROR: setsockopt failed:%d, io:%p", errno, pio);
return -1;
wsa_error = WSAGetLastError();
debug3("finish_connect - ERROR: setsockopt failed:%d, io:%p", wsa_error, pio);
goto done;
}
/* Reset any state used during connect */
/* close event handle */
done:
CloseHandle(pio->write_overlapped.hEvent);
ZeroMemory(&pio->write_details, sizeof(pio->write_details));
pio->internal.state = SOCK_CONNECTED;
return 0;
pio->write_overlapped.hEvent = 0;
pio->write_details.pending = FALSE;
if (wsa_error) {
pio->read_details.error = wsa_error;
pio->write_details.error = wsa_error;
errno = errno_from_WSAError(wsa_error);
} else /* reset write_detail that were previously used for async connect */
ZeroMemory(&pio->write_details, sizeof(pio->write_details));
pio->internal.state = SOCK_READY;
return (wsa_error? -1 : 0);
}
/* checks if a given io is ready/available */
@ -870,7 +882,7 @@ socketio_is_io_available(struct w32_io* pio, BOOL rd)
OVERLAPPED *overlapped = sock_listening ? &pio->read_overlapped : &pio->write_overlapped;
BOOL pending = sock_listening ? pio->read_details.pending : pio->write_details.pending;
if (pending)
if (pending) {
/* if there is an error to be picked up */
if (sock_listening) {
if (pio->read_details.error)
@ -879,18 +891,19 @@ socketio_is_io_available(struct w32_io* pio, BOOL rd)
if (pio->write_details.error)
return TRUE;
}
}
if (WSAGetOverlappedResult(pio->sock, overlapped, &numBytes, FALSE, &flags))
return TRUE;
else if (WSAGetLastError() != WSA_IO_INCOMPLETE) {
if (sock_listening)
pio->read_details.error = WSAGetLastError();
else
pio->write_details.error = WSAGetLastError();
return TRUE;
}
if (WSAGetOverlappedResult(pio->sock, overlapped, &numBytes, FALSE, &flags))
return TRUE;
else if (WSAGetLastError() != WSA_IO_INCOMPLETE) {
if (sock_listening)
pio->read_details.error = WSAGetLastError();
else
pio->write_details.error = WSAGetLastError();
return TRUE;
}
return FALSE;
return FALSE;
} else if (rd) {
if (pio->read_details.remaining || pio->read_details.error)
return TRUE;
@ -922,15 +935,15 @@ socketio_on_select(struct w32_io* pio, BOOL rd)
SetEvent(pio->read_overlapped.hEvent);
return;
}
} else {
} else if(sock_state == SOCK_READY) {
/* connected socket - WSARecv if needed */
if ((!pio->read_details.pending) && (!socketio_is_io_available(pio, rd)))
if (socketio_WSARecv(pio, NULL) != 0) {
/* set error, recv() will pick it */
pio->read_details.error = errno;
errno = 0;
return;
}
if ((!pio->read_details.pending) && (!socketio_is_io_available(pio, rd)) && (socketio_WSARecv(pio, NULL) != 0))
{
/* set error, recv() will pick it */
pio->read_details.error = errno;
errno = 0;
return;
}
}
}

View File

@ -31,7 +31,9 @@
*/
#include "agent.h"
#include "..\misc_internal.h"
#pragma warning(push, 3)
int scm_start_service(DWORD, LPWSTR*);
@ -133,7 +135,6 @@ wmain(int argc, wchar_t **argv)
/* - just start ssh-agent service if needed */
{
SC_HANDLE sc_handle, svc_handle;
DWORD err;
if ((sc_handle = OpenSCManagerW(NULL, NULL, SERVICE_START)) == NULL ||
(svc_handle = OpenServiceW(sc_handle, L"ssh-agent", SERVICE_START)) == NULL) {
@ -168,3 +169,4 @@ scm_start_service(DWORD num, LPWSTR* args)
return 0;
}
#pragma warning(pop)

View File

@ -110,9 +110,7 @@ agent_listen_loop()
if (GetLastError() == ERROR_PIPE_CONNECTED) {
debug("Client has already connected");
SetEvent(ol.hEvent);
}
if (GetLastError() != ERROR_IO_PENDING) {
} else if (GetLastError() != ERROR_IO_PENDING) {
debug("ConnectNamedPipe failed ERROR: %d", GetLastError());
SetEvent(event_stop_agent);
}

View File

@ -1,5 +1,7 @@
#include <Windows.h>
#include <stdio.h>
#define __attribute__(A)
#include "log.h"
#define MAX_MESSAGE_SIZE 256 * 1024
#define SSH_ROOT L"SOFTWARE\\SSH"
@ -25,10 +27,13 @@ struct agent_connection {
WRITING,
DONE
} state;
enum {
enum { /* retain this order */
UNKNOWN = 0,
USER, /* client is running as some user */
MACHINE /* clinet is running as machine - System, NS or LS */
NONADMIN_USER, /* client is running as a nonadmin user */
ADMIN_USER, /* client is running as admin */
SSHD_SERVICE, /* client is sshd service */
SYSTEM, /* client is running as System */
SERVICE, /* client is running as LS or NS */
} client_type;
HANDLE auth_token;
HANDLE hProfile;

View File

@ -48,13 +48,15 @@
#include <utf.h>
#pragma warning(push, 3)
Buffer cfg;
ServerOptions options;
struct passwd *privsep_pw = NULL;
static char *config_file_name = _PATH_SERVER_CONFIG_FILE;
int auth_sock = -1;
int
int
auth2_methods_valid(const char * c, int i) {
return 1;
}
@ -97,12 +99,16 @@ int
load_config() {
wchar_t basePath[PATH_MAX] = { 0 };
wchar_t path[PATH_MAX] = { 0 };
wchar_t* config_file = L"/sshd_config";
if (GetCurrentModulePath(basePath, PATH_MAX) == -1)
return -1;
wcsncpy(path, basePath, PATH_MAX);
wcsncat(path, L"/sshd_config", PATH_MAX);
if (wcslen(basePath) + wcslen(config_file) + 1 > PATH_MAX)
fatal("unexpected config file path length");
wcsncpy_s(path, PATH_MAX, basePath, PATH_MAX);
wcsncat_s(path, PATH_MAX, L"/sshd_config", PATH_MAX - wcslen(basePath));
if ((config_file_name = utf16_to_utf8(path)) == NULL)
return -1;
@ -129,4 +135,6 @@ pubkey_allowed(struct sshkey* pubkey, HANDLE user_token) {
return 0;
return user_key_allowed(pw, pubkey, 1);
}
}
#pragma warning(pop)

View File

@ -40,6 +40,11 @@
#include "key.h"
#include "inc\utf.h"
#pragma warning(push, 3)
int
pubkey_allowed(struct sshkey*, HANDLE);
static void
InitLsaString(LSA_STRING *lsa_string, const char *str)
{
@ -47,7 +52,7 @@ InitLsaString(LSA_STRING *lsa_string, const char *str)
memset(lsa_string, 0, sizeof(LSA_STRING));
else {
lsa_string->Buffer = (char *)str;
lsa_string->Length = strlen(str);
lsa_string->Length = (USHORT)strlen(str);
lsa_string->MaximumLength = lsa_string->Length + 1;
}
}
@ -146,7 +151,7 @@ generate_user_token(wchar_t* user_cpn) {
s4u_logon = (KERB_S4U_LOGON*)logon_info;
s4u_logon->MessageType = KerbS4ULogon;
s4u_logon->Flags = 0;
s4u_logon->ClientUpn.Length = wcslen(user_cpn) * 2;
s4u_logon->ClientUpn.Length = (USHORT)wcslen(user_cpn) * 2;
s4u_logon->ClientUpn.MaximumLength = s4u_logon->ClientUpn.Length;
s4u_logon->ClientUpn.Buffer = (WCHAR*)(s4u_logon + 1);
memcpy(s4u_logon->ClientUpn.Buffer, user_cpn, s4u_logon->ClientUpn.Length + 2);
@ -164,7 +169,7 @@ generate_user_token(wchar_t* user_cpn) {
s4u_logon = (MSV1_0_S4U_LOGON*)logon_info;
s4u_logon->MessageType = MsV1_0S4ULogon;
s4u_logon->Flags = 0;
s4u_logon->UserPrincipalName.Length = wcslen(user_cpn) * 2;
s4u_logon->UserPrincipalName.Length = (USHORT)wcslen(user_cpn) * 2;
s4u_logon->UserPrincipalName.MaximumLength = s4u_logon->UserPrincipalName.Length;
s4u_logon->UserPrincipalName.Buffer = (WCHAR*)(s4u_logon + 1);
memcpy(s4u_logon->UserPrincipalName.Buffer, user_cpn, s4u_logon->UserPrincipalName.Length + 2);
@ -184,7 +189,7 @@ generate_user_token(wchar_t* user_cpn) {
Network,
auth_package_id,
logon_info,
logon_info_size,
(ULONG)logon_info_size,
NULL,
&sourceContext,
(PVOID*)&pProfile,
@ -208,14 +213,39 @@ done:
return token;
}
static HANDLE
duplicate_token_for_client(struct agent_connection* con, HANDLE t) {
ULONG client_pid;
HANDLE client_proc = NULL, dup_t = NULL;
/* Should the token match client's session id?
ULONG client_sessionId;
if (GetNamedPipeClientSessionId(con->pipe_handle, &client_sessionId) == FALSE ||
SetTokenInformation(t, TokenSessionId, &client_sessionId, sizeof(client_sessionId)) == FALSE) {
error("unable to set token session id, error: %d", GetLastError());
goto done;
}*/
if ((FALSE == GetNamedPipeClientProcessId(con->pipe_handle, &client_pid)) ||
((client_proc = OpenProcess(PROCESS_DUP_HANDLE, FALSE, client_pid)) == NULL) ||
DuplicateHandle(GetCurrentProcess(), t, client_proc, &dup_t, TOKEN_QUERY | TOKEN_IMPERSONATE, FALSE, DUPLICATE_SAME_ACCESS) == FALSE ) {
error("failed to duplicate user token");
goto done;
}
done:
if (client_proc)
CloseHandle(client_proc);
return dup_t;
}
/* TODO - SecureZeroMemory password */
int process_passwordauth_request(struct sshbuf* request, struct sshbuf* response, struct agent_connection* con) {
char *user = NULL, *domain = NULL, *pwd = NULL;
size_t user_len, pwd_len;
wchar_t *user_utf16 = NULL, *udom_utf16 = NULL, *pwd_utf16 = NULL, *tmp;
int r = -1;
HANDLE token = 0, dup_token, client_proc = 0;
ULONG client_pid;
HANDLE token = 0, dup_token;
if (sshbuf_get_cstring(request, &user, &user_len) != 0 ||
sshbuf_get_cstring(request, &pwd, &pwd_len) != 0 ||
@ -243,13 +273,11 @@ int process_passwordauth_request(struct sshbuf* request, struct sshbuf* response
goto done;
}
if ((FALSE == GetNamedPipeClientProcessId(con->pipe_handle, &client_pid)) ||
((client_proc = OpenProcess(PROCESS_DUP_HANDLE, FALSE, client_pid)) == NULL) ||
(FALSE == DuplicateHandle(GetCurrentProcess(), token, client_proc, &dup_token, TOKEN_QUERY | TOKEN_IMPERSONATE, FALSE, DUPLICATE_SAME_ACCESS)) ||
(sshbuf_put_u32(response, (int)(intptr_t)dup_token) != 0)) {
debug("failed to duplicate user token");
if ((dup_token = duplicate_token_for_client(con, token)) == NULL)
goto done;
if (sshbuf_put_u32(response, (int)(intptr_t)dup_token) != 0)
goto done;
}
con->auth_token = token;
LoadProfile(con, user_utf16, udom_utf16);
@ -267,8 +295,6 @@ done:
free(user_utf16);
if (pwd_utf16)
free(pwd_utf16);
if (client_proc)
CloseHandle(client_proc);
return r;
}
@ -278,11 +304,10 @@ int process_pubkeyauth_request(struct sshbuf* request, struct sshbuf* response,
char *key_blob, *user, *sig, *blob;
size_t key_blob_len, user_len, sig_len, blob_len;
struct sshkey *key = NULL;
HANDLE token = NULL, dup_token = NULL, client_proc = NULL;
HANDLE token = NULL, dup_token = NULL;
wchar_t *user_utf16 = NULL, *udom_utf16 = NULL, *tmp;
PWSTR wuser_home = NULL;
ULONG client_pid;
LUID_AND_ATTRIBUTES priv_to_delete[1];
user = NULL;
if (sshbuf_get_string_direct(request, &key_blob, &key_blob_len) != 0 ||
@ -301,7 +326,7 @@ int process_pubkeyauth_request(struct sshbuf* request, struct sshbuf* response,
}
if ((token = generate_user_token(user_utf16)) == 0) {
debug("unable to generate token for user %ls", user_utf16);
error("unable to generate token for user %ls", user_utf16);
goto done;
}
@ -311,18 +336,16 @@ int process_pubkeyauth_request(struct sshbuf* request, struct sshbuf* response,
goto done;
}
if (key_verify(key, sig, sig_len, blob, blob_len) != 1) {
if (key_verify(key, sig, (u_int)sig_len, blob, (u_int)blob_len) != 1) {
debug("signature verification failed");
goto done;
}
if ((FALSE == GetNamedPipeClientProcessId(con->pipe_handle, &client_pid)) ||
( (client_proc = OpenProcess(PROCESS_DUP_HANDLE, FALSE, client_pid)) == NULL) ||
(FALSE == DuplicateHandle(GetCurrentProcess(), token, client_proc, &dup_token, TOKEN_QUERY | TOKEN_IMPERSONATE, FALSE, DUPLICATE_SAME_ACCESS)) ||
(sshbuf_put_u32(response, (int)(intptr_t)dup_token) != 0)) {
debug("failed to authorize user");
if ((dup_token = duplicate_token_for_client(con, token)) == NULL)
goto done;
if (sshbuf_put_u32(response, (int)(intptr_t)dup_token) != 0)
goto done;
}
con->auth_token = token;
token = NULL;
@ -346,8 +369,6 @@ done:
sshkey_free(key);
if (wuser_home)
CoTaskMemFree(wuser_home);
if (client_proc)
CloseHandle(client_proc);
if (token)
CloseHandle(token);
return r;
@ -361,6 +382,12 @@ int process_authagent_request(struct sshbuf* request, struct sshbuf* response, s
return -1;
}
/* allow only admins and NT Service\sshd to send auth requests */
if (con->client_type != SSHD_SERVICE && con->client_type != ADMIN_USER) {
error("cannot authenticate: client process is not admin or sshd");
return -1;
}
if (memcmp(opn, PUBKEY_AUTH_REQUEST, opn_len) == 0)
return process_pubkeyauth_request(request, response, con);
else if (memcmp(opn, PASSWD_AUTH_REQUEST, opn_len) == 0)
@ -369,4 +396,6 @@ int process_authagent_request(struct sshbuf* request, struct sshbuf* response, s
debug("unknown auth request: %s", opn);
return -1;
}
}
}
#pragma warning(pop)

View File

@ -31,6 +31,8 @@
#include "agent.h"
#include "agent-request.h"
#pragma warning(push, 3)
int process_request(struct agent_connection*);
#define ABORT_CONNECTION_RETURN(c) do { \
@ -114,20 +116,41 @@ agent_connection_disconnect(struct agent_connection* con)
DisconnectNamedPipe(con->pipe_handle);
}
static char*
con_type_to_string(struct agent_connection* con) {
switch (con->client_type) {
case UNKNOWN:
return "unknown";
case NONADMIN_USER:
return "restricted user";
case ADMIN_USER:
return "administrator";
case SSHD_SERVICE:
return "sshd service";
case SYSTEM:
return "system";
case SERVICE:
return "service";
default:
return "unexpected";
}
}
static int
get_con_client_type(struct agent_connection* con)
{
int r = -1;
char system_sid[SECURITY_MAX_SID_SIZE];
char ns_sid[SECURITY_MAX_SID_SIZE];
char ls_sid[SECURITY_MAX_SID_SIZE];
char sid[SECURITY_MAX_SID_SIZE];
wchar_t *sshd_act = L"NT SERVICE\\SSHD", *ref_dom = NULL;
DWORD reg_dom_len = 0, info_len = 0, sid_size;
DWORD sshd_sid_len = 0;
PSID sshd_sid = NULL;
SID_NAME_USE nuse;
HANDLE token;
TOKEN_USER* info = NULL;
HANDLE pipe = con->pipe_handle;
BOOL isMember = FALSE;
if (ImpersonateNamedPipeClient(pipe) == FALSE)
if (ImpersonateNamedPipeClient(con->pipe_handle) == FALSE)
return -1;
if (OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &token) == FALSE ||
@ -136,26 +159,76 @@ get_con_client_type(struct agent_connection* con)
GetTokenInformation(token, TokenUser, info, info_len, &info_len) == FALSE)
goto done;
sid_size = SECURITY_MAX_SID_SIZE;
if (CreateWellKnownSid(WinLocalSystemSid, NULL, system_sid, &sid_size) == FALSE)
goto done;
sid_size = SECURITY_MAX_SID_SIZE;
if (CreateWellKnownSid(WinNetworkServiceSid, NULL, ns_sid, &sid_size) == FALSE)
goto done;
sid_size = SECURITY_MAX_SID_SIZE;
if (CreateWellKnownSid(WinLocalServiceSid, NULL, ls_sid, &sid_size) == FALSE)
/* check if its localsystem */
if (IsWellKnownSid(info->User.Sid, WinLocalSystemSid)) {
con->client_type = SYSTEM;
r = 0;
goto done;
}
if (EqualSid(info->User.Sid, system_sid) ||
EqualSid(info->User.Sid, ls_sid) ||
EqualSid(info->User.Sid, ns_sid))
con->client_type = MACHINE;
else
con->client_type = USER;
/* check if its SSHD service */
{
/* Does NT Service/SSHD exist */
LookupAccountNameW(NULL, sshd_act, NULL, &sshd_sid_len, NULL, &reg_dom_len, &nuse);
if (GetLastError() == ERROR_NONE_MAPPED)
debug3("Cannot look up SSHD account, its likely not installed");
else if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
error("LookupAccountNameW on SSHD account failed with %d", GetLastError());
goto done;
} else {
if ((sshd_sid = malloc(sshd_sid_len)) == NULL ||
(ref_dom = (wchar_t*)malloc(reg_dom_len * 2)) == NULL ||
LookupAccountNameW(NULL, sshd_act, sshd_sid, &sshd_sid_len, ref_dom, &reg_dom_len, &nuse) == FALSE)
goto done;
debug2("client type: %s", con->client_type == MACHINE? "machine" : "user");
if (EqualSid(info->User.Sid, sshd_sid)) {
con->client_type = SSHD_SERVICE;
r = 0;
goto done;
}
if (CheckTokenMembership(token, sshd_sid, &isMember) == FALSE)
goto done;
if (isMember) {
con->client_type = SSHD_SERVICE;
r = 0;
goto done;
}
}
}
/* check if its LS or NS */
if (IsWellKnownSid(info->User.Sid, WinNetworkServiceSid) ||
IsWellKnownSid(info->User.Sid, WinLocalServiceSid)) {
con->client_type = SERVICE;
r = 0;
goto done;
}
/* check if its admin */
{
sid_size = SECURITY_MAX_SID_SIZE;
if (CreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, sid, &sid_size) == FALSE)
goto done;
if (CheckTokenMembership(token, sid, &isMember) == FALSE)
goto done;
if (isMember) {
con->client_type = ADMIN_USER;
r = 0;
goto done;
}
}
/* none of above */
con->client_type = NONADMIN_USER;
r = 0;
done:
debug("client type: %s", con_type_to_string(con));
if (sshd_sid)
free(sshd_sid);
if (ref_dom)
free(ref_dom);
if (info)
free(info);
RevertToSelf();
@ -214,13 +287,15 @@ done:
ZeroMemory(&con->io_buf, sizeof(con->io_buf));
if (r == 0) {
POKE_U32(con->io_buf.buf, sshbuf_len(response));
POKE_U32(con->io_buf.buf, (u_int32_t)sshbuf_len(response));
memcpy(con->io_buf.buf + 4, sshbuf_ptr(response), sshbuf_len(response));
con->io_buf.num_bytes = sshbuf_len(response) + 4;
con->io_buf.num_bytes = (DWORD)sshbuf_len(response) + 4;
}
if (response)
sshbuf_free(response);
return r;
}
}
#pragma warning(pop)

View File

@ -33,6 +33,8 @@
#include "agent-request.h"
#include <sddl.h>
#pragma warning(push, 3)
#define MAX_KEY_LENGTH 255
#define MAX_VALUE_NAME 16383
@ -48,7 +50,7 @@ get_user_root(struct agent_connection* con, HKEY *root)
LONG ret;
*root = HKEY_LOCAL_MACHINE;
if (con->client_type == USER) {
if (con->client_type <= ADMIN_USER) {
if (ImpersonateNamedPipeClient(con->pipe_handle) == FALSE)
return -1;
*root = NULL;
@ -71,7 +73,7 @@ convert_blob(struct agent_connection* con, const char *blob, DWORD blen, char **
int success = 0;
DATA_BLOB in, out;
if (con->client_type == USER)
if (con->client_type <= ADMIN_USER)
if (ImpersonateNamedPipeClient(con->pipe_handle) == FALSE)
return -1;
@ -102,7 +104,7 @@ convert_blob(struct agent_connection* con, const char *blob, DWORD blen, char **
done:
if (out.pbData)
LocalFree(out.pbData);
if (con->client_type == USER)
if (con->client_type <= ADMIN_USER)
RevertToSelf();
return success? 0: -1;
}
@ -123,6 +125,7 @@ process_add_identity(struct sshbuf* request, struct sshbuf* response, struct age
SECURITY_ATTRIBUTES sa;
/* parse input request */
memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES));
blob = sshbuf_ptr(request);
if (sshkey_private_deserialize(request, &key) != 0 ||
(blob_len = (sshbuf_ptr(request) - blob) & 0xffffffff) == 0 ||
@ -142,9 +145,9 @@ process_add_identity(struct sshbuf* request, struct sshbuf* response, struct age
RegCreateKeyExW(user_root, SSH_KEYS_ROOT, 0, 0, 0, KEY_WRITE | KEY_WOW64_64KEY, &sa, &reg, NULL) != 0 ||
RegCreateKeyExA(reg, thumbprint, 0, 0, 0, KEY_WRITE | KEY_WOW64_64KEY, &sa, &sub, NULL) != 0 ||
RegSetValueExW(sub, NULL, 0, REG_BINARY, eblob, eblob_len) != 0 ||
RegSetValueExW(sub, L"pub", 0, REG_BINARY, pubkey_blob, pubkey_blob_len) != 0 ||
RegSetValueExW(sub, L"pub", 0, REG_BINARY, pubkey_blob, (DWORD)pubkey_blob_len) != 0 ||
RegSetValueExW(sub, L"type", 0, REG_DWORD, (BYTE*)&key->type, 4) != 0 ||
RegSetValueExW(sub, L"comment", 0, REG_BINARY, comment, comment_len) != 0 ) {
RegSetValueExW(sub, L"comment", 0, REG_BINARY, comment, (DWORD)comment_len) != 0 ) {
debug("failed to add key to store");
goto done;
}
@ -450,4 +453,6 @@ int process_keyagent_request(struct sshbuf* request, struct sshbuf* response, st
debug("unknown key agent request %d", type);
return -1;
}
}
}
#pragma warning(pop)

View File

@ -59,15 +59,9 @@ tty_make_modes(int fd, struct termios *tiop)
void (*put_arg)(Buffer *, u_int);
buffer_init(&buf);
if (compat20) {
tty_op_ospeed = TTY_OP_OSPEED_PROTO2;
tty_op_ispeed = TTY_OP_ISPEED_PROTO2;
put_arg = buffer_put_int;
} else {
tty_op_ospeed = TTY_OP_OSPEED_PROTO1;
tty_op_ispeed = TTY_OP_ISPEED_PROTO1;
put_arg = (void (*)(Buffer *, u_int)) buffer_put_char;
}
tty_op_ospeed = TTY_OP_OSPEED_PROTO2;
tty_op_ispeed = TTY_OP_ISPEED_PROTO2;
put_arg = buffer_put_int;
/* Store input and output baud rates. */
baud = 9600;
@ -93,10 +87,7 @@ tty_make_modes(int fd, struct termios *tiop)
end:
/* Mark end of mode data. */
buffer_put_char(&buf, TTY_OP_END);
if (compat20)
packet_put_string(buffer_ptr(&buf), buffer_len(&buf));
else
packet_put_raw(buffer_ptr(&buf), buffer_len(&buf));
packet_put_string(buffer_ptr(&buf), buffer_len(&buf));
buffer_free(&buf);
}
@ -116,16 +107,11 @@ tty_parse_modes(int fd, int *n_bytes_ptr)
u_int (*get_arg)(void);
int arg_size;
if (compat20) {
*n_bytes_ptr = packet_get_int();
if (*n_bytes_ptr == 0)
return;
get_arg = packet_get_int;
arg_size = 4;
} else {
get_arg = packet_get_char;
arg_size = 1;
}
*n_bytes_ptr = packet_get_int();
if (*n_bytes_ptr == 0)
return;
get_arg = packet_get_int;
arg_size = 4;
for (;;) {
n_bytes += 1;
@ -168,35 +154,7 @@ tty_parse_modes(int fd, int *n_bytes_ptr)
default:
debug("Ignoring unsupported tty mode opcode %d (0x%x)",
opcode, opcode);
if (!compat20) {
/*
* SSH1:
* Opcodes 1 to 127 are defined to have
* a one-byte argument.
* Opcodes 128 to 159 are defined to have
* an integer argument.
*/
if (opcode > 0 && opcode < 128) {
n_bytes += 1;
(void) packet_get_char();
break;
} else if (opcode >= 128 && opcode < 160) {
n_bytes += 4;
(void) packet_get_int();
break;
} else {
/*
* It is a truly undefined opcode (160 to 255).
* We have no idea about its arguments. So we
* must stop parsing. Note that some data
* may be left in the packet; hopefully there
* is nothing more coming after the mode data.
*/
logit("parse_tty_modes: unknown opcode %d",
opcode);
goto set;
}
} else {
{
/*
* SSH2:
* Opcodes 1 to 159 are defined to have

View File

@ -31,33 +31,27 @@
#include <Windows.h>
#include <Sddl.h>
#include <Aclapi.h>
#include <Ntsecapi.h>
#include <lm.h>
#include <stdio.h>
#include "inc\pwd.h"
#include "sshfileperm.h"
#include "misc_internal.h"
#include "debug.h"
#define SSHD_ACCOUNT L"NT Service\\sshd"
/*
* The function is to check if user prepresented by pw is secure to access to the file.
* Check the owner of the file is one of these types: Local Administrators groups, system account,
* direct user accounts in local administrators, or user represented by pw
* The function is to check if current user is secure to access to the file.
* Check the owner of the file is one of these types: Local Administrators groups, system account, current user account
* Check the users have access permission to the file don't voilate the following rules:
1. no user other than local administrators group, system account, user represented by pw,
and owner accounts have write permission on the file
2. sshd account can only have read permission
3. user represented by pw and file owner should at least have read permission.
1. no user other than local administrators group, system account, and pwd user have write permission on the file
2. sshd account can only have read permission
* Returns 0 on success and -1 on failure
*/
int
check_secure_file_permission(const char *name, struct passwd * pw)
{
return 0;
/*PSECURITY_DESCRIPTOR pSD = NULL;
{
PSECURITY_DESCRIPTOR pSD = NULL;
wchar_t * name_utf16 = NULL;
PSID owner_sid = NULL, user_sid = NULL;
PACL dacl = NULL;
@ -73,17 +67,18 @@ check_secure_file_permission(const char *name, struct passwd * pw)
if (ConvertStringSidToSid(pwd->pw_sid, &user_sid) == FALSE ||
(IsValidSid(user_sid) == FALSE)) {
debug3("failed to retrieve the sid of the pwd");
debug3("failed to retrieve sid of user %s", pwd->pw_name);
ret = -1;
goto cleanup;
}
if ((name_utf16 = utf8_to_utf16(name)) == NULL) {
ret = -1;
errno = ENOMEM;
goto cleanup;
}*/
}
/*Get the owner sid of the file.*/
/*if ((error_code = GetNamedSecurityInfoW(name_utf16, SE_FILE_OBJECT,
if ((error_code = GetNamedSecurityInfoW(name_utf16, SE_FILE_OBJECT,
OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
&owner_sid, NULL, &dacl, NULL, &pSD)) != ERROR_SUCCESS) {
debug3("failed to retrieve the owner sid and dacl of file %s with error code: %d", name, error_code);
@ -98,19 +93,17 @@ check_secure_file_permission(const char *name, struct passwd * pw)
}
if (!IsWellKnownSid(owner_sid, WinBuiltinAdministratorsSid) &&
!IsWellKnownSid(owner_sid, WinLocalSystemSid) &&
!EqualSid(owner_sid, user_sid) &&
!is_admin_account(owner_sid)) {
!EqualSid(owner_sid, user_sid)) {
debug3("Bad owner on %s", name);
ret = -1;
goto cleanup;
}*/
}
/*
iterate all aces of the file to find out if there is voilation of the following rules:
1. no others than administrators group, system account, and current user, owner accounts have write permission on the file
1. no others than administrators group, system account, and current user account have write permission on the file
2. sshd account can only have read permission
3. this user and file owner should at least have read permission
*/
/*for (DWORD i = 0; i < dacl->AceCount; i++) {
for (DWORD i = 0; i < dacl->AceCount; i++) {
PVOID current_ace = NULL;
PACE_HEADER current_aceHeader = NULL;
PSID current_trustee_sid = NULL;
@ -124,43 +117,18 @@ check_secure_file_permission(const char *name, struct passwd * pw)
}
current_aceHeader = (PACE_HEADER)current_ace;
// Determine the location of the trustee's sid and the value of the access mask
switch (current_aceHeader->AceType) {
case ACCESS_ALLOWED_ACE_TYPE: {
PACCESS_ALLOWED_ACE pAllowedAce = (PACCESS_ALLOWED_ACE)current_ace;
current_trustee_sid = &(pAllowedAce->SidStart);
current_access_mask = pAllowedAce->Mask;
break;
}
case ACCESS_DENIED_ACE_TYPE: {
PACCESS_DENIED_ACE pDeniedAce = (PACCESS_DENIED_ACE)current_ace;
current_trustee_sid = &(pDeniedAce->SidStart);
if((pDeniedAce->Mask & (FILE_GENERIC_READ & ~(SYNCHRONIZE | READ_CONTROL))) != 0) {
if (EqualSid(current_trustee_sid, owner_sid)){
debug3("Bad permission on %s. The owner of the file should at least have read permission.", name);
ret = -1;
goto cleanup;
}
else if (EqualSid(current_trustee_sid, user_sid)) {
debug3("Bad permission on %s. The user should at least have read permission.", name);
ret = -1;
goto cleanup;
}
}
/* only interested in Allow ACE */
if(current_aceHeader->AceType != ACCESS_ALLOWED_ACE_TYPE)
continue;
}
default: {
// Not interested ACE
continue;
}
}*/
/*no need to check administrators group, owner account, user account and system account*/
/*if (IsWellKnownSid(current_trustee_sid, WinBuiltinAdministratorsSid) ||
PACCESS_ALLOWED_ACE pAllowedAce = (PACCESS_ALLOWED_ACE)current_ace;
current_trustee_sid = &(pAllowedAce->SidStart);
current_access_mask = pAllowedAce->Mask;
/*no need to check administrators group, pwd user account, and system account*/
if (IsWellKnownSid(current_trustee_sid, WinBuiltinAdministratorsSid) ||
IsWellKnownSid(current_trustee_sid, WinLocalSystemSid) ||
EqualSid(current_trustee_sid, owner_sid) ||
EqualSid(current_trustee_sid, user_sid) ||
is_admin_account(current_trustee_sid)) {
EqualSid(current_trustee_sid, user_sid)) {
continue;
}
else if(is_sshd_account(current_trustee_sid)){
@ -186,12 +154,13 @@ cleanup:
if (pSD)
LocalFree(pSD);
if (user_sid)
FreeSid(user_sid);
LocalFree(user_sid);
if(name_utf16)
free(name_utf16);
return ret;*/
return ret;
}
/*TODO: optimize to get sshd sid first and then call EqualSid*/
static BOOL
is_sshd_account(PSID user_sid) {
wchar_t user_name[UNCLEN], full_name[UNCLEN + DNLEN + 2];
@ -210,145 +179,3 @@ is_sshd_account(PSID user_sid) {
wmemcpy(full_name + domain_name_length + 1, user_name, wcslen(user_name)+1);
return (wcsicmp(full_name, SSHD_ACCOUNT) == 0);
}
/*
* Check if the user is in local administrators group
* currently only check if the user is directly in the group
* Returns TRUE if the user is in administrators group; otherwise false;
*/
static BOOL
is_admin_account(PSID user_sid)
{
DWORD entries_read = 0, total_entries = 0, i = 0, name_length = UNCLEN, domain_name_length = DNLEN, sid_size;
LPLOCALGROUP_MEMBERS_INFO_1 local_groups_member_info = NULL;
char admins_sid[SECURITY_MAX_SID_SIZE];
wchar_t admins_group_name[UNCLEN], domain_name[DNLEN];
SID_NAME_USE sid_type = SidTypeInvalid;
NET_API_STATUS status;
BOOL ret = FALSE;
if (CreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, admins_sid, &sid_size) == FALSE) {
debug3("CreateWellKnownSid failed with error code: %d.", GetLastError());
goto done;
}
if (LookupAccountSidLocalW(admins_sid, admins_group_name, &name_length,
domain_name, &domain_name_length, &sid_type) == FALSE) {
debug3("LookupAccountSidLocalW() failed with error: %d. ", GetLastError());
errno = ENOENT;
goto done;
}
status = NetLocalGroupGetMembers(NULL, admins_group_name, 1, (LPBYTE*)&local_groups_member_info,
MAX_PREFERRED_LENGTH, &entries_read, &total_entries, NULL);
if (status != NERR_Success) {
debug3("NetLocalGroupGetMembers failed with error code: %d.", status);
goto done;
}
for (i = 0; i < entries_read; i++) {
if (local_groups_member_info[i].lgrmi1_sidusage == SidTypeDeletedAccount)
continue;
else if (EqualSid(local_groups_member_info[i].lgrmi1_sid, user_sid)) {
ret = TRUE;
break;
}
}
done:
if (local_groups_member_info)
NetApiBufferFree(local_groups_member_info);
return ret;
}
/*
* Set the owner of the secure file to the user represented by pw and only grant
* it the full control access
*/
int
set_secure_file_permission(const char *name, struct passwd * pw)
{
return 0;
/*PSECURITY_DESCRIPTOR pSD = NULL;
PSID owner_sid = NULL;
PACL dacl = NULL;
wchar_t *name_utf16 = NULL, *sid_utf16 = NULL, sddl[256];
DWORD error_code = ERROR_SUCCESS;
struct passwd * pwd = pw;
BOOL present, defaulted;
int ret = 0;
if (pwd == NULL)
if ((pwd = getpwuid(0)) == NULL)
fatal("getpwuid failed.");
if (ConvertStringSidToSid(pwd->pw_sid, &owner_sid) == FALSE) {
debug3("failed to retrieve the sid of the pwd with error code: %d", GetLastError());
ret = -1;
goto cleanup;
}
if((IsValidSid(owner_sid) == FALSE)) {
debug3("IsValidSid(owner_sid): FALSE");
ret = -1;
goto cleanup;
}
if ((sid_utf16 = utf8_to_utf16(pwd->pw_sid)) == NULL) {
debug3("Failed to get utf16 of the sid string");
errno = ENOMEM;
ret = -1;
goto cleanup;
}
swprintf(sddl, sizeof(sddl) - 1, L"D:P(A;;FA;;;%s)", sid_utf16);
if(ConvertStringSecurityDescriptorToSecurityDescriptorW(sddl, SDDL_REVISION, &pSD, NULL) == FALSE) {
debug3("ConvertStringSecurityDescriptorToSecurityDescriptorW failed with error code %d", GetLastError());
ret = -1;
goto cleanup;
}
if (IsValidSecurityDescriptor(pSD) == FALSE) {
debug3("IsValidSecurityDescriptor return FALSE");
ret = -1;
goto cleanup;
}
if (GetSecurityDescriptorDacl(pSD, &present, &dacl, &defaulted) == FALSE) {
debug3("GetSecurityDescriptorDacl failed with error code %d", GetLastError());
ret = -1;
goto cleanup;
}
if (!present || dacl == NULL) {
debug3("failed to find the acl from security descriptior.");
ret = -1;
goto cleanup;
}
if ((name_utf16 = utf8_to_utf16(name)) == NULL) {
debug3("Failed to get utf16 of the name");
errno = ENOMEM;
ret = -1;
goto cleanup;
}*/
/*Set the owner sid and acl of the file.*/
/*if ((error_code = SetNamedSecurityInfoW(name_utf16, SE_FILE_OBJECT,
OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION,
owner_sid, NULL, dacl, NULL)) != ERROR_SUCCESS) {
debug3("failed to set the owner sid and dacl of file %s with error code: %d", name, error_code);
errno = EOTHER;
ret = -1;
goto cleanup;
}
cleanup:
if (pSD)
LocalFree(pSD);
if (name_utf16)
free(name_utf16);
if(sid_utf16)
free(sid_utf16);
if (owner_sid)
FreeSid(owner_sid);
return ret;*/
}

View File

@ -387,16 +387,24 @@ w32_pipe(int *pfds)
}
int
w32_open(const char *pathname, int flags, ...)
w32_open(const char *pathname, int flags, ... /* arg */)
{
int min_index = fd_table_get_min_index();
struct w32_io* pio;
va_list valist;
u_short mode = 0;
errno = 0;
if (min_index == -1)
return -1;
if (flags & O_CREAT) {
va_start(valist, flags);
mode = va_arg(valist, u_short);
va_end(valist);
}
pio = fileio_open(sanitized_path(pathname), flags, 0);
pio = fileio_open(sanitized_path(pathname), flags, mode);
if (pio == NULL)
return -1;
@ -607,12 +615,10 @@ w32_select(int fds, w32_fd_set* readfds, w32_fd_set* writefds, w32_fd_set* excep
}
/* TODO - see if this needs to be supported */
/* if (exceptfds) {
errno = EOPNOTSUPP;
debug3("select - ERROR: exceptfds not supported");
DebugBreak();
return -1;
} */
if (exceptfds) {
for (i = 0; i < fds; i++)
FD_CLR(i, exceptfds);
}
if (readfds) {
for (i = 0; i < fds; i++)
@ -691,7 +697,6 @@ w32_select(int fds, w32_fd_set* readfds, w32_fd_set* writefds, w32_fd_set* excep
}
}
/* timeout specified and both fields are 0 - polling mode*/
/* proceed with further wait if not in polling mode*/
if ((timeout == NULL) || (timeout_ms != 0))
@ -738,26 +743,31 @@ w32_select(int fds, w32_fd_set* readfds, w32_fd_set* writefds, w32_fd_set* excep
/* clear out fds that are not ready yet */
if (readfds)
for (i = 0; i < fds; i++)
if (FD_ISSET(i, readfds) && (!FD_ISSET(i, &read_ready_fds)))
FD_CLR(i, readfds);
if (FD_ISSET(i, readfds)) {
if (FD_ISSET(i, &read_ready_fds)) {
/* for connect() initiated sockets finish WSA connect process*/
if ((fd_table.w32_ios[i]->type == SOCK_FD) &&
((fd_table.w32_ios[i]->internal.state == SOCK_CONNECTING)))
if (socketio_finish_connect(fd_table.w32_ios[i]) != 0) {
/* async connect failed, error will be picked up by recv or send */
errno = 0;
}
} else
FD_CLR(i, readfds);
}
if (writefds)
for (i = 0; i < fds; i++)
if (FD_ISSET(i, writefds)) {
if (FD_ISSET(i, &write_ready_fds)) {
/* for connect() completed sockets finish WSA connect process*/
/* for connect() initiated sockets finish WSA connect process*/
if ((fd_table.w32_ios[i]->type == SOCK_FD) &&
((fd_table.w32_ios[i]->internal.state == SOCK_CONNECTING)))
if (socketio_finish_connect(fd_table.w32_ios[i]) != 0) {
/* finalizeing connect failed - recored error */
/* error gets picked up later recv and/or send*/
fd_table.w32_ios[i]->read_details.error = errno;
fd_table.w32_ios[i]->write_details.error = errno;
fd_table.w32_ios[i]->internal.state = SOCK_CONNECTED;
/* async connect failed, error will be picked up by recv or send */
errno = 0;
}
}
else
} else
FD_CLR(i, writefds);
}
@ -847,6 +857,9 @@ w32_allocate_fd_for_handle(HANDLE h, BOOL is_sock)
pio->type = is_sock ? SOCK_FD : NONSOCK_FD;
pio->handle = h;
/* TODO - get socket state and confirm that its connected */
pio->internal.state = SOCK_READY;
fd_table_set(pio, min_index);
return min_index;
}

View File

@ -60,9 +60,8 @@ enum w32_io_type {
enum w32_io_sock_state {
SOCK_INITIALIZED = 0,
SOCK_LISTENING = 1, /*listen called on socket*/
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*/
SOCK_CONNECTING = 2, /*connect called on socket, connect is in progress*/
SOCK_READY = 3 /*recv and send can be done*/
};
/*
@ -145,7 +144,7 @@ int fileio_close(struct w32_io* pio);
int fileio_pipe(struct w32_io* pio[2]);
struct w32_io* fileio_afunix_socket();
int fileio_connect(struct w32_io*, char*);
struct w32_io* fileio_open(const char *pathname, int flags, int mode);
struct w32_io* fileio_open(const char *pathname, int flags, u_short mode);
int fileio_read(struct w32_io* pio, void *dst, unsigned int max);
int fileio_write(struct w32_io* pio, const void *buf, unsigned int max);
int fileio_fstat(struct w32_io* pio, struct _stat64 *buf);

View File

@ -42,8 +42,54 @@ struct DIR_ {
intptr_t hFile;
struct _wfinddata_t c_file;
int first;
wchar_t * nextdisk;
};
#define ATTR_ROOTDIR UINT_MAX
/* Enumerate all devices which have drive name.
Return a DIR stream on the root directory, or NULL if it could not be enumerated. */
DIR *
openrootdir(const char *name)
{
int hr = 0;
DWORD dw;
DIR * pdir;
struct _wfinddata_t c_file = {0};
wchar_t * p;
dw = GetLogicalDriveStringsW(_countof(c_file.name) - 2, c_file.name);
if (!dw) {
errno = ENODEV;
return NULL;
}
c_file.attrib = ATTR_ROOTDIR;
c_file.size = 0;
p = c_file.name;
while (*p) {
size_t len = wcslen(p);
if (len == 0)
break;
p += len + 1;
c_file.size++;
}
if (c_file.size == 0) {
errno = ENODEV;
return NULL;
}
pdir = malloc(sizeof(DIR));
if (!pdir) {
errno = ENOMEM;
return NULL;
}
memset(pdir, 0, sizeof(DIR));
pdir->hFile = 0;
memcpy(&pdir->c_file, &c_file, sizeof(c_file));
pdir->first = 1;
return pdir;
}
/* Open a directory stream on NAME.
Return a DIR stream on the directory, or NULL if it could not be opened. */
DIR *
@ -55,14 +101,31 @@ opendir(const char *name)
wchar_t searchstr[PATH_MAX];
wchar_t* wname = NULL;
int needed;
size_t len;
/* Detect root dir */
if (name && strcmp(name, "/") == 0)
return openrootdir(name);
if ((wname = utf8_to_utf16(sanitized_path(name))) == NULL) {
errno = ENOMEM;
return NULL;
}
convertToBackslashW(wname);
len = wcslen(wname);
if (len && wname[len-1] == L'\\') {
len--;
wname[len] = 0;
}
if (len >= PATH_MAX) {
free(wname);
errno = ENAMETOOLONG;
return NULL;
}
/* add *.* for Windows _findfirst() search pattern */
swprintf_s(searchstr, PATH_MAX, L"%s\\*.*", wname);
swprintf_s(searchstr, _countof(searchstr) - 1, L"%s\\*.*", wname);
free(wname);
if ((hFile = _wfindfirst(searchstr, &c_file)) == -1L)
@ -88,15 +151,73 @@ opendir(const char *name)
int
closedir(DIR *dirp)
{
if(!dirp) return -1;
if (dirp && (dirp->hFile)) {
_findclose(dirp->hFile);
dirp->hFile = 0;
free(dirp);
}
free(dirp);
return 0;
}
/* Read a root directory entry from DIRP.
Return a pointer to a `struct dirent' describing the entry,
or NULL for EOF or error. The storage returned may be overwritten
by a later readdir call on the same DIR stream. */
struct dirent *
readrootdir(DIR * dirp)
{
wchar_t * p;
size_t len = 0;
struct dirent *pdirentry;
UINT dt;
ULARGE_INTEGER totalNumberOfBytes;
BOOL x;
if (dirp->c_file.size <= 0) {
errno = ENODATA;
return NULL;
}
if (dirp->first) {
dirp->first = 0;
dirp->nextdisk = dirp->c_file.name;
}
p = dirp->nextdisk;
for ( ; ; p += len + 1) {
len = wcslen(p);
if (len == 0) {
dirp->nextdisk = p;
errno = ENODATA;
return NULL; /* end of multi-string */
}
dt = GetDriveTypeW(p);
if (dt == DRIVE_UNKNOWN || dt == DRIVE_NO_ROOT_DIR || dt == DRIVE_RAMDISK)
continue;
x = GetDiskFreeSpaceExW(p, NULL, &totalNumberOfBytes, NULL);
if (!x || totalNumberOfBytes.QuadPart == 0)
continue;
break; // process filtered disk
}
dirp->nextdisk = p + len + 1;
if ((pdirentry = malloc(sizeof(struct dirent))) == NULL) {
errno = ENOMEM;
return NULL;
}
pdirentry->d_name[0] = (char)p[0];
pdirentry->d_name[1] = ':';
pdirentry->d_name[2] = 0;
pdirentry->d_ino = 1; // a fictious one like UNIX to say it is nonzero
return pdirentry;
}
/* Read a directory entry from DIRP.
Return a pointer to a `struct dirent' describing the entry,
or NULL for EOF or error. The storage returned may be overwritten
@ -104,11 +225,16 @@ closedir(DIR *dirp)
struct dirent *
readdir(void *avp)
{
if(!avp) return NULL;
static struct dirent pdirentry;
struct _wfinddata_t c_file;
DIR *dirp = (DIR *)avp;
char *tmp = NULL;
if (dirp->hFile == 0 && dirp->c_file.attrib == ATTR_ROOTDIR)
return readrootdir(dirp);
for (;;) {
if (dirp->first) {
memcpy(&c_file, &dirp->c_file, sizeof(c_file));
@ -124,7 +250,7 @@ readdir(void *avp)
return NULL;
}
strncpy(pdirentry.d_name, tmp, strlen(tmp) + 1);
strncpy(pdirentry.d_name, tmp, sizeof(pdirentry.d_name));
free(tmp);
pdirentry.d_ino = 1; /* a fictious one like UNIX to say it is nonzero */

View File

@ -39,10 +39,7 @@ pty_make_controlling_tty(int *ttyfd, const char *tty) {
void
pty_change_window_size(int ptyfd, u_int row, u_int col,
u_int xpixel, u_int ypixel) {
COORD coord;
coord.X = col;
coord.Y = 9999;
SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coord);
/* TODO - Need to implement*/
}

View File

@ -328,6 +328,28 @@ typedef unsigned int size_t;
#define SIZE_MAX SIZE_T_MAX
#endif
#ifndef INT32_MAX
# if (SIZEOF_INT == 4)
# define INT32_MAX INT_MAX
# elif (SIZEOF_LONG == 4)
# define INT32_MAX LONG_MAX
# else
# error "need INT32_MAX"
# endif
#endif
#ifndef INT64_MAX
# if (SIZEOF_INT == 8)
# define INT64_MAX INT_MAX
# elif (SIZEOF_LONG == 8)
# define INT64_MAX LONG_MAX
# elif (SIZEOF_LONG_LONG_INT == 8)
# define INT64_MAX LLONG_MAX
# else
# error "need INT64_MAX"
# endif
#endif
#ifndef HAVE_SSIZE_T
typedef int ssize_t;
# define HAVE_SSIZE_T

View File

@ -1,4 +1,4 @@
/* $OpenBSD: digest-libc.c,v 1.5 2015/05/05 02:48:17 jsg Exp $ */
/* $OpenBSD: digest-libc.c,v 1.6 2017/05/08 22:57:38 djm Exp $ */
/*
* Copyright (c) 2013 Damien Miller <djm@mindrot.org>
* Copyright (c) 2014 Markus Friedl. All rights reserved.
@ -68,16 +68,6 @@ const struct ssh_digest digests[SSH_DIGEST_MAX] = {
(md_update_fn *) MD5Update,
(md_final_fn *) MD5Final
},
{
SSH_DIGEST_RIPEMD160,
"RIPEMD160",
RMD160_BLOCK_LENGTH,
RMD160_DIGEST_LENGTH,
sizeof(RMD160_CTX),
(md_init_fn *) RMD160Init,
(md_update_fn *) RMD160Update,
(md_final_fn *) RMD160Final
},
{
SSH_DIGEST_SHA1,
"SHA1",

View File

@ -1,4 +1,4 @@
/* $OpenBSD: digest-openssl.c,v 1.6 2017/03/10 02:59:51 dtucker Exp $ */
/* $OpenBSD: digest-openssl.c,v 1.7 2017/05/08 22:57:38 djm Exp $ */
/*
* Copyright (c) 2013 Damien Miller <djm@mindrot.org>
*
@ -56,7 +56,6 @@ struct ssh_digest {
/* NB. Indexed directly by algorithm number */
const struct ssh_digest digests[] = {
{ SSH_DIGEST_MD5, "MD5", 16, EVP_md5 },
{ SSH_DIGEST_RIPEMD160, "RIPEMD160", 20, EVP_ripemd160 },
{ SSH_DIGEST_SHA1, "SHA1", 20, EVP_sha1 },
{ SSH_DIGEST_SHA256, "SHA256", 32, EVP_sha256 },
{ SSH_DIGEST_SHA384, "SHA384", 48, EVP_sha384 },

View File

@ -1,4 +1,4 @@
/* $OpenBSD: digest.h,v 1.7 2014/12/21 22:27:56 djm Exp $ */
/* $OpenBSD: digest.h,v 1.8 2017/05/08 22:57:38 djm Exp $ */
/*
* Copyright (c) 2013 Damien Miller <djm@mindrot.org>
*
@ -23,12 +23,11 @@
/* Digest algorithms */
#define SSH_DIGEST_MD5 0
#define SSH_DIGEST_RIPEMD160 1
#define SSH_DIGEST_SHA1 2
#define SSH_DIGEST_SHA256 3
#define SSH_DIGEST_SHA384 4
#define SSH_DIGEST_SHA512 5
#define SSH_DIGEST_MAX 6
#define SSH_DIGEST_SHA1 1
#define SSH_DIGEST_SHA256 2
#define SSH_DIGEST_SHA384 3
#define SSH_DIGEST_SHA512 4
#define SSH_DIGEST_MAX 5
struct sshbuf;
struct ssh_digest_ctx;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: dispatch.c,v 1.27 2015/05/01 07:10:01 djm Exp $ */
/* $OpenBSD: dispatch.c,v 1.29 2017/04/30 23:28:42 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@ -30,7 +30,6 @@
#include <signal.h>
#include <stdarg.h>
#include "ssh1.h"
#include "ssh2.h"
#include "log.h"
#include "dispatch.h"
@ -45,8 +44,6 @@ dispatch_protocol_error(int type, u_int32_t seq, void *ctx)
int r;
logit("dispatch_protocol_error: type %d seq %u", type, seq);
if (!compat20)
fatal("protocol error");
if ((r = sshpkt_start(ssh, SSH2_MSG_UNIMPLEMENTED)) != 0 ||
(r = sshpkt_put_u32(ssh, seq)) != 0 ||
(r = sshpkt_send(ssh)) != 0 ||

View File

@ -1,4 +1,4 @@
/* $OpenBSD: hostfile.c,v 1.68 2017/03/10 04:26:06 djm Exp $ */
/* $OpenBSD: hostfile.c,v 1.70 2017/04/30 23:18:44 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -346,16 +346,11 @@ check_hostkeys_by_key_or_type(struct hostkeys *hostkeys,
HostStatus end_return = HOST_NEW;
int want_cert = sshkey_is_cert(k);
HostkeyMarker want_marker = want_cert ? MRK_CA : MRK_NONE;
int proto = (k ? k->type : keytype) == KEY_RSA1 ? 1 : 2;
if (found != NULL)
*found = NULL;
for (i = 0; i < hostkeys->num_entries; i++) {
if (proto == 1 && hostkeys->entries[i].key->type != KEY_RSA1)
continue;
if (proto == 2 && hostkeys->entries[i].key->type == KEY_RSA1)
continue;
if (hostkeys->entries[i].marker != want_marker)
continue;
if (k == NULL) {
@ -490,13 +485,6 @@ host_delete(struct hostkey_foreach_line *l, void *_ctx)
return 0;
}
/* XXX might need a knob for this later */
/* Don't remove RSA1 keys */
if (l->key->type == KEY_RSA1) {
fprintf(ctx->out, "%s\n", l->line);
return 0;
}
/*
* If this line contains one of the keys that we will be
* adding later, then don't change it and mark the key for
@ -795,20 +783,7 @@ hostkeys_foreach(const char *path, hostkeys_foreach_fn *callback, void *ctx,
break;
}
if (!hostfile_read_key(&cp, &kbits, lineinfo.key)) {
#ifdef WITH_SSH1
sshkey_free(lineinfo.key);
lineinfo.key = sshkey_new(KEY_RSA1);
if (lineinfo.key == NULL) {
error("%s: sshkey_new fail", __func__);
r = SSH_ERR_ALLOC_FAIL;
break;
}
if (!hostfile_read_key(&cp, &kbits,
lineinfo.key))
goto bad;
#else
goto bad;
#endif
}
lineinfo.keytype = lineinfo.key->type;
lineinfo.comment = cp;
@ -823,12 +798,12 @@ hostkeys_foreach(const char *path, hostkeys_foreach_fn *callback, void *ctx,
lineinfo.keytype = sshkey_type_from_name(ktype);
/*
* Assume RSA1 if the first component is a short
* Assume legacy RSA1 if the first component is a short
* decimal number.
*/
if (lineinfo.keytype == KEY_UNSPEC && l < 8 &&
strspn(ktype, "0123456789") == l)
lineinfo.keytype = KEY_RSA1;
goto bad;
/*
* Check that something other than whitespace follows

43
kex.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: kex.c,v 1.131 2017/03/15 07:07:39 markus Exp $ */
/* $OpenBSD: kex.c,v 1.132 2017/04/30 23:10:43 djm Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
*
@ -980,47 +980,6 @@ kex_derive_keys_bn(struct ssh *ssh, u_char *hash, u_int hashlen,
}
#endif
#ifdef WITH_SSH1
int
derive_ssh1_session_id(BIGNUM *host_modulus, BIGNUM *server_modulus,
u_int8_t cookie[8], u_int8_t id[16])
{
u_int8_t hbuf[2048], sbuf[2048], obuf[SSH_DIGEST_MAX_LENGTH];
struct ssh_digest_ctx *hashctx = NULL;
size_t hlen, slen;
int r;
hlen = BN_num_bytes(host_modulus);
slen = BN_num_bytes(server_modulus);
if (hlen < (512 / 8) || (u_int)hlen > sizeof(hbuf) ||
slen < (512 / 8) || (u_int)slen > sizeof(sbuf))
return SSH_ERR_KEY_BITS_MISMATCH;
if (BN_bn2bin(host_modulus, hbuf) <= 0 ||
BN_bn2bin(server_modulus, sbuf) <= 0) {
r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
if ((hashctx = ssh_digest_start(SSH_DIGEST_MD5)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
if (ssh_digest_update(hashctx, hbuf, hlen) != 0 ||
ssh_digest_update(hashctx, sbuf, slen) != 0 ||
ssh_digest_update(hashctx, cookie, 8) != 0 ||
ssh_digest_final(hashctx, obuf, sizeof(obuf)) != 0) {
r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
memcpy(id, obuf, ssh_digest_bytes(SSH_DIGEST_MD5));
r = 0;
out:
ssh_digest_free(hashctx);
explicit_bzero(hbuf, sizeof(hbuf));
explicit_bzero(sbuf, sizeof(sbuf));
explicit_bzero(obuf, sizeof(obuf));
return r;
}
#endif
#if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH)
void

5
kex.h
View File

@ -1,4 +1,4 @@
/* $OpenBSD: kex.h,v 1.81 2016/09/28 21:44:52 djm Exp $ */
/* $OpenBSD: kex.h,v 1.82 2017/05/03 21:08:09 naddy Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@ -225,9 +225,6 @@ int kexc25519_shared_key(const u_char key[CURVE25519_SIZE],
__attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE)))
__attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE)));
int
derive_ssh1_session_id(BIGNUM *, BIGNUM *, u_int8_t[8], u_int8_t[16]);
#if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH)
void dump_digest(char *, u_char *, int);
#endif

View File

@ -1,4 +1,4 @@
/* $OpenBSD: kexgexc.c,v 1.23 2016/09/12 01:22:38 deraadt Exp $ */
/* $OpenBSD: kexgexc.c,v 1.24 2017/05/16 16:56:15 djm Exp $ */
/*
* Copyright (c) 2000 Niels Provos. All rights reserved.
* Copyright (c) 2001 Markus Friedl. All rights reserved.
@ -165,10 +165,6 @@ input_kex_dh_gex_reply(int type, u_int32_t seq, void *ctxt)
(r = sshkey_from_blob(server_host_key_blob, sbloblen,
&server_host_key)) != 0)
goto out;
if (server_host_key->type != kex->hostkey_type) {
r = SSH_ERR_KEY_TYPE_MISMATCH;
goto out;
}
if (server_host_key->type != kex->hostkey_type ||
(kex->hostkey_type == KEY_ECDSA &&
server_host_key->ecdsa_nid != kex->hostkey_nid)) {

35
log.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: log.c,v 1.49 2017/03/10 03:15:58 djm Exp $ */
/* $OpenBSD: log.c,v 1.50 2017/05/17 01:24:17 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -256,18 +256,7 @@ log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr)
argv0 = av0;
switch (level) {
case SYSLOG_LEVEL_QUIET:
case SYSLOG_LEVEL_FATAL:
case SYSLOG_LEVEL_ERROR:
case SYSLOG_LEVEL_INFO:
case SYSLOG_LEVEL_VERBOSE:
case SYSLOG_LEVEL_DEBUG1:
case SYSLOG_LEVEL_DEBUG2:
case SYSLOG_LEVEL_DEBUG3:
log_level = level;
break;
default:
if (log_change_level(level) != 0) {
fprintf(stderr, "Unrecognized internal syslog level code %d\n",
(int) level);
exit(1);
@ -340,13 +329,27 @@ log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr)
#endif
}
void
int
log_change_level(LogLevel new_log_level)
{
/* no-op if log_init has not been called */
if (argv0 == NULL)
return;
log_init(argv0, new_log_level, log_facility, log_on_stderr);
return 0;
switch (new_log_level) {
case SYSLOG_LEVEL_QUIET:
case SYSLOG_LEVEL_FATAL:
case SYSLOG_LEVEL_ERROR:
case SYSLOG_LEVEL_INFO:
case SYSLOG_LEVEL_VERBOSE:
case SYSLOG_LEVEL_DEBUG1:
case SYSLOG_LEVEL_DEBUG2:
case SYSLOG_LEVEL_DEBUG3:
log_level = new_log_level;
return 0;
default:
return -1;
}
}
int

4
log.h
View File

@ -1,4 +1,4 @@
/* $OpenBSD: log.h,v 1.21 2016/07/15 05:01:58 dtucker Exp $ */
/* $OpenBSD: log.h,v 1.22 2017/05/17 01:24:17 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -49,7 +49,7 @@ typedef enum {
typedef void (log_handler_fn)(LogLevel, const char *, void *);
void log_init(char *, LogLevel, SyslogFacility, int);
void log_change_level(LogLevel);
int log_change_level(LogLevel);
int log_is_on_stderr(void);
void log_redirect_stderr_to(const char *);

9
mac.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: mac.c,v 1.33 2016/07/08 03:44:42 djm Exp $ */
/* $OpenBSD: mac.c,v 1.34 2017/05/08 22:57:38 djm Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
*
@ -64,10 +64,6 @@ static const struct macalg macs[] = {
#endif
{ "hmac-md5", SSH_DIGEST, SSH_DIGEST_MD5, 0, 0, 0, 0 },
{ "hmac-md5-96", SSH_DIGEST, SSH_DIGEST_MD5, 96, 0, 0, 0 },
#ifdef HAVE_EVP_RIPEMD160
{ "hmac-ripemd160", SSH_DIGEST, SSH_DIGEST_RIPEMD160, 0, 0, 0, 0 },
{ "hmac-ripemd160@openssh.com", SSH_DIGEST, SSH_DIGEST_RIPEMD160, 0, 0, 0, 0 },
#endif
{ "umac-64@openssh.com", SSH_UMAC, 0, 0, 128, 64, 0 },
{ "umac-128@openssh.com", SSH_UMAC128, 0, 0, 128, 128, 0 },
@ -80,9 +76,6 @@ static const struct macalg macs[] = {
#endif
{ "hmac-md5-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_MD5, 0, 0, 0, 1 },
{ "hmac-md5-96-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_MD5, 96, 0, 0, 1 },
#ifdef HAVE_EVP_RIPEMD160
{ "hmac-ripemd160-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_RIPEMD160, 0, 0, 0, 1 },
#endif
{ "umac-64-etm@openssh.com", SSH_UMAC, 0, 0, 128, 64, 1 },
{ "umac-128-etm@openssh.com", SSH_UMAC128, 0, 0, 128, 128, 1 },

View File

@ -1,4 +1,4 @@
/* $OpenBSD: monitor_wrap.c,v 1.89 2016/08/13 17:47:41 markus Exp $ */
/* $OpenBSD: monitor_wrap.c,v 1.90 2017/05/17 01:24:17 djm Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* Copyright 2002 Markus Friedl <markus@openbsd.org>
@ -295,6 +295,7 @@ out:
#undef M_CP_STRARRAYOPT
copy_set_server_options(&options, newopts, 1);
log_change_level(options.log_level);
free(newopts);
buffer_free(&m);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: myproposal.h,v 1.54 2016/09/28 16:33:07 djm Exp $ */
/* $OpenBSD: myproposal.h,v 1.55 2017/05/07 23:13:42 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
@ -121,8 +121,7 @@
"aes128-ctr,aes192-ctr,aes256-ctr" \
AESGCM_CIPHER_MODES
#define KEX_CLIENT_ENCRYPT KEX_SERVER_ENCRYPT "," \
"aes128-cbc,aes192-cbc,aes256-cbc"
#define KEX_CLIENT_ENCRYPT KEX_SERVER_ENCRYPT
#define KEX_SERVER_MAC \
"umac-64-etm@openssh.com," \

309
nchan.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: nchan.c,v 1.63 2010/01/26 01:28:35 djm Exp $ */
/* $OpenBSD: nchan.c,v 1.65 2017/04/30 23:28:42 djm Exp $ */
/*
* Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved.
*
@ -33,7 +33,6 @@
#include <stdarg.h>
#include "openbsd-compat/sys-queue.h"
#include "ssh1.h"
#include "ssh2.h"
#include "buffer.h"
#include "packet.h"
@ -74,9 +73,6 @@
/*
* ACTIONS: should never update the channel states
*/
static void chan_send_ieof1(Channel *);
static void chan_send_oclose1(Channel *);
static void chan_send_close2(Channel *);
static void chan_send_eof2(Channel *);
static void chan_send_eow2(Channel *);
@ -96,6 +92,7 @@ chan_set_istate(Channel *c, u_int next)
istates[next]);
c->istate = next;
}
static void
chan_set_ostate(Channel *c, u_int next)
{
@ -106,34 +103,6 @@ chan_set_ostate(Channel *c, u_int next)
c->ostate = next;
}
/*
* SSH1 specific implementation of event functions
*/
static void
chan_rcvd_oclose1(Channel *c)
{
debug2("channel %d: rcvd oclose", c->self);
switch (c->istate) {
case CHAN_INPUT_WAIT_OCLOSE:
chan_set_istate(c, CHAN_INPUT_CLOSED);
break;
case CHAN_INPUT_OPEN:
chan_shutdown_read(c);
chan_send_ieof1(c);
chan_set_istate(c, CHAN_INPUT_CLOSED);
break;
case CHAN_INPUT_WAIT_DRAIN:
/* both local read_failed and remote write_failed */
chan_send_ieof1(c);
chan_set_istate(c, CHAN_INPUT_CLOSED);
break;
default:
error("channel %d: protocol error: rcvd_oclose for istate %d",
c->self, c->istate);
return;
}
}
void
chan_read_failed(Channel *c)
{
@ -149,6 +118,7 @@ chan_read_failed(Channel *c)
break;
}
}
void
chan_ibuf_empty(Channel *c)
{
@ -160,14 +130,9 @@ chan_ibuf_empty(Channel *c)
}
switch (c->istate) {
case CHAN_INPUT_WAIT_DRAIN:
if (compat20) {
if (!(c->flags & (CHAN_CLOSE_SENT|CHAN_LOCAL)))
chan_send_eof2(c);
chan_set_istate(c, CHAN_INPUT_CLOSED);
} else {
chan_send_ieof1(c);
chan_set_istate(c, CHAN_INPUT_WAIT_OCLOSE);
}
if (!(c->flags & (CHAN_CLOSE_SENT|CHAN_LOCAL)))
chan_send_eof2(c);
chan_set_istate(c, CHAN_INPUT_CLOSED);
break;
default:
error("channel %d: chan_ibuf_empty for istate %d",
@ -175,44 +140,7 @@ chan_ibuf_empty(Channel *c)
break;
}
}
static void
chan_rcvd_ieof1(Channel *c)
{
debug2("channel %d: rcvd ieof", c->self);
switch (c->ostate) {
case CHAN_OUTPUT_OPEN:
chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
break;
case CHAN_OUTPUT_WAIT_IEOF:
chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
break;
default:
error("channel %d: protocol error: rcvd_ieof for ostate %d",
c->self, c->ostate);
break;
}
}
static void
chan_write_failed1(Channel *c)
{
debug2("channel %d: write failed", c->self);
switch (c->ostate) {
case CHAN_OUTPUT_OPEN:
chan_shutdown_write(c);
chan_send_oclose1(c);
chan_set_ostate(c, CHAN_OUTPUT_WAIT_IEOF);
break;
case CHAN_OUTPUT_WAIT_DRAIN:
chan_shutdown_write(c);
chan_send_oclose1(c);
chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
break;
default:
error("channel %d: chan_write_failed for ostate %d",
c->self, c->ostate);
break;
}
}
void
chan_obuf_empty(Channel *c)
{
@ -225,8 +153,6 @@ chan_obuf_empty(Channel *c)
switch (c->ostate) {
case CHAN_OUTPUT_WAIT_DRAIN:
chan_shutdown_write(c);
if (!compat20)
chan_send_oclose1(c);
chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
break;
default:
@ -235,47 +161,90 @@ chan_obuf_empty(Channel *c)
break;
}
}
static void
chan_send_ieof1(Channel *c)
void
chan_rcvd_eow(Channel *c)
{
debug2("channel %d: send ieof", c->self);
debug2("channel %d: rcvd eow", c->self);
switch (c->istate) {
case CHAN_INPUT_OPEN:
case CHAN_INPUT_WAIT_DRAIN:
packet_start(SSH_MSG_CHANNEL_INPUT_EOF);
packet_put_int(c->remote_id);
packet_send();
break;
default:
error("channel %d: cannot send ieof for istate %d",
c->self, c->istate);
break;
}
}
static void
chan_send_oclose1(Channel *c)
{
debug2("channel %d: send oclose", c->self);
switch (c->ostate) {
case CHAN_OUTPUT_OPEN:
case CHAN_OUTPUT_WAIT_DRAIN:
buffer_clear(&c->output);
packet_start(SSH_MSG_CHANNEL_OUTPUT_CLOSE);
packet_put_int(c->remote_id);
packet_send();
break;
default:
error("channel %d: cannot send oclose for ostate %d",
c->self, c->ostate);
chan_shutdown_read(c);
chan_set_istate(c, CHAN_INPUT_CLOSED);
break;
}
}
/*
* the same for SSH2
*/
static void
chan_rcvd_close2(Channel *c)
chan_send_eof2(Channel *c)
{
debug2("channel %d: send eof", c->self);
switch (c->istate) {
case CHAN_INPUT_WAIT_DRAIN:
packet_start(SSH2_MSG_CHANNEL_EOF);
packet_put_int(c->remote_id);
packet_send();
c->flags |= CHAN_EOF_SENT;
break;
default:
error("channel %d: cannot send eof for istate %d",
c->self, c->istate);
break;
}
}
static void
chan_send_close2(Channel *c)
{
debug2("channel %d: send close", c->self);
if (c->ostate != CHAN_OUTPUT_CLOSED ||
c->istate != CHAN_INPUT_CLOSED) {
error("channel %d: cannot send close for istate/ostate %d/%d",
c->self, c->istate, c->ostate);
} else if (c->flags & CHAN_CLOSE_SENT) {
error("channel %d: already sent close", c->self);
} else {
packet_start(SSH2_MSG_CHANNEL_CLOSE);
packet_put_int(c->remote_id);
packet_send();
c->flags |= CHAN_CLOSE_SENT;
}
}
static void
chan_send_eow2(Channel *c)
{
debug2("channel %d: send eow", c->self);
if (c->ostate == CHAN_OUTPUT_CLOSED) {
error("channel %d: must not sent eow on closed output",
c->self);
return;
}
if (!(datafellows & SSH_NEW_OPENSSH))
return;
packet_start(SSH2_MSG_CHANNEL_REQUEST);
packet_put_int(c->remote_id);
packet_put_cstring("eow@openssh.com");
packet_put_char(0);
packet_send();
}
/* shared */
void
chan_rcvd_ieof(Channel *c)
{
debug2("channel %d: rcvd eof", c->self);
c->flags |= CHAN_EOF_RCVD;
if (c->ostate == CHAN_OUTPUT_OPEN)
chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN &&
buffer_len(&c->output) == 0 &&
!CHANNEL_EFD_OUTPUT_ACTIVE(c))
chan_obuf_empty(c);
}
void
chan_rcvd_oclose(Channel *c)
{
debug2("channel %d: rcvd close", c->self);
if (!(c->flags & CHAN_LOCAL)) {
@ -313,26 +282,7 @@ chan_rcvd_close2(Channel *c)
}
void
chan_rcvd_eow(Channel *c)
{
debug2("channel %d: rcvd eow", c->self);
switch (c->istate) {
case CHAN_INPUT_OPEN:
chan_shutdown_read(c);
chan_set_istate(c, CHAN_INPUT_CLOSED);
break;
}
}
static void
chan_rcvd_eof2(Channel *c)
{
debug2("channel %d: rcvd eof", c->self);
c->flags |= CHAN_EOF_RCVD;
if (c->ostate == CHAN_OUTPUT_OPEN)
chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
}
static void
chan_write_failed2(Channel *c)
chan_write_failed(Channel *c)
{
debug2("channel %d: write failed", c->self);
switch (c->ostate) {
@ -349,88 +299,6 @@ chan_write_failed2(Channel *c)
break;
}
}
static void
chan_send_eof2(Channel *c)
{
debug2("channel %d: send eof", c->self);
switch (c->istate) {
case CHAN_INPUT_WAIT_DRAIN:
packet_start(SSH2_MSG_CHANNEL_EOF);
packet_put_int(c->remote_id);
packet_send();
c->flags |= CHAN_EOF_SENT;
break;
default:
error("channel %d: cannot send eof for istate %d",
c->self, c->istate);
break;
}
}
static void
chan_send_close2(Channel *c)
{
debug2("channel %d: send close", c->self);
if (c->ostate != CHAN_OUTPUT_CLOSED ||
c->istate != CHAN_INPUT_CLOSED) {
error("channel %d: cannot send close for istate/ostate %d/%d",
c->self, c->istate, c->ostate);
} else if (c->flags & CHAN_CLOSE_SENT) {
error("channel %d: already sent close", c->self);
} else {
packet_start(SSH2_MSG_CHANNEL_CLOSE);
packet_put_int(c->remote_id);
packet_send();
c->flags |= CHAN_CLOSE_SENT;
}
}
static void
chan_send_eow2(Channel *c)
{
debug2("channel %d: send eow", c->self);
if (c->ostate == CHAN_OUTPUT_CLOSED) {
error("channel %d: must not sent eow on closed output",
c->self);
return;
}
if (!(datafellows & SSH_NEW_OPENSSH))
return;
packet_start(SSH2_MSG_CHANNEL_REQUEST);
packet_put_int(c->remote_id);
packet_put_cstring("eow@openssh.com");
packet_put_char(0);
packet_send();
}
/* shared */
void
chan_rcvd_ieof(Channel *c)
{
if (compat20)
chan_rcvd_eof2(c);
else
chan_rcvd_ieof1(c);
if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN &&
buffer_len(&c->output) == 0 &&
!CHANNEL_EFD_OUTPUT_ACTIVE(c))
chan_obuf_empty(c);
}
void
chan_rcvd_oclose(Channel *c)
{
if (compat20)
chan_rcvd_close2(c);
else
chan_rcvd_oclose1(c);
}
void
chan_write_failed(Channel *c)
{
if (compat20)
chan_write_failed2(c);
else
chan_write_failed1(c);
}
void
chan_mark_dead(Channel *c)
@ -447,10 +315,6 @@ chan_is_dead(Channel *c, int do_send)
}
if (c->istate != CHAN_INPUT_CLOSED || c->ostate != CHAN_OUTPUT_CLOSED)
return 0;
if (!compat20) {
debug2("channel %d: is dead", c->self);
return 1;
}
if ((datafellows & SSH_BUG_EXTEOF) &&
c->extended_usage == CHAN_EXTENDED_WRITE &&
c->efd != -1 &&
@ -488,7 +352,7 @@ static void
chan_shutdown_write(Channel *c)
{
buffer_clear(&c->output);
if (compat20 && c->type == SSH_CHANNEL_LARVAL)
if (c->type == SSH_CHANNEL_LARVAL)
return;
/* shutdown failure is allowed if write failed already */
debug2("channel %d: close_write", c->self);
@ -504,10 +368,11 @@ chan_shutdown_write(Channel *c)
c->self, c->wfd, strerror(errno));
}
}
static void
chan_shutdown_read(Channel *c)
{
if (compat20 && c->type == SSH_CHANNEL_LARVAL)
if (c->type == SSH_CHANNEL_LARVAL)
return;
debug2("channel %d: close_read", c->self);
if (c->sock != -1) {

View File

@ -74,16 +74,6 @@ ssh_packet_put_raw(struct ssh *ssh, const void *buf, u_int len)
fatal("%s: %s", __func__, ssh_err(r));
}
#ifdef WITH_SSH1
void
ssh_packet_put_bignum(struct ssh *ssh, BIGNUM * value)
{
int r;
if ((r = sshpkt_put_bignum1(ssh, value)) != 0)
fatal("%s: %s", __func__, ssh_err(r));
}
#endif
#ifdef WITH_OPENSSL
void
@ -150,16 +140,6 @@ ssh_packet_get_int64(struct ssh *ssh)
return val;
}
#ifdef WITH_SSH1
void
ssh_packet_get_bignum(struct ssh *ssh, BIGNUM * value)
{
int r;
if ((r = sshpkt_get_bignum1(ssh, value)) != 0)
fatal("%s: %s", __func__, ssh_err(r));
}
#endif
#ifdef WITH_OPENSSL
void

View File

@ -6,7 +6,6 @@ void ssh_packet_start(struct ssh *, u_char);
void ssh_packet_put_char(struct ssh *, int ch);
void ssh_packet_put_int(struct ssh *, u_int value);
void ssh_packet_put_int64(struct ssh *, u_int64_t value);
void ssh_packet_put_bignum(struct ssh *, BIGNUM * value);
void ssh_packet_put_bignum2(struct ssh *, BIGNUM * value);
void ssh_packet_put_ecpoint(struct ssh *, const EC_GROUP *, const EC_POINT *);
void ssh_packet_put_string(struct ssh *, const void *buf, u_int len);
@ -17,7 +16,6 @@ void ssh_packet_send(struct ssh *);
u_int ssh_packet_get_char(struct ssh *);
u_int ssh_packet_get_int(struct ssh *);
u_int64_t ssh_packet_get_int64(struct ssh *);
void ssh_packet_get_bignum(struct ssh *, BIGNUM * value);
void ssh_packet_get_bignum2(struct ssh *, BIGNUM * value);
void ssh_packet_get_ecpoint(struct ssh *, const EC_GROUP *, EC_POINT *);
void *ssh_packet_get_string(struct ssh *, u_int *length_ptr);
@ -62,8 +60,6 @@ void packet_read_expect(int expected_type);
ssh_packet_get_protocol_flags(active_state)
#define packet_start_compression(level) \
ssh_packet_start_compression(active_state, (level))
#define packet_set_encryption_key(key, keylen, number) \
ssh_packet_set_encryption_key(active_state, (key), (keylen), (number))
#define packet_start(type) \
ssh_packet_start(active_state, (type))
#define packet_put_char(value) \
@ -78,8 +74,6 @@ void packet_read_expect(int expected_type);
ssh_packet_put_cstring(active_state, (str))
#define packet_put_raw(buf, len) \
ssh_packet_put_raw(active_state, (buf), (len))
#define packet_put_bignum(value) \
ssh_packet_put_bignum(active_state, (value))
#define packet_put_bignum2(value) \
ssh_packet_put_bignum2(active_state, (value))
#define packet_send() \
@ -88,8 +82,6 @@ void packet_read_expect(int expected_type);
ssh_packet_read(active_state)
#define packet_get_int64() \
ssh_packet_get_int64(active_state)
#define packet_get_bignum(value) \
ssh_packet_get_bignum(active_state, (value))
#define packet_get_bignum2(value) \
ssh_packet_get_bignum2(active_state, (value))
#define packet_remaining() \

627
packet.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: packet.c,v 1.247 2017/03/11 13:07:35 markus Exp $ */
/* $OpenBSD: packet.c,v 1.256 2017/05/08 06:03:39 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -68,9 +68,7 @@
#include "xmalloc.h"
#include "crc32.h"
#include "deattack.h"
#include "compat.h"
#include "ssh1.h"
#include "ssh2.h"
#include "cipher.h"
#include "sshkey.h"
@ -186,10 +184,6 @@ struct session_state {
u_int32_t rekey_interval; /* how often in seconds */
time_t rekey_time; /* time of last rekeying */
/* Session key for protocol v1 */
u_char ssh1_key[SSH_SESSION_KEY_LENGTH];
u_int ssh1_keylen;
/* roundup current message to extra_pad bytes */
u_char extra_pad;
@ -216,9 +210,6 @@ struct session_state {
/* One-off warning about weak ciphers */
int cipher_warning_done;
/* SSH1 CRC compensation attack detector */
struct deattack_ctx deattack;
/* Hook for fuzzing inbound packets */
ssh_packet_hook_fn *hook_in;
void *hook_in_ctx;
@ -278,13 +269,12 @@ ssh_packet_set_input_hook(struct ssh *ssh, ssh_packet_hook_fn *hook, void *ctx)
int
ssh_packet_is_rekeying(struct ssh *ssh)
{
return compat20 &&
(ssh->state->rekeying || (ssh->kex != NULL && ssh->kex->done == 0));
return ssh->state->rekeying ||
(ssh->kex != NULL && ssh->kex->done == 0);
}
/*
* Sets the descriptors used for communication. Disables encryption until
* packet_set_encryption_key is called.
* Sets the descriptors used for communication.
*/
struct ssh *
ssh_packet_set_connection(struct ssh *ssh, int fd_in, int fd_out)
@ -315,7 +305,6 @@ ssh_packet_set_connection(struct ssh *ssh, int fd_in, int fd_out)
return NULL;
}
state->newkeys[MODE_IN] = state->newkeys[MODE_OUT] = NULL;
deattack_init(&state->deattack);
/*
* Cache the IP address of the remote connection for use in error
* messages that might be generated after the connection has closed.
@ -698,7 +687,7 @@ ssh_packet_start_compression(struct ssh *ssh, int level)
{
int r;
if (ssh->state->packet_compression && !compat20)
if (ssh->state->packet_compression)
return SSH_ERR_INTERNAL_ERROR;
ssh->state->packet_compression = 1;
if ((r = ssh_packet_init_compression(ssh)) != 0 ||
@ -802,138 +791,6 @@ uncompress_buffer(struct ssh *ssh, struct sshbuf *in, struct sshbuf *out)
/* NOTREACHED */
}
/*
* Causes any further packets to be encrypted using the given key. The same
* key is used for both sending and reception. However, both directions are
* encrypted independently of each other.
*/
void
ssh_packet_set_encryption_key(struct ssh *ssh, const u_char *key, u_int keylen, int number)
{
#ifndef WITH_SSH1
fatal("no SSH protocol 1 support");
#else /* WITH_SSH1 */
struct session_state *state = ssh->state;
const struct sshcipher *cipher = cipher_by_number(number);
int r;
const char *wmsg;
if (cipher == NULL)
fatal("%s: unknown cipher number %d", __func__, number);
if (keylen < 20)
fatal("%s: keylen too small: %d", __func__, keylen);
if (keylen > SSH_SESSION_KEY_LENGTH)
fatal("%s: keylen too big: %d", __func__, keylen);
memcpy(state->ssh1_key, key, keylen);
state->ssh1_keylen = keylen;
if ((r = cipher_init(&state->send_context, cipher, key, keylen,
NULL, 0, CIPHER_ENCRYPT)) != 0 ||
(r = cipher_init(&state->receive_context, cipher, key, keylen,
NULL, 0, CIPHER_DECRYPT) != 0))
fatal("%s: cipher_init failed: %s", __func__, ssh_err(r));
if (!state->cipher_warning_done &&
((wmsg = cipher_warning_message(state->send_context)) != NULL ||
(wmsg = cipher_warning_message(state->send_context)) != NULL)) {
error("Warning: %s", wmsg);
state->cipher_warning_done = 1;
}
#endif /* WITH_SSH1 */
}
/*
* Finalizes and sends the packet. If the encryption key has been set,
* encrypts the packet before sending.
*/
int
ssh_packet_send1(struct ssh *ssh)
{
struct session_state *state = ssh->state;
u_char buf[8], *cp;
int r, padding, len;
u_int checksum;
/*
* If using packet compression, compress the payload of the outgoing
* packet.
*/
if (state->packet_compression) {
sshbuf_reset(state->compression_buffer);
/* Skip padding. */
if ((r = sshbuf_consume(state->outgoing_packet, 8)) != 0)
goto out;
/* padding */
if ((r = sshbuf_put(state->compression_buffer,
"\0\0\0\0\0\0\0\0", 8)) != 0)
goto out;
if ((r = compress_buffer(ssh, state->outgoing_packet,
state->compression_buffer)) != 0)
goto out;
sshbuf_reset(state->outgoing_packet);
if ((r = sshbuf_putb(state->outgoing_packet,
state->compression_buffer)) != 0)
goto out;
}
/* Compute packet length without padding (add checksum, remove padding). */
len = sshbuf_len(state->outgoing_packet) + 4 - 8;
/* Insert padding. Initialized to zero in packet_start1() */
padding = 8 - len % 8;
if (!cipher_ctx_is_plaintext(state->send_context)) {
cp = sshbuf_mutable_ptr(state->outgoing_packet);
if (cp == NULL) {
r = SSH_ERR_INTERNAL_ERROR;
goto out;
}
arc4random_buf(cp + 8 - padding, padding);
}
if ((r = sshbuf_consume(state->outgoing_packet, 8 - padding)) != 0)
goto out;
/* Add check bytes. */
checksum = ssh_crc32(sshbuf_ptr(state->outgoing_packet),
sshbuf_len(state->outgoing_packet));
POKE_U32(buf, checksum);
if ((r = sshbuf_put(state->outgoing_packet, buf, 4)) != 0)
goto out;
#ifdef PACKET_DEBUG
fprintf(stderr, "packet_send plain: ");
sshbuf_dump(state->outgoing_packet, stderr);
#endif
/* Append to output. */
POKE_U32(buf, len);
if ((r = sshbuf_put(state->output, buf, 4)) != 0)
goto out;
if ((r = sshbuf_reserve(state->output,
sshbuf_len(state->outgoing_packet), &cp)) != 0)
goto out;
if ((r = cipher_crypt(state->send_context, 0, cp,
sshbuf_ptr(state->outgoing_packet),
sshbuf_len(state->outgoing_packet), 0, 0)) != 0)
goto out;
#ifdef PACKET_DEBUG
fprintf(stderr, "encrypted: ");
sshbuf_dump(state->output, stderr);
#endif
state->p_send.packets++;
state->p_send.bytes += len +
sshbuf_len(state->outgoing_packet);
sshbuf_reset(state->outgoing_packet);
/*
* Note that the packet is now only buffered in output. It won't be
* actually sent until ssh_packet_write_wait or ssh_packet_write_poll
* is called.
*/
r = 0;
out:
return r;
}
int
ssh_set_newkeys(struct ssh *ssh, int mode)
{
@ -1027,7 +884,7 @@ ssh_set_newkeys(struct ssh *ssh, int mode)
}
/*
* The 2^(blocksize*2) limit is too expensive for 3DES,
* blowfish, etc, so enforce a 1GB limit for small blocksizes.
* so enforce a 1GB limit for small blocksizes.
*/
if (enc->block_size >= 16)
*max_blocks = (u_int64_t)1 << (enc->block_size*2);
@ -1424,13 +1281,6 @@ ssh_packet_read_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)
r = ssh_packet_read_poll_seqnr(ssh, typep, seqnr_p);
if (r != 0)
break;
if (!compat20 && (
*typep == SSH_SMSG_SUCCESS
|| *typep == SSH_SMSG_FAILURE
|| *typep == SSH_CMSG_EOF
|| *typep == SSH_CMSG_EXIT_CONFIRMATION))
if ((r = sshpkt_get_end(ssh)) != 0)
break;
/* If we got a packet, return it. */
if (*typep != SSH_MSG_NONE)
break;
@ -1524,153 +1374,6 @@ ssh_packet_read_expect(struct ssh *ssh, u_int expected_type)
return 0;
}
/* Checks if a full packet is available in the data received so far via
* packet_process_incoming. If so, reads the packet; otherwise returns
* SSH_MSG_NONE. This does not wait for data from the connection.
*
* SSH_MSG_DISCONNECT is handled specially here. Also,
* SSH_MSG_IGNORE messages are skipped by this function and are never returned
* to higher levels.
*/
int
ssh_packet_read_poll1(struct ssh *ssh, u_char *typep)
{
struct session_state *state = ssh->state;
u_int len, padded_len;
const char *emsg;
const u_char *cp;
u_char *p;
u_int checksum, stored_checksum;
int r;
*typep = SSH_MSG_NONE;
/* Check if input size is less than minimum packet size. */
if (sshbuf_len(state->input) < 4 + 8)
return 0;
/* Get length of incoming packet. */
len = PEEK_U32(sshbuf_ptr(state->input));
if (len < 1 + 2 + 2 || len > 256 * 1024) {
if ((r = sshpkt_disconnect(ssh, "Bad packet length %u",
len)) != 0)
return r;
return SSH_ERR_CONN_CORRUPT;
}
padded_len = (len + 8) & ~7;
/* Check if the packet has been entirely received. */
if (sshbuf_len(state->input) < 4 + padded_len)
return 0;
/* The entire packet is in buffer. */
/* Consume packet length. */
if ((r = sshbuf_consume(state->input, 4)) != 0)
goto out;
/*
* Cryptographic attack detector for ssh
* (C)1998 CORE-SDI, Buenos Aires Argentina
* Ariel Futoransky(futo@core-sdi.com)
*/
if (!cipher_ctx_is_plaintext(state->receive_context)) {
emsg = NULL;
switch (detect_attack(&state->deattack,
sshbuf_ptr(state->input), padded_len)) {
case DEATTACK_OK:
break;
case DEATTACK_DETECTED:
emsg = "crc32 compensation attack detected";
break;
case DEATTACK_DOS_DETECTED:
emsg = "deattack denial of service detected";
break;
default:
emsg = "deattack error";
break;
}
if (emsg != NULL) {
error("%s", emsg);
if ((r = sshpkt_disconnect(ssh, "%s", emsg)) != 0 ||
(r = ssh_packet_write_wait(ssh)) != 0)
return r;
return SSH_ERR_CONN_CORRUPT;
}
}
/* Decrypt data to incoming_packet. */
sshbuf_reset(state->incoming_packet);
if ((r = sshbuf_reserve(state->incoming_packet, padded_len, &p)) != 0)
goto out;
if ((r = cipher_crypt(state->receive_context, 0, p,
sshbuf_ptr(state->input), padded_len, 0, 0)) != 0)
goto out;
if ((r = sshbuf_consume(state->input, padded_len)) != 0)
goto out;
#ifdef PACKET_DEBUG
fprintf(stderr, "read_poll plain: ");
sshbuf_dump(state->incoming_packet, stderr);
#endif
/* Compute packet checksum. */
checksum = ssh_crc32(sshbuf_ptr(state->incoming_packet),
sshbuf_len(state->incoming_packet) - 4);
/* Skip padding. */
if ((r = sshbuf_consume(state->incoming_packet, 8 - len % 8)) != 0)
goto out;
/* Test check bytes. */
if (len != sshbuf_len(state->incoming_packet)) {
error("%s: len %d != sshbuf_len %zd", __func__,
len, sshbuf_len(state->incoming_packet));
if ((r = sshpkt_disconnect(ssh, "invalid packet length")) != 0 ||
(r = ssh_packet_write_wait(ssh)) != 0)
return r;
return SSH_ERR_CONN_CORRUPT;
}
cp = sshbuf_ptr(state->incoming_packet) + len - 4;
stored_checksum = PEEK_U32(cp);
if (checksum != stored_checksum) {
error("Corrupted check bytes on input");
if ((r = sshpkt_disconnect(ssh, "connection corrupted")) != 0 ||
(r = ssh_packet_write_wait(ssh)) != 0)
return r;
return SSH_ERR_CONN_CORRUPT;
}
if ((r = sshbuf_consume_end(state->incoming_packet, 4)) < 0)
goto out;
if (state->packet_compression) {
sshbuf_reset(state->compression_buffer);
if ((r = uncompress_buffer(ssh, state->incoming_packet,
state->compression_buffer)) != 0)
goto out;
sshbuf_reset(state->incoming_packet);
if ((r = sshbuf_putb(state->incoming_packet,
state->compression_buffer)) != 0)
goto out;
}
state->p_read.packets++;
state->p_read.bytes += padded_len + 4;
if ((r = sshbuf_get_u8(state->incoming_packet, typep)) != 0)
goto out;
if (*typep < SSH_MSG_MIN || *typep > SSH_MSG_MAX) {
error("Invalid ssh1 packet type: %d", *typep);
if ((r = sshpkt_disconnect(ssh, "invalid packet type")) != 0 ||
(r = ssh_packet_write_wait(ssh)) != 0)
return r;
return SSH_ERR_PROTOCOL_ERROR;
}
r = 0;
out:
return r;
}
static int
ssh_packet_read_poll2_mux(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)
{
@ -1951,75 +1654,48 @@ ssh_packet_read_poll_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)
for (;;) {
msg = NULL;
if (compat20) {
r = ssh_packet_read_poll2(ssh, typep, seqnr_p);
if (r != 0)
r = ssh_packet_read_poll2(ssh, typep, seqnr_p);
if (r != 0)
return r;
if (*typep) {
state->keep_alive_timeouts = 0;
DBG(debug("received packet type %d", *typep));
}
switch (*typep) {
case SSH2_MSG_IGNORE:
debug3("Received SSH2_MSG_IGNORE");
break;
case SSH2_MSG_DEBUG:
if ((r = sshpkt_get_u8(ssh, NULL)) != 0 ||
(r = sshpkt_get_string(ssh, &msg, NULL)) != 0 ||
(r = sshpkt_get_string(ssh, NULL, NULL)) != 0) {
free(msg);
return r;
if (*typep) {
state->keep_alive_timeouts = 0;
DBG(debug("received packet type %d", *typep));
}
switch (*typep) {
case SSH2_MSG_IGNORE:
debug3("Received SSH2_MSG_IGNORE");
break;
case SSH2_MSG_DEBUG:
if ((r = sshpkt_get_u8(ssh, NULL)) != 0 ||
(r = sshpkt_get_string(ssh, &msg, NULL)) != 0 ||
(r = sshpkt_get_string(ssh, NULL, NULL)) != 0) {
free(msg);
return r;
}
debug("Remote: %.900s", msg);
free(msg);
break;
case SSH2_MSG_DISCONNECT:
if ((r = sshpkt_get_u32(ssh, &reason)) != 0 ||
(r = sshpkt_get_string(ssh, &msg, NULL)) != 0)
return r;
/* Ignore normal client exit notifications */
do_log2(ssh->state->server_side &&
reason == SSH2_DISCONNECT_BY_APPLICATION ?
SYSLOG_LEVEL_INFO : SYSLOG_LEVEL_ERROR,
"Received disconnect from %s port %d:"
"%u: %.400s", ssh_remote_ipaddr(ssh),
ssh_remote_port(ssh), reason, msg);
free(msg);
return SSH_ERR_DISCONNECTED;
case SSH2_MSG_UNIMPLEMENTED:
if ((r = sshpkt_get_u32(ssh, &seqnr)) != 0)
return r;
debug("Received SSH2_MSG_UNIMPLEMENTED for %u",
seqnr);
break;
default:
return 0;
}
} else {
r = ssh_packet_read_poll1(ssh, typep);
switch (*typep) {
case SSH_MSG_NONE:
return SSH_MSG_NONE;
case SSH_MSG_IGNORE:
break;
case SSH_MSG_DEBUG:
if ((r = sshpkt_get_string(ssh, &msg, NULL)) != 0)
return r;
debug("Remote: %.900s", msg);
free(msg);
break;
case SSH_MSG_DISCONNECT:
if ((r = sshpkt_get_string(ssh, &msg, NULL)) != 0)
return r;
error("Received disconnect from %s port %d: "
"%.400s", ssh_remote_ipaddr(ssh),
ssh_remote_port(ssh), msg);
free(msg);
return SSH_ERR_DISCONNECTED;
default:
DBG(debug("received packet type %d", *typep));
return 0;
}
debug("Remote: %.900s", msg);
free(msg);
break;
case SSH2_MSG_DISCONNECT:
if ((r = sshpkt_get_u32(ssh, &reason)) != 0 ||
(r = sshpkt_get_string(ssh, &msg, NULL)) != 0)
return r;
/* Ignore normal client exit notifications */
do_log2(ssh->state->server_side &&
reason == SSH2_DISCONNECT_BY_APPLICATION ?
SYSLOG_LEVEL_INFO : SYSLOG_LEVEL_ERROR,
"Received disconnect from %s port %d:"
"%u: %.400s", ssh_remote_ipaddr(ssh),
ssh_remote_port(ssh), reason, msg);
free(msg);
return SSH_ERR_DISCONNECTED;
case SSH2_MSG_UNIMPLEMENTED:
if ((r = sshpkt_get_u32(ssh, &seqnr)) != 0)
return r;
debug("Received SSH2_MSG_UNIMPLEMENTED for %u",
seqnr);
break;
default:
return 0;
}
}
}
@ -2071,27 +1747,19 @@ ssh_packet_send_debug(struct ssh *ssh, const char *fmt,...)
va_list args;
int r;
if (compat20 && (ssh->compat & SSH_BUG_DEBUG))
if ((ssh->compat & SSH_BUG_DEBUG))
return;
va_start(args, fmt);
vsnprintf(buf, sizeof(buf), fmt, args);
va_end(args);
if (compat20) {
if ((r = sshpkt_start(ssh, SSH2_MSG_DEBUG)) != 0 ||
(r = sshpkt_put_u8(ssh, 0)) != 0 || /* always display */
(r = sshpkt_put_cstring(ssh, buf)) != 0 ||
(r = sshpkt_put_cstring(ssh, "")) != 0 ||
(r = sshpkt_send(ssh)) != 0)
fatal("%s: %s", __func__, ssh_err(r));
} else {
if ((r = sshpkt_start(ssh, SSH_MSG_DEBUG)) != 0 ||
(r = sshpkt_put_cstring(ssh, buf)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
fatal("%s: %s", __func__, ssh_err(r));
}
if ((r = ssh_packet_write_wait(ssh)) != 0)
if ((r = sshpkt_start(ssh, SSH2_MSG_DEBUG)) != 0 ||
(r = sshpkt_put_u8(ssh, 0)) != 0 || /* always display */
(r = sshpkt_put_cstring(ssh, buf)) != 0 ||
(r = sshpkt_put_cstring(ssh, "")) != 0 ||
(r = sshpkt_send(ssh)) != 0 ||
(r = ssh_packet_write_wait(ssh)) != 0)
fatal("%s: %s", __func__, ssh_err(r));
}
@ -2412,8 +2080,7 @@ ssh_packet_send_ignore(struct ssh *ssh, int nbytes)
u_int32_t rnd = 0;
int r, i;
if ((r = sshpkt_start(ssh, compat20 ?
SSH2_MSG_IGNORE : SSH_MSG_IGNORE)) != 0 ||
if ((r = sshpkt_start(ssh, SSH2_MSG_IGNORE)) != 0 ||
(r = sshpkt_put_u32(ssh, nbytes)) != 0)
fatal("%s: %s", __func__, ssh_err(r));
for (i = 0; i < nbytes; i++) {
@ -2556,54 +2223,22 @@ int
ssh_packet_get_state(struct ssh *ssh, struct sshbuf *m)
{
struct session_state *state = ssh->state;
u_char *p;
size_t slen, rlen;
int r, ssh1cipher;
int r;
if (!compat20) {
ssh1cipher = cipher_ctx_get_number(state->receive_context);
slen = cipher_get_keyiv_len(state->send_context);
rlen = cipher_get_keyiv_len(state->receive_context);
if ((r = sshbuf_put_u32(m, state->remote_protocol_flags)) != 0 ||
(r = sshbuf_put_u32(m, ssh1cipher)) != 0 ||
(r = sshbuf_put_string(m, state->ssh1_key, state->ssh1_keylen)) != 0 ||
(r = sshbuf_put_u32(m, slen)) != 0 ||
(r = sshbuf_reserve(m, slen, &p)) != 0 ||
(r = cipher_get_keyiv(state->send_context, p, slen)) != 0 ||
(r = sshbuf_put_u32(m, rlen)) != 0 ||
(r = sshbuf_reserve(m, rlen, &p)) != 0 ||
(r = cipher_get_keyiv(state->receive_context, p, rlen)) != 0)
return r;
} else {
if ((r = kex_to_blob(m, ssh->kex)) != 0 ||
(r = newkeys_to_blob(m, ssh, MODE_OUT)) != 0 ||
(r = newkeys_to_blob(m, ssh, MODE_IN)) != 0 ||
(r = sshbuf_put_u64(m, state->rekey_limit)) != 0 ||
(r = sshbuf_put_u32(m, state->rekey_interval)) != 0 ||
(r = sshbuf_put_u32(m, state->p_send.seqnr)) != 0 ||
(r = sshbuf_put_u64(m, state->p_send.blocks)) != 0 ||
(r = sshbuf_put_u32(m, state->p_send.packets)) != 0 ||
(r = sshbuf_put_u64(m, state->p_send.bytes)) != 0 ||
(r = sshbuf_put_u32(m, state->p_read.seqnr)) != 0 ||
(r = sshbuf_put_u64(m, state->p_read.blocks)) != 0 ||
(r = sshbuf_put_u32(m, state->p_read.packets)) != 0 ||
(r = sshbuf_put_u64(m, state->p_read.bytes)) != 0)
return r;
}
slen = cipher_get_keycontext(state->send_context, NULL);
rlen = cipher_get_keycontext(state->receive_context, NULL);
if ((r = sshbuf_put_u32(m, slen)) != 0 ||
(r = sshbuf_reserve(m, slen, &p)) != 0)
return r;
if (cipher_get_keycontext(state->send_context, p) != (int)slen)
return SSH_ERR_INTERNAL_ERROR;
if ((r = sshbuf_put_u32(m, rlen)) != 0 ||
(r = sshbuf_reserve(m, rlen, &p)) != 0)
return r;
if (cipher_get_keycontext(state->receive_context, p) != (int)rlen)
return SSH_ERR_INTERNAL_ERROR;
if ((r = sshbuf_put_stringb(m, state->input)) != 0 ||
if ((r = kex_to_blob(m, ssh->kex)) != 0 ||
(r = newkeys_to_blob(m, ssh, MODE_OUT)) != 0 ||
(r = newkeys_to_blob(m, ssh, MODE_IN)) != 0 ||
(r = sshbuf_put_u64(m, state->rekey_limit)) != 0 ||
(r = sshbuf_put_u32(m, state->rekey_interval)) != 0 ||
(r = sshbuf_put_u32(m, state->p_send.seqnr)) != 0 ||
(r = sshbuf_put_u64(m, state->p_send.blocks)) != 0 ||
(r = sshbuf_put_u32(m, state->p_send.packets)) != 0 ||
(r = sshbuf_put_u64(m, state->p_send.bytes)) != 0 ||
(r = sshbuf_put_u32(m, state->p_read.seqnr)) != 0 ||
(r = sshbuf_put_u64(m, state->p_read.blocks)) != 0 ||
(r = sshbuf_put_u32(m, state->p_read.packets)) != 0 ||
(r = sshbuf_put_u64(m, state->p_read.bytes)) != 0 ||
(r = sshbuf_put_stringb(m, state->input)) != 0 ||
(r = sshbuf_put_stringb(m, state->output)) != 0)
return r;
@ -2728,61 +2363,33 @@ int
ssh_packet_set_state(struct ssh *ssh, struct sshbuf *m)
{
struct session_state *state = ssh->state;
const u_char *ssh1key, *ivin, *ivout, *keyin, *keyout, *input, *output;
size_t ssh1keylen, rlen, slen, ilen, olen;
const u_char *input, *output;
size_t ilen, olen;
int r;
u_int ssh1cipher = 0;
if (!compat20) {
if ((r = sshbuf_get_u32(m, &state->remote_protocol_flags)) != 0 ||
(r = sshbuf_get_u32(m, &ssh1cipher)) != 0 ||
(r = sshbuf_get_string_direct(m, &ssh1key, &ssh1keylen)) != 0 ||
(r = sshbuf_get_string_direct(m, &ivout, &slen)) != 0 ||
(r = sshbuf_get_string_direct(m, &ivin, &rlen)) != 0)
return r;
if (ssh1cipher > INT_MAX)
return SSH_ERR_KEY_UNKNOWN_CIPHER;
ssh_packet_set_encryption_key(ssh, ssh1key, ssh1keylen,
(int)ssh1cipher);
if (cipher_get_keyiv_len(state->send_context) != (int)slen ||
cipher_get_keyiv_len(state->receive_context) != (int)rlen)
return SSH_ERR_INVALID_FORMAT;
if ((r = cipher_set_keyiv(state->send_context, ivout)) != 0 ||
(r = cipher_set_keyiv(state->receive_context, ivin)) != 0)
return r;
} else {
if ((r = kex_from_blob(m, &ssh->kex)) != 0 ||
(r = newkeys_from_blob(m, ssh, MODE_OUT)) != 0 ||
(r = newkeys_from_blob(m, ssh, MODE_IN)) != 0 ||
(r = sshbuf_get_u64(m, &state->rekey_limit)) != 0 ||
(r = sshbuf_get_u32(m, &state->rekey_interval)) != 0 ||
(r = sshbuf_get_u32(m, &state->p_send.seqnr)) != 0 ||
(r = sshbuf_get_u64(m, &state->p_send.blocks)) != 0 ||
(r = sshbuf_get_u32(m, &state->p_send.packets)) != 0 ||
(r = sshbuf_get_u64(m, &state->p_send.bytes)) != 0 ||
(r = sshbuf_get_u32(m, &state->p_read.seqnr)) != 0 ||
(r = sshbuf_get_u64(m, &state->p_read.blocks)) != 0 ||
(r = sshbuf_get_u32(m, &state->p_read.packets)) != 0 ||
(r = sshbuf_get_u64(m, &state->p_read.bytes)) != 0)
return r;
/*
* We set the time here so that in post-auth privsep slave we
* count from the completion of the authentication.
*/
state->rekey_time = monotime();
/* XXX ssh_set_newkeys overrides p_read.packets? XXX */
if ((r = ssh_set_newkeys(ssh, MODE_IN)) != 0 ||
(r = ssh_set_newkeys(ssh, MODE_OUT)) != 0)
return r;
}
if ((r = sshbuf_get_string_direct(m, &keyout, &slen)) != 0 ||
(r = sshbuf_get_string_direct(m, &keyin, &rlen)) != 0)
if ((r = kex_from_blob(m, &ssh->kex)) != 0 ||
(r = newkeys_from_blob(m, ssh, MODE_OUT)) != 0 ||
(r = newkeys_from_blob(m, ssh, MODE_IN)) != 0 ||
(r = sshbuf_get_u64(m, &state->rekey_limit)) != 0 ||
(r = sshbuf_get_u32(m, &state->rekey_interval)) != 0 ||
(r = sshbuf_get_u32(m, &state->p_send.seqnr)) != 0 ||
(r = sshbuf_get_u64(m, &state->p_send.blocks)) != 0 ||
(r = sshbuf_get_u32(m, &state->p_send.packets)) != 0 ||
(r = sshbuf_get_u64(m, &state->p_send.bytes)) != 0 ||
(r = sshbuf_get_u32(m, &state->p_read.seqnr)) != 0 ||
(r = sshbuf_get_u64(m, &state->p_read.blocks)) != 0 ||
(r = sshbuf_get_u32(m, &state->p_read.packets)) != 0 ||
(r = sshbuf_get_u64(m, &state->p_read.bytes)) != 0)
return r;
/*
* We set the time here so that in post-auth privsep slave we
* count from the completion of the authentication.
*/
state->rekey_time = monotime();
/* XXX ssh_set_newkeys overrides p_read.packets? XXX */
if ((r = ssh_set_newkeys(ssh, MODE_IN)) != 0 ||
(r = ssh_set_newkeys(ssh, MODE_OUT)) != 0)
return r;
if (cipher_get_keycontext(state->send_context, NULL) != (int)slen ||
cipher_get_keycontext(state->receive_context, NULL) != (int)rlen)
return SSH_ERR_INVALID_FORMAT;
cipher_set_keycontext(state->send_context, keyout);
cipher_set_keycontext(state->receive_context, keyin);
if ((r = ssh_packet_set_postauth(ssh)) != 0)
return r;
@ -2862,13 +2469,6 @@ sshpkt_put_ec(struct ssh *ssh, const EC_POINT *v, const EC_GROUP *g)
}
#endif /* OPENSSL_HAS_ECC */
#ifdef WITH_SSH1
int
sshpkt_put_bignum1(struct ssh *ssh, const BIGNUM *v)
{
return sshbuf_put_bignum1(ssh->state->outgoing_packet, v);
}
#endif /* WITH_SSH1 */
int
sshpkt_put_bignum2(struct ssh *ssh, const BIGNUM *v)
@ -2930,13 +2530,6 @@ sshpkt_get_ec(struct ssh *ssh, EC_POINT *v, const EC_GROUP *g)
}
#endif /* OPENSSL_HAS_ECC */
#ifdef WITH_SSH1
int
sshpkt_get_bignum1(struct ssh *ssh, BIGNUM *v)
{
return sshbuf_get_bignum1(ssh->state->incoming_packet, v);
}
#endif /* WITH_SSH1 */
int
sshpkt_get_bignum2(struct ssh *ssh, BIGNUM *v)
@ -2966,15 +2559,13 @@ sshpkt_ptr(struct ssh *ssh, size_t *lenp)
int
sshpkt_start(struct ssh *ssh, u_char type)
{
u_char buf[9];
int len;
u_char buf[6]; /* u32 packet length, u8 pad len, u8 type */
DBG(debug("packet_start[%d]", type));
len = compat20 ? 6 : 9;
memset(buf, 0, len - 1);
buf[len - 1] = type;
memset(buf, 0, sizeof(buf));
buf[sizeof(buf) - 1] = type;
sshbuf_reset(ssh->state->outgoing_packet);
return sshbuf_put(ssh->state->outgoing_packet, buf, len);
return sshbuf_put(ssh->state->outgoing_packet, buf, sizeof(buf));
}
static int
@ -3014,10 +2605,7 @@ sshpkt_send(struct ssh *ssh)
{
if (ssh->state && ssh->state->mux)
return ssh_packet_send_mux(ssh);
if (compat20)
return ssh_packet_send2(ssh);
else
return ssh_packet_send1(ssh);
return ssh_packet_send2(ssh);
}
int
@ -3031,19 +2619,12 @@ sshpkt_disconnect(struct ssh *ssh, const char *fmt,...)
vsnprintf(buf, sizeof(buf), fmt, args);
va_end(args);
if (compat20) {
if ((r = sshpkt_start(ssh, SSH2_MSG_DISCONNECT)) != 0 ||
(r = sshpkt_put_u32(ssh, SSH2_DISCONNECT_PROTOCOL_ERROR)) != 0 ||
(r = sshpkt_put_cstring(ssh, buf)) != 0 ||
(r = sshpkt_put_cstring(ssh, "")) != 0 ||
(r = sshpkt_send(ssh)) != 0)
return r;
} else {
if ((r = sshpkt_start(ssh, SSH_MSG_DISCONNECT)) != 0 ||
(r = sshpkt_put_cstring(ssh, buf)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
return r;
}
if ((r = sshpkt_start(ssh, SSH2_MSG_DISCONNECT)) != 0 ||
(r = sshpkt_put_u32(ssh, SSH2_DISCONNECT_PROTOCOL_ERROR)) != 0 ||
(r = sshpkt_put_cstring(ssh, buf)) != 0 ||
(r = sshpkt_put_cstring(ssh, "")) != 0 ||
(r = sshpkt_send(ssh)) != 0)
return r;
return 0;
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: packet.h,v 1.76 2017/02/03 23:03:33 djm Exp $ */
/* $OpenBSD: packet.h,v 1.79 2017/05/03 21:08:09 naddy Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -93,7 +93,6 @@ void ssh_packet_set_nonblocking(struct ssh *);
int ssh_packet_get_connection_in(struct ssh *);
int ssh_packet_get_connection_out(struct ssh *);
void ssh_packet_close(struct ssh *);
void ssh_packet_set_encryption_key(struct ssh *, const u_char *, u_int, int);
void ssh_packet_set_input_hook(struct ssh *, ssh_packet_hook_fn *, void *);
int ssh_packet_is_rekeying(struct ssh *);
@ -112,14 +111,12 @@ int ssh_packet_set_log_preamble(struct ssh *, const char *, ...)
int ssh_packet_log_type(u_char);
int ssh_packet_send1(struct ssh *);
int ssh_packet_send2_wrapped(struct ssh *);
int ssh_packet_send2(struct ssh *);
int ssh_packet_read(struct ssh *);
int ssh_packet_read_expect(struct ssh *, u_int type);
int ssh_packet_read_poll(struct ssh *);
int ssh_packet_read_poll1(struct ssh *, u_char *);
int ssh_packet_read_poll2(struct ssh *, u_char *, u_int32_t *seqnr_p);
int ssh_packet_process_incoming(struct ssh *, const char *buf, u_int len);
int ssh_packet_read_seqnr(struct ssh *, u_char *, u_int32_t *seqnr_p);
@ -182,7 +179,6 @@ int sshpkt_put_string(struct ssh *ssh, const void *v, size_t len);
int sshpkt_put_cstring(struct ssh *ssh, const void *v);
int sshpkt_put_stringb(struct ssh *ssh, const struct sshbuf *v);
int sshpkt_put_ec(struct ssh *ssh, const EC_POINT *v, const EC_GROUP *g);
int sshpkt_put_bignum1(struct ssh *ssh, const BIGNUM *v);
int sshpkt_put_bignum2(struct ssh *ssh, const BIGNUM *v);
int sshpkt_get(struct ssh *ssh, void *valp, size_t len);
@ -193,7 +189,6 @@ int sshpkt_get_string(struct ssh *ssh, u_char **valp, size_t *lenp);
int sshpkt_get_string_direct(struct ssh *ssh, const u_char **valp, size_t *lenp);
int sshpkt_get_cstring(struct ssh *ssh, char **valp, size_t *lenp);
int sshpkt_get_ec(struct ssh *ssh, EC_POINT *v, const EC_GROUP *g);
int sshpkt_get_bignum1(struct ssh *ssh, BIGNUM *v);
int sshpkt_get_bignum2(struct ssh *ssh, BIGNUM *v);
int sshpkt_get_end(struct ssh *ssh);
const u_char *sshpkt_ptr(struct ssh *, size_t *lenp);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: pathnames.h,v 1.25 2016/03/31 05:24:06 dtucker Exp $ */
/* $OpenBSD: pathnames.h,v 1.27 2017/05/05 10:42:49 naddy Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -36,7 +36,6 @@
*/
#define _PATH_SERVER_CONFIG_FILE SSHDIR "/sshd_config"
#define _PATH_HOST_CONFIG_FILE SSHDIR "/ssh_config"
#define _PATH_HOST_KEY_FILE SSHDIR "/ssh_host_key"
#define _PATH_HOST_DSA_KEY_FILE SSHDIR "/ssh_host_dsa_key"
#define _PATH_HOST_ECDSA_KEY_FILE SSHDIR "/ssh_host_ecdsa_key"
#define _PATH_HOST_ED25519_KEY_FILE SSHDIR "/ssh_host_ed25519_key"
@ -72,7 +71,6 @@
* Name of the default file containing client-side authentication key. This
* file should only be readable by the user him/herself.
*/
#define _PATH_SSH_CLIENT_IDENTITY _PATH_SSH_USER_DIR "/identity"
#define _PATH_SSH_CLIENT_ID_DSA _PATH_SSH_USER_DIR "/id_dsa"
#define _PATH_SSH_CLIENT_ID_ECDSA _PATH_SSH_USER_DIR "/id_ecdsa"
#define _PATH_SSH_CLIENT_ID_RSA _PATH_SSH_USER_DIR "/id_rsa"

View File

@ -1,4 +1,4 @@
/* $OpenBSD: readconf.c,v 1.270 2017/03/10 04:27:32 djm Exp $ */
/* $OpenBSD: readconf.c,v 1.275 2017/04/30 23:18:22 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -153,7 +153,7 @@ typedef enum {
oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts,
oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
oUsePrivilegedPort, oLogFacility, oLogLevel, oCiphers, oMacs,
oPubkeyAuthentication,
oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
@ -172,7 +172,7 @@ typedef enum {
oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys,
oFingerprintHash, oUpdateHostkeys, oHostbasedKeyTypes,
oPubkeyAcceptedKeyTypes, oProxyJump,
oIgnoredUnknownOption, oDeprecated, oUnsupported
oIgnore, oIgnoredUnknownOption, oDeprecated, oUnsupported
} OpCodes;
/* Textual representations of the tokens. */
@ -182,6 +182,8 @@ static struct {
OpCodes opcode;
} keywords[] = {
/* Deprecated options */
{ "protocol", oIgnore }, /* NB. silently ignored */
{ "cipher", oDeprecated },
{ "fallbacktorsh", oDeprecated },
{ "globalknownhostsfile2", oDeprecated },
{ "rhostsauthentication", oDeprecated },
@ -209,15 +211,9 @@ static struct {
{ "smartcarddevice", oUnsupported },
{ "pkcs11provider", oUnsupported },
#endif
#ifdef WITH_SSH1
{ "rsaauthentication", oRSAAuthentication },
{ "rhostsrsaauthentication", oRhostsRSAAuthentication },
{ "compressionlevel", oCompressionLevel },
# else
{ "rsaauthentication", oUnsupported },
{ "rhostsrsaauthentication", oUnsupported },
{ "compressionlevel", oUnsupported },
#endif
{ "forwardagent", oForwardAgent },
{ "forwardx11", oForwardX11 },
@ -246,10 +242,8 @@ static struct {
{ "hostkeyalias", oHostKeyAlias },
{ "proxycommand", oProxyCommand },
{ "port", oPort },
{ "cipher", oCipher },
{ "ciphers", oCiphers },
{ "macs", oMacs },
{ "protocol", oProtocol },
{ "remoteforward", oRemoteForward },
{ "localforward", oLocalForward },
{ "user", oUser },
@ -266,6 +260,7 @@ static struct {
{ "tcpkeepalive", oTCPKeepAlive },
{ "keepalive", oTCPKeepAlive }, /* obsolete */
{ "numberofpasswordprompts", oNumberOfPasswordPrompts },
{ "syslogfacility", oLogFacility },
{ "loglevel", oLogLevel },
{ "dynamicforward", oDynamicForward },
{ "preferredauthentications", oPreferredAuthentications },
@ -836,6 +831,7 @@ process_config_line_depth(Options *options, struct passwd *pw, const char *host,
u_int i, *uintptr, max_entries = 0;
int r, oactive, negated, opcode, *intptr, value, value2, cmdline = 0;
LogLevel *log_level_ptr;
SyslogFacility *log_facility_ptr;
long long val64;
size_t len;
struct Forward fwd;
@ -876,6 +872,8 @@ process_config_line_depth(Options *options, struct passwd *pw, const char *host,
case oBadOption:
/* don't panic, but count bad options */
return -1;
case oIgnore:
return 0;
case oIgnoredUnknownOption:
debug("%s line %d: Ignored unknown option \"%s\"",
filename, linenum, keyword);
@ -959,14 +957,6 @@ parse_time:
intptr = &options->pubkey_authentication;
goto parse_flag;
case oRSAAuthentication:
intptr = &options->rsa_authentication;
goto parse_flag;
case oRhostsRSAAuthentication:
intptr = &options->rhosts_rsa_authentication;
goto parse_flag;
case oHostbasedAuthentication:
intptr = &options->hostbased_authentication;
goto parse_flag;
@ -1017,10 +1007,6 @@ parse_time:
intptr = &options->number_of_password_prompts;
goto parse_int;
case oCompressionLevel:
intptr = &options->compression_level;
goto parse_int;
case oRekeyLimit:
arg = strdelim(&s);
if (!arg || *arg == '\0')
@ -1183,19 +1169,6 @@ parse_int:
intptr = &options->connection_attempts;
goto parse_int;
case oCipher:
intptr = &options->cipher;
arg = strdelim(&s);
if (!arg || *arg == '\0')
fatal("%.200s line %d: Missing argument.", filename, linenum);
value = cipher_number(arg);
if (value == -1)
fatal("%.200s line %d: Bad cipher '%s'.",
filename, linenum, arg ? arg : "<NONE>");
if (*activep && *intptr == -1)
*intptr = value;
break;
case oCiphers:
arg = strdelim(&s);
if (!arg || *arg == '\0')
@ -1246,19 +1219,6 @@ parse_keytypes:
*charptr = xstrdup(arg);
break;
case oProtocol:
intptr = &options->protocol;
arg = strdelim(&s);
if (!arg || *arg == '\0')
fatal("%.200s line %d: Missing argument.", filename, linenum);
value = proto_spec(arg);
if (value == SSH_PROTO_UNKNOWN)
fatal("%.200s line %d: Bad protocol spec '%s'.",
filename, linenum, arg ? arg : "<NONE>");
if (*activep && *intptr == SSH_PROTO_UNKNOWN)
*intptr = value;
break;
case oLogLevel:
log_level_ptr = &options->log_level;
arg = strdelim(&s);
@ -1270,6 +1230,17 @@ parse_keytypes:
*log_level_ptr = (LogLevel) value;
break;
case oLogFacility:
log_facility_ptr = &options->log_facility;
arg = strdelim(&s);
value = log_facility_number(arg);
if (value == SYSLOG_FACILITY_NOT_SET)
fatal("%.200s line %d: unsupported log facility '%s'",
filename, linenum, arg ? arg : "<NONE>");
if (*log_facility_ptr == -1)
*log_facility_ptr = (SyslogFacility) value;
break;
case oLocalForward:
case oRemoteForward:
case oDynamicForward:
@ -1739,9 +1710,9 @@ read_config_file_depth(const char *filename, struct passwd *pw,
if (flags & SSHCONF_CHECKPERM) {
#if WINDOWS
/*
file permissions are designed differently on windows
implementation on windows to make sure the config file is owned by the user and
nobody else except Administrators group and current user of calling process, and SYSTEM account has the write permission
file permissions are designed differently on windows.
implementation on windows to make sure the config file is owned by a user, administrators group, or LOCALSYSTEM account
and nobody else except Administrators group, LOCALSYSTEM, and file owner account has the write permission
*/
if (check_secure_file_permission(filename, pw) != 0)
fatal("Bad owner or permissions on %s", filename);
@ -1811,7 +1782,6 @@ initialize_options(Options * options)
options->fwd_opts.streamlocal_bind_mask = (mode_t)-1;
options->fwd_opts.streamlocal_bind_unlink = -1;
options->use_privileged_port = -1;
options->rsa_authentication = -1;
options->pubkey_authentication = -1;
options->challenge_response_authentication = -1;
options->gss_authentication = -1;
@ -1819,25 +1789,21 @@ initialize_options(Options * options)
options->password_authentication = -1;
options->kbd_interactive_authentication = -1;
options->kbd_interactive_devices = NULL;
options->rhosts_rsa_authentication = -1;
options->hostbased_authentication = -1;
options->batch_mode = -1;
options->check_host_ip = -1;
options->strict_host_key_checking = -1;
options->compression = -1;
options->tcp_keep_alive = -1;
options->compression_level = -1;
options->port = -1;
options->address_family = -1;
options->connection_attempts = -1;
options->connection_timeout = -1;
options->number_of_password_prompts = -1;
options->cipher = -1;
options->ciphers = NULL;
options->macs = NULL;
options->kex_algorithms = NULL;
options->hostkeyalgorithms = NULL;
options->protocol = SSH_PROTO_UNKNOWN;
options->num_identity_files = 0;
options->num_certificate_files = 0;
options->hostname = NULL;
@ -1855,6 +1821,7 @@ initialize_options(Options * options)
options->num_local_forwards = 0;
options->remote_forwards = NULL;
options->num_remote_forwards = 0;
options->log_facility = SYSLOG_FACILITY_NOT_SET;
options->log_level = SYSLOG_LEVEL_NOT_SET;
options->preferred_authentications = NULL;
options->bind_address = NULL;
@ -1951,8 +1918,6 @@ fill_default_options(Options * options)
options->fwd_opts.streamlocal_bind_unlink = 0;
if (options->use_privileged_port == -1)
options->use_privileged_port = 0;
if (options->rsa_authentication == -1)
options->rsa_authentication = 1;
if (options->pubkey_authentication == -1)
options->pubkey_authentication = 1;
if (options->challenge_response_authentication == -1)
@ -1965,8 +1930,6 @@ fill_default_options(Options * options)
options->password_authentication = 1;
if (options->kbd_interactive_authentication == -1)
options->kbd_interactive_authentication = 1;
if (options->rhosts_rsa_authentication == -1)
options->rhosts_rsa_authentication = 0;
if (options->hostbased_authentication == -1)
options->hostbased_authentication = 0;
if (options->batch_mode == -1)
@ -1979,8 +1942,6 @@ fill_default_options(Options * options)
options->compression = 0;
if (options->tcp_keep_alive == -1)
options->tcp_keep_alive = 1;
if (options->compression_level == -1)
options->compression_level = 6;
if (options->port == -1)
options->port = 0; /* Filled in ssh_connect. */
if (options->address_family == -1)
@ -1989,31 +1950,17 @@ fill_default_options(Options * options)
options->connection_attempts = 1;
if (options->number_of_password_prompts == -1)
options->number_of_password_prompts = 3;
/* Selected in ssh_login(). */
if (options->cipher == -1)
options->cipher = SSH_CIPHER_NOT_SET;
/* options->hostkeyalgorithms, default set in myproposals.h */
if (options->protocol == SSH_PROTO_UNKNOWN)
options->protocol = SSH_PROTO_2;
if (options->add_keys_to_agent == -1)
options->add_keys_to_agent = 0;
if (options->num_identity_files == 0) {
if (options->protocol & SSH_PROTO_1) {
add_identity_file(options, "~/",
_PATH_SSH_CLIENT_IDENTITY, 0);
}
if (options->protocol & SSH_PROTO_2) {
add_identity_file(options, "~/",
_PATH_SSH_CLIENT_ID_RSA, 0);
add_identity_file(options, "~/",
_PATH_SSH_CLIENT_ID_DSA, 0);
add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_RSA, 0);
add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_DSA, 0);
#ifdef OPENSSL_HAS_ECC
add_identity_file(options, "~/",
_PATH_SSH_CLIENT_ID_ECDSA, 0);
add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_ECDSA, 0);
#endif
add_identity_file(options, "~/",
_PATH_SSH_CLIENT_ID_ED25519, 0);
}
add_identity_file(options, "~/",
_PATH_SSH_CLIENT_ID_ED25519, 0);
}
if (options->escape_char == -1)
options->escape_char = '~';
@ -2031,6 +1978,8 @@ fill_default_options(Options * options)
}
if (options->log_level == SYSLOG_LEVEL_NOT_SET)
options->log_level = SYSLOG_LEVEL_INFO;
if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
options->log_facility = SYSLOG_FACILITY_USER;
if (options->no_host_authentication_for_localhost == - 1)
options->no_host_authentication_for_localhost = 0;
if (options->identities_only == -1)
@ -2402,17 +2351,6 @@ fmt_intarg(OpCodes code, int val)
return fmt_multistate_int(val, multistate_canonicalizehostname);
case oFingerprintHash:
return ssh_digest_alg_name(val);
case oProtocol:
switch (val) {
case SSH_PROTO_1:
return "1";
case SSH_PROTO_2:
return "2";
case (SSH_PROTO_1|SSH_PROTO_2):
return "2,1";
default:
return "UNKNOWN";
}
default:
switch (val) {
case 0:
@ -2557,14 +2495,9 @@ dump_client_config(Options *o, const char *host)
dump_cfg_fmtint(oNoHostAuthenticationForLocalhost, o->no_host_authentication_for_localhost);
dump_cfg_fmtint(oPasswordAuthentication, o->password_authentication);
dump_cfg_fmtint(oPermitLocalCommand, o->permit_local_command);
dump_cfg_fmtint(oProtocol, o->protocol);
dump_cfg_fmtint(oProxyUseFdpass, o->proxy_use_fdpass);
dump_cfg_fmtint(oPubkeyAuthentication, o->pubkey_authentication);
dump_cfg_fmtint(oRequestTTY, o->request_tty);
#ifdef WITH_RSA1
dump_cfg_fmtint(oRhostsRSAAuthentication, o->rhosts_rsa_authentication);
dump_cfg_fmtint(oRSAAuthentication, o->rsa_authentication);
#endif
dump_cfg_fmtint(oStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);
dump_cfg_fmtint(oStrictHostKeyChecking, o->strict_host_key_checking);
dump_cfg_fmtint(oTCPKeepAlive, o->tcp_keep_alive);
@ -2576,9 +2509,6 @@ dump_client_config(Options *o, const char *host)
/* Integer options */
dump_cfg_int(oCanonicalizeMaxDots, o->canonicalize_max_dots);
#ifdef WITH_SSH1
dump_cfg_int(oCompressionLevel, o->compression_level);
#endif
dump_cfg_int(oConnectionAttempts, o->connection_attempts);
dump_cfg_int(oForwardX11Timeout, o->forward_x11_timeout);
dump_cfg_int(oNumberOfPasswordPrompts, o->number_of_password_prompts);
@ -2648,10 +2578,6 @@ dump_client_config(Options *o, const char *host)
printf("\n");
}
/* oCipher */
if (o->cipher != SSH_CIPHER_NOT_SET)
printf("Cipher %s\n", cipher_name(o->cipher));
/* oControlPersist */
if (o->control_persist == 0 || o->control_persist_timeout == 0)
dump_cfg_fmtint(oControlPersist, o->control_persist);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: readconf.h,v 1.117 2016/07/15 00:24:30 djm Exp $ */
/* $OpenBSD: readconf.h,v 1.121 2017/04/30 23:18:22 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -37,9 +37,6 @@ typedef struct {
char *xauth_location; /* Location for xauth program */
struct ForwardOptions fwd_opts; /* forwarding options */
int use_privileged_port; /* Don't use privileged port if false. */
int rhosts_rsa_authentication; /* Try rhosts with RSA
* authentication. */
int rsa_authentication; /* Try RSA authentication. */
int pubkey_authentication; /* Try ssh2 pubkey authentication. */
int hostbased_authentication; /* ssh2's rhosts_rsa */
int challenge_response_authentication;
@ -54,11 +51,10 @@ typedef struct {
int check_host_ip; /* Also keep track of keys for IP address */
int strict_host_key_checking; /* Strict host key checking. */
int compression; /* Compress packets in both directions. */
int compression_level; /* Compression level 1 (fast) to 9
* (best). */
int tcp_keep_alive; /* Set SO_KEEPALIVE. */
int ip_qos_interactive; /* IP ToS/DSCP/class for interactive */
int ip_qos_bulk; /* IP ToS/DSCP/class for bulk traffic */
SyslogFacility log_facility; /* Facility for system logging. */
LogLevel log_level; /* Level for logging. */
int port; /* Port to connect. */
@ -69,12 +65,10 @@ typedef struct {
* aborting connection attempt */
int number_of_password_prompts; /* Max number of password
* prompts. */
int cipher; /* Cipher to use. */
char *ciphers; /* SSH2 ciphers in order of preference. */
char *macs; /* SSH2 macs in order of preference. */
char *hostkeyalgorithms; /* SSH2 server key types in order of preference. */
char *kex_algorithms; /* SSH2 kex methods in order of preference. */
int protocol; /* Protocol in order of preference. */
char *hostname; /* Real host to connect. */
char *host_key_alias; /* hostname alias for .ssh/known_hosts */
char *proxy_command; /* Proxy command for connecting the host. */

View File

@ -89,30 +89,33 @@ INTEROP_TESTS= putty-transfer putty-ciphers putty-kex conch-ciphers
#LTESTS= cipher-speed
USERNAME!= id -un
USERNAME= ${LOGNAME}
CLEANFILES= *.core actual agent-key.* authorized_keys_${USERNAME} \
authorized_keys_${USERNAME}.* \
authorized_principals_${USERNAME} \
banner.in banner.out cert_host_key* cert_user_key* \
copy.1 copy.2 data ed25519-agent ed25519-agent* \
ed25519-agent.pub empty.in expect failed-regress.log \
failed-ssh.log failed-sshd.log hkr.* host.rsa host.rsa1 \
host_* host_ca_key* host_krl_* host_revoked_* key.* \
key.dsa-* key.ecdsa-* key.ed25519-512 key.ed25519-512.pub \
key.rsa-* keys-command-args kh.* known_hosts \
known_hosts-cert known_hosts.* krl-* ls.copy modpipe \
netcat pidfile putty.rsa2 ready regress.log remote_pid \
revoked-* rsa rsa-agent rsa-agent.pub rsa.pub rsa1 \
rsa1-agent rsa1-agent.pub rsa1.pub rsa_ssh2_cr.prv \
ed25519-agent.pub ed25519 ed25519.pub empty.in \
expect failed-regress.log failed-ssh.log failed-sshd.log \
hkr.* host.ed25519 host.rsa host.rsa1 host_* \
host_ca_key* host_krl_* host_revoked_* key.* \
key.dsa-* key.ecdsa-* key.ed25519-512 \
key.ed25519-512.pub key.rsa-* keys-command-args kh.* \
known_hosts known_hosts-cert known_hosts.* krl-* ls.copy \
modpipe netcat no_identity_config \
pidfile putty.rsa2 ready regress.log \
remote_pid revoked-* rsa rsa-agent rsa-agent.pub rsa.pub \
rsa1 rsa1-agent rsa1-agent.pub rsa1.pub rsa_ssh2_cr.prv \
rsa_ssh2_crnl.prv scp-ssh-wrapper.exe \
scp-ssh-wrapper.scp setuid-allowed sftp-server.log \
sftp-server.sh sftp.log ssh-log-wrapper.sh ssh.log \
ssh_config ssh_config.* ssh_proxy ssh_proxy_bak \
ssh_proxy_envpass sshd.log sshd_config sshd_config.orig \
sshd_proxy sshd_proxy.* sshd_proxy_bak sshd_proxy_orig \
t10.out t10.out.pub t12.out t12.out.pub t2.out t3.out \
t6.out1 t6.out2 t7.out t7.out.pub t8.out t8.out.pub \
t9.out t9.out.pub testdata user_*key* user_ca* user_key*
ssh_proxy_envpass sshd.log sshd_config sshd_config_minimal \
sshd_config.orig sshd_proxy sshd_proxy.* sshd_proxy_bak \
sshd_proxy_orig t10.out t10.out.pub t12.out t12.out.pub \
t2.out t3.out t6.out1 t6.out2 t7.out t7.out.pub \
t8.out t8.out.pub t9.out t9.out.pub testdata \
user_*key* user_ca* user_key*
SUDO_CLEAN+= /var/run/testdata_${USERNAME} /var/run/keycommand_${USERNAME}

View File

@ -1,4 +1,4 @@
# $OpenBSD: agent-pkcs11.sh,v 1.2 2015/01/12 11:46:32 djm Exp $
# $OpenBSD: agent-pkcs11.sh,v 1.3 2017/04/30 23:34:55 djm Exp $
# Placed in the Public Domain.
tid="pkcs11 agent test"
@ -53,7 +53,7 @@ else
fi
trace "pkcs11 connect via agent"
${SSH} -2 -F $OBJ/ssh_proxy somehost exit 5
${SSH} -F $OBJ/ssh_proxy somehost exit 5
r=$?
if [ $r -ne 5 ]; then
fail "ssh connect failed (exit code $r)"

View File

@ -1,4 +1,4 @@
# $OpenBSD: agent.sh,v 1.11 2015/03/03 22:35:19 markus Exp $
# $OpenBSD: agent.sh,v 1.12 2017/04/30 23:34:55 djm Exp $
# Placed in the Public Domain.
tid="simple agent test"
@ -46,28 +46,24 @@ else
fi
trace "simple connect via agent"
for p in ${SSH_PROTOCOLS}; do
${SSH} -$p -F $OBJ/ssh_proxy somehost exit 5$p
r=$?
if [ $r -ne 5$p ]; then
fail "ssh connect with protocol $p failed (exit code $r)"
fi
done
${SSH} -F $OBJ/ssh_proxy somehost exit 52
r=$?
if [ $r -ne 52 ]; then
fail "ssh connect with failed (exit code $r)"
fi
trace "agent forwarding"
for p in ${SSH_PROTOCOLS}; do
${SSH} -A -$p -F $OBJ/ssh_proxy somehost ${SSHADD} -l > /dev/null 2>&1
r=$?
if [ $r -ne 0 ]; then
fail "ssh-add -l via agent fwd proto $p failed (exit code $r)"
fi
${SSH} -A -$p -F $OBJ/ssh_proxy somehost \
"${SSH} -$p -F $OBJ/ssh_proxy somehost exit 5$p"
r=$?
if [ $r -ne 5$p ]; then
fail "agent fwd proto $p failed (exit code $r)"
fi
done
${SSH} -A -F $OBJ/ssh_proxy somehost ${SSHADD} -l > /dev/null 2>&1
r=$?
if [ $r -ne 0 ]; then
fail "ssh-add -l via agent fwd failed (exit code $r)"
fi
${SSH} -A -F $OBJ/ssh_proxy somehost \
"${SSH} -F $OBJ/ssh_proxy somehost exit 52"
r=$?
if [ $r -ne 52 ]; then
fail "agent fwd failed (exit code $r)"
fi
trace "delete all agent keys"
${SSHADD} -D > /dev/null 2>&1

View File

@ -1,4 +1,4 @@
# $OpenBSD: banner.sh,v 1.2 2003/10/11 11:49:49 dtucker Exp $
# $OpenBSD: banner.sh,v 1.3 2017/04/30 23:34:55 djm Exp $
# Placed in the Public Domain.
tid="banner"
@ -9,7 +9,7 @@ touch $OBJ/empty.in
trace "test missing banner file"
verbose "test $tid: missing banner file"
( ${SSH} -2 -F $OBJ/ssh_proxy otherhost true 2>$OBJ/banner.out && \
( ${SSH} -F $OBJ/ssh_proxy otherhost true 2>$OBJ/banner.out && \
cmp $OBJ/empty.in $OBJ/banner.out ) || \
fail "missing banner file"
@ -30,14 +30,14 @@ for s in 0 10 100 1000 10000 100000 ; do
trace "test banner size $s"
verbose "test $tid: size $s"
( ${SSH} -2 -F $OBJ/ssh_proxy otherhost true 2>$OBJ/banner.out && \
( ${SSH} -F $OBJ/ssh_proxy otherhost true 2>$OBJ/banner.out && \
cmp $OBJ/banner.in $OBJ/banner.out ) || \
fail "banner size $s mismatch"
done
trace "test suppress banner (-q)"
verbose "test $tid: suppress banner (-q)"
( ${SSH} -q -2 -F $OBJ/ssh_proxy otherhost true 2>$OBJ/banner.out && \
( ${SSH} -q -F $OBJ/ssh_proxy otherhost true 2>$OBJ/banner.out && \
cmp $OBJ/empty.in $OBJ/banner.out ) || \
fail "suppress banner (-q)"

View File

@ -1,15 +1,12 @@
# $OpenBSD: broken-pipe.sh,v 1.5 2015/03/03 22:35:19 markus Exp $
# $OpenBSD: broken-pipe.sh,v 1.6 2017/04/30 23:34:55 djm Exp $
# Placed in the Public Domain.
tid="broken pipe test"
for p in ${SSH_PROTOCOLS}; do
trace "protocol $p"
for i in 1 2 3 4; do
${SSH} -$p -F $OBJ/ssh_config_config nexthost echo $i 2> /dev/null | true
r=$?
if [ $r -ne 0 ]; then
fail "broken pipe returns $r for protocol $p"
fi
done
for i in 1 2 3 4; do
${SSH} -F $OBJ/ssh_config_config nexthost echo $i 2> /dev/null | true
r=$?
if [ $r -ne 0 ]; then
fail "broken pipe returns $r"
fi
done

View File

@ -1,4 +1,4 @@
# $OpenBSD: brokenkeys.sh,v 1.1 2004/10/29 23:59:22 djm Exp $
# $OpenBSD: brokenkeys.sh,v 1.2 2017/04/30 23:34:55 djm Exp $
# Placed in the Public Domain.
tid="broken keys"
@ -14,9 +14,9 @@ echo "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEABTM= bad key" > $KEYS
cat ${KEYS}.bak >> ${KEYS}
cat $OBJ/$t.pub >> $OBJ/authorized_keys_$USER
${SSH} -2 -F $OBJ/ssh_config somehost true
${SSH} -F $OBJ/ssh_config somehost true
if [ $? -ne 0 ]; then
fail "ssh connect with protocol $p failed"
fail "ssh connect with failed"
fi
mv ${KEYS}.bak ${KEYS}

View File

@ -1,4 +1,4 @@
# $OpenBSD: cert-file.sh,v 1.5 2017/03/11 23:44:16 djm Exp $
# $OpenBSD: cert-file.sh,v 1.6 2017/04/30 23:34:55 djm Exp $
# Placed in the Public Domain.
tid="ssh with certificates"
@ -54,66 +54,64 @@ cat $OBJ/ssh_proxy | grep -v IdentityFile > $OBJ/no_identity_config
# XXX: verify that certificate used was what we expect. Needs exposure of
# keys via enviornment variable or similar.
for p in ${SSH_PROTOCOLS}; do
# Key with no .pub should work - finding the equivalent *-cert.pub.
verbose "protocol $p: identity cert with no plain public file"
${SSH} -F $OBJ/no_identity_config -oIdentitiesOnly=yes \
-i $OBJ/user_key3 somehost exit 5$p
[ $? -ne 5$p ] && fail "ssh failed"
verbose "identity cert with no plain public file"
${SSH} -F $OBJ/no_identity_config -oIdentitiesOnly=yes \
-i $OBJ/user_key3 somehost exit 52
[ $? -ne 52 ] && fail "ssh failed"
# CertificateFile matching private key with no .pub file should work.
verbose "protocol $p: CertificateFile with no plain public file"
${SSH} -F $OBJ/no_identity_config -oIdentitiesOnly=yes \
-oCertificateFile=$OBJ/user_key3-cert.pub \
-i $OBJ/user_key3 somehost exit 5$p
[ $? -ne 5$p ] && fail "ssh failed"
# CertificateFile matching private key with no .pub file should work.
verbose "CertificateFile with no plain public file"
${SSH} -F $OBJ/no_identity_config -oIdentitiesOnly=yes \
-oCertificateFile=$OBJ/user_key3-cert.pub \
-i $OBJ/user_key3 somehost exit 52
[ $? -ne 52 ] && fail "ssh failed"
# Just keys should fail
verbose "protocol $p: plain keys"
${SSH} $opts2 somehost exit 5$p
r=$?
if [ $r -eq 5$p ]; then
fail "ssh succeeded with no certs in protocol $p"
fi
# Just keys should fail
verbose "plain keys"
${SSH} $opts2 somehost exit 52
r=$?
if [ $r -eq 52 ]; then
fail "ssh succeeded with no certs"
fi
# Keys with untrusted cert should fail.
verbose "protocol $p: untrusted cert"
opts3="$opts2 -oCertificateFile=$OBJ/cert_user_key1_2.pub"
${SSH} $opts3 somehost exit 5$p
r=$?
if [ $r -eq 5$p ]; then
fail "ssh succeeded with bad cert in protocol $p"
fi
# Keys with untrusted cert should fail.
verbose "untrusted cert"
opts3="$opts2 -oCertificateFile=$OBJ/cert_user_key1_2.pub"
${SSH} $opts3 somehost exit 52
r=$?
if [ $r -eq 52 ]; then
fail "ssh succeeded with bad cert"
fi
# Good cert with bad key should fail.
verbose "protocol $p: good cert, bad key"
opts3="$opts -i $OBJ/user_key2"
opts3="$opts3 -oCertificateFile=$OBJ/cert_user_key1_1.pub"
${SSH} $opts3 somehost exit 5$p
r=$?
if [ $r -eq 5$p ]; then
fail "ssh succeeded with no matching key in protocol $p"
fi
# Good cert with bad key should fail.
verbose "good cert, bad key"
opts3="$opts -i $OBJ/user_key2"
opts3="$opts3 -oCertificateFile=$OBJ/cert_user_key1_1.pub"
${SSH} $opts3 somehost exit 52
r=$?
if [ $r -eq 52 ]; then
fail "ssh succeeded with no matching key"
fi
# Keys with one trusted cert, should succeed.
verbose "protocol $p: single trusted"
opts3="$opts2 -oCertificateFile=$OBJ/cert_user_key1_1.pub"
${SSH} $opts3 somehost exit 5$p
r=$?
if [ $r -ne 5$p ]; then
fail "ssh failed with trusted cert and key in protocol $p"
fi
# Keys with one trusted cert, should succeed.
verbose "single trusted"
opts3="$opts2 -oCertificateFile=$OBJ/cert_user_key1_1.pub"
${SSH} $opts3 somehost exit 52
r=$?
if [ $r -ne 52 ]; then
fail "ssh failed with trusted cert and key"
fi
# Multiple certs and keys, with one trusted cert, should succeed.
verbose "protocol $p: multiple trusted"
opts3="$opts2 -oCertificateFile=$OBJ/cert_user_key1_2.pub"
opts3="$opts3 -oCertificateFile=$OBJ/cert_user_key1_1.pub"
${SSH} $opts3 somehost exit 5$p
r=$?
if [ $r -ne 5$p ]; then
fail "ssh failed with multiple certs in protocol $p"
fi
done
# Multiple certs and keys, with one trusted cert, should succeed.
verbose "multiple trusted"
opts3="$opts2 -oCertificateFile=$OBJ/cert_user_key1_2.pub"
opts3="$opts3 -oCertificateFile=$OBJ/cert_user_key1_1.pub"
${SSH} $opts3 somehost exit 52
r=$?
if [ $r -ne 52 ]; then
fail "ssh failed with multiple certs"
fi
#next, using an agent in combination with the keys
SSH_AUTH_SOCK=/nonexistent ${SSHADD} -l > /dev/null 2>&1
@ -139,26 +137,25 @@ if [ $? -ne 0 ]; then
fi
# try ssh with the agent and certificates
# note: ssh agent only uses certificates in protocol 2
opts="-F $OBJ/ssh_proxy"
# with no certificates, shoud fail
${SSH} -2 $opts somehost exit 52
${SSH} $opts somehost exit 52
if [ $? -eq 52 ]; then
fail "ssh connect with agent in protocol 2 succeeded with no cert"
fail "ssh connect with agent in succeeded with no cert"
fi
#with an untrusted certificate, should fail
opts="$opts -oCertificateFile=$OBJ/cert_user_key1_2.pub"
${SSH} -2 $opts somehost exit 52
${SSH} $opts somehost exit 52
if [ $? -eq 52 ]; then
fail "ssh connect with agent in protocol 2 succeeded with bad cert"
fail "ssh connect with agent in succeeded with bad cert"
fi
#with an additional trusted certificate, should succeed
opts="$opts -oCertificateFile=$OBJ/cert_user_key1_1.pub"
${SSH} -2 $opts somehost exit 52
${SSH} $opts somehost exit 52
if [ $? -ne 52 ]; then
fail "ssh connect with agent in protocol 2 failed with good cert"
fail "ssh connect with agent in failed with good cert"
fi
trace "kill agent"

View File

@ -1,4 +1,4 @@
# $OpenBSD: cert-hostkey.sh,v 1.14 2016/05/02 09:52:00 djm Exp $
# $OpenBSD: cert-hostkey.sh,v 1.15 2017/04/30 23:34:55 djm Exp $
# Placed in the Public Domain.
tid="certified host keys"
@ -104,7 +104,7 @@ attempt_connect() {
shift; shift
verbose "$tid: $_ident expect success $_expect_success"
cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert
${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \
${SSH} -oUserKnownHostsFile=$OBJ/known_hosts-cert \
-oGlobalKnownHostsFile=$OBJ/known_hosts-cert \
"$@" -F $OBJ/ssh_proxy somehost true
_r=$?
@ -169,7 +169,7 @@ for privsep in yes no ; do
) > $OBJ/sshd_proxy
cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert
${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \
${SSH} -oUserKnownHostsFile=$OBJ/known_hosts-cert \
-oGlobalKnownHostsFile=$OBJ/known_hosts-cert \
-F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
if [ $? -eq 0 ]; then
@ -190,7 +190,7 @@ for ktype in $PLAIN_TYPES ; do
echo HostCertificate $OBJ/cert_host_key_${ktype}-cert.pub
) > $OBJ/sshd_proxy
cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert
${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \
${SSH} -oUserKnownHostsFile=$OBJ/known_hosts-cert \
-oGlobalKnownHostsFile=$OBJ/known_hosts-cert \
-F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
if [ $? -eq 0 ]; then
@ -222,7 +222,7 @@ test_one() {
) > $OBJ/sshd_proxy
cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert
${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \
${SSH} -oUserKnownHostsFile=$OBJ/known_hosts-cert \
-oGlobalKnownHostsFile=$OBJ/known_hosts-cert \
-F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
rc=$?
@ -271,7 +271,7 @@ for ktype in $PLAIN_TYPES ; do
echo HostCertificate $OBJ/cert_host_key_${ktype}-cert.pub
) > $OBJ/sshd_proxy
${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \
${SSH} -oUserKnownHostsFile=$OBJ/known_hosts-cert \
-oGlobalKnownHostsFile=$OBJ/known_hosts-cert \
-F $OBJ/ssh_proxy somehost true
if [ $? -ne 0 ]; then
@ -303,7 +303,7 @@ for kt in $PLAIN_TYPES ; do
) > $OBJ/sshd_proxy
cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert
${SSH} -2 -oUserKnownHostsFile=$OBJ/known_hosts-cert \
${SSH} -oUserKnownHostsFile=$OBJ/known_hosts-cert \
-oGlobalKnownHostsFile=$OBJ/known_hosts-cert \
-F $OBJ/ssh_proxy -q somehost true >/dev/null 2>&1
if [ $? -eq 0 ]; then

View File

@ -1,4 +1,4 @@
# $OpenBSD: cert-userkey.sh,v 1.17 2016/11/30 03:01:33 djm Exp $
# $OpenBSD: cert-userkey.sh,v 1.18 2017/04/30 23:34:55 djm Exp $
# Placed in the Public Domain.
tid="certified user keys"
@ -67,7 +67,7 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do
# Missing authorized_principals
verbose "$tid: ${_prefix} missing authorized_principals"
rm -f $OBJ/authorized_principals_$USER
${SSH} -2i $OBJ/cert_user_key_${ktype} \
${SSH} -i $OBJ/cert_user_key_${ktype} \
-F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
if [ $? -eq 0 ]; then
fail "ssh cert connect succeeded unexpectedly"
@ -76,7 +76,7 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do
# Empty authorized_principals
verbose "$tid: ${_prefix} empty authorized_principals"
echo > $OBJ/authorized_principals_$USER
${SSH} -2i $OBJ/cert_user_key_${ktype} \
${SSH} -i $OBJ/cert_user_key_${ktype} \
-F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
if [ $? -eq 0 ]; then
fail "ssh cert connect succeeded unexpectedly"
@ -85,7 +85,7 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do
# Wrong authorized_principals
verbose "$tid: ${_prefix} wrong authorized_principals"
echo gregorsamsa > $OBJ/authorized_principals_$USER
${SSH} -2i $OBJ/cert_user_key_${ktype} \
${SSH} -i $OBJ/cert_user_key_${ktype} \
-F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
if [ $? -eq 0 ]; then
fail "ssh cert connect succeeded unexpectedly"
@ -94,7 +94,7 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do
# Correct authorized_principals
verbose "$tid: ${_prefix} correct authorized_principals"
echo mekmitasdigoat > $OBJ/authorized_principals_$USER
${SSH} -2i $OBJ/cert_user_key_${ktype} \
${SSH} -i $OBJ/cert_user_key_${ktype} \
-F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
if [ $? -ne 0 ]; then
fail "ssh cert connect failed"
@ -103,7 +103,7 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do
# authorized_principals with bad key option
verbose "$tid: ${_prefix} authorized_principals bad key opt"
echo 'blah mekmitasdigoat' > $OBJ/authorized_principals_$USER
${SSH} -2i $OBJ/cert_user_key_${ktype} \
${SSH} -i $OBJ/cert_user_key_${ktype} \
-F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
if [ $? -eq 0 ]; then
fail "ssh cert connect succeeded unexpectedly"
@ -113,7 +113,7 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do
verbose "$tid: ${_prefix} authorized_principals command=false"
echo 'command="false" mekmitasdigoat' > \
$OBJ/authorized_principals_$USER
${SSH} -2i $OBJ/cert_user_key_${ktype} \
${SSH} -i $OBJ/cert_user_key_${ktype} \
-F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
if [ $? -eq 0 ]; then
fail "ssh cert connect succeeded unexpectedly"
@ -124,7 +124,7 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do
verbose "$tid: ${_prefix} authorized_principals command=true"
echo 'command="true" mekmitasdigoat' > \
$OBJ/authorized_principals_$USER
${SSH} -2i $OBJ/cert_user_key_${ktype} \
${SSH} -i $OBJ/cert_user_key_${ktype} \
-F $OBJ/ssh_proxy somehost false >/dev/null 2>&1
if [ $? -ne 0 ]; then
fail "ssh cert connect failed"
@ -148,7 +148,7 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do
printf 'cert-authority,principals="gregorsamsa" '
cat $OBJ/user_ca_key.pub
) > $OBJ/authorized_keys_$USER
${SSH} -2i $OBJ/cert_user_key_${ktype} \
${SSH} -i $OBJ/cert_user_key_${ktype} \
-F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
if [ $? -eq 0 ]; then
fail "ssh cert connect succeeded unexpectedly"
@ -160,7 +160,7 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do
printf 'cert-authority,principals="mekmitasdigoat" '
cat $OBJ/user_ca_key.pub
) > $OBJ/authorized_keys_$USER
${SSH} -2i $OBJ/cert_user_key_${ktype} \
${SSH} -i $OBJ/cert_user_key_${ktype} \
-F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
if [ $? -ne 0 ]; then
fail "ssh cert connect failed"
@ -198,7 +198,7 @@ basic_tests() {
echo "PubkeyAcceptedKeyTypes ${t}"
) > $OBJ/ssh_proxy
${SSH} -2i $OBJ/cert_user_key_${ktype} \
${SSH} -i $OBJ/cert_user_key_${ktype} \
-F $OBJ/ssh_proxy somehost true
if [ $? -ne 0 ]; then
fail "ssh cert connect failed"
@ -215,7 +215,7 @@ basic_tests() {
) > $OBJ/sshd_proxy
cp $OBJ/cert_user_key_${ktype}.pub \
$OBJ/cert_user_key_revoked
${SSH} -2i $OBJ/cert_user_key_${ktype} \
${SSH} -i $OBJ/cert_user_key_${ktype} \
-F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
if [ $? -eq 0 ]; then
fail "ssh cert connect succeeded unexpecedly"
@ -224,14 +224,14 @@ basic_tests() {
rm $OBJ/cert_user_key_revoked
${SSHKEYGEN} -kqf $OBJ/cert_user_key_revoked \
$OBJ/cert_user_key_${ktype}.pub
${SSH} -2i $OBJ/cert_user_key_${ktype} \
${SSH} -i $OBJ/cert_user_key_${ktype} \
-F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
if [ $? -eq 0 ]; then
fail "ssh cert connect succeeded unexpecedly"
fi
verbose "$tid: ${_prefix} empty KRL"
${SSHKEYGEN} -kqf $OBJ/cert_user_key_revoked
${SSH} -2i $OBJ/cert_user_key_${ktype} \
${SSH} -i $OBJ/cert_user_key_${ktype} \
-F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
if [ $? -ne 0 ]; then
fail "ssh cert connect failed"
@ -246,7 +246,7 @@ basic_tests() {
echo "PubkeyAcceptedKeyTypes ${t}"
echo "$extra_sshd"
) > $OBJ/sshd_proxy
${SSH} -2i $OBJ/cert_user_key_${ktype} -F $OBJ/ssh_proxy \
${SSH} -i $OBJ/cert_user_key_${ktype} -F $OBJ/ssh_proxy \
somehost true >/dev/null 2>&1
if [ $? -eq 0 ]; then
fail "ssh cert connect succeeded unexpecedly"
@ -260,7 +260,7 @@ basic_tests() {
echo "$extra_sshd"
) > $OBJ/sshd_proxy
verbose "$tid: ensure CA key does not authenticate user"
${SSH} -2i $OBJ/user_ca_key \
${SSH} -i $OBJ/user_ca_key \
-F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
if [ $? -eq 0 ]; then
fail "ssh cert connect with CA key succeeded unexpectedly"
@ -307,7 +307,7 @@ test_one() {
$sign_opts $OBJ/cert_user_key_${ktype} ||
fail "couldn't sign cert_user_key_${ktype}"
${SSH} -2i $OBJ/cert_user_key_${ktype} \
${SSH} -i $OBJ/cert_user_key_${ktype} \
-F $OBJ/ssh_proxy somehost true >/dev/null 2>&1
rc=$?
if [ "x$result" = "xsuccess" ] ; then
@ -378,7 +378,7 @@ for ktype in $PLAIN_TYPES ; do
-n $USER $OBJ/cert_user_key_${ktype} ||
fatal "couldn't sign cert_user_key_${ktype}"
verbose "$tid: user ${ktype} connect wrong cert"
${SSH} -2i $OBJ/cert_user_key_${ktype} -F $OBJ/ssh_proxy \
${SSH} -i $OBJ/cert_user_key_${ktype} -F $OBJ/ssh_proxy \
somehost true >/dev/null 2>&1
if [ $? -eq 0 ]; then
fail "ssh cert connect $ident succeeded unexpectedly"

View File

@ -1,4 +1,4 @@
# $OpenBSD: cfgmatch.sh,v 1.9 2015/03/03 22:35:19 markus Exp $
# $OpenBSD: cfgmatch.sh,v 1.10 2017/04/30 23:34:55 djm Exp $
# Placed in the Public Domain.
tid="sshd_config match"
@ -13,7 +13,7 @@ echo "ExitOnForwardFailure=yes" >> $OBJ/ssh_proxy
start_client()
{
rm -f $pidfile
${SSH} -q -$p $fwd "$@" somehost \
${SSH} -q $fwd "$@" somehost \
exec sh -c \'"echo \$\$ > $pidfile; exec sleep 100"\' \
>>$TEST_REGRESS_LOGFILE 2>&1 &
client_pid=$!
@ -56,22 +56,18 @@ start_sshd
#set -x
# Test Match + PermitOpen in sshd_config. This should be permitted
for p in ${SSH_PROTOCOLS}; do
trace "match permitopen localhost proto $p"
start_client -F $OBJ/ssh_config
${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true || \
fail "match permitopen permit proto $p"
stop_client
done
trace "match permitopen localhost"
start_client -F $OBJ/ssh_config
${SSH} -q -p $fwdport -F $OBJ/ssh_config somehost true || \
fail "match permitopen permit"
stop_client
# Same but from different source. This should not be permitted
for p in ${SSH_PROTOCOLS}; do
trace "match permitopen proxy proto $p"
start_client -F $OBJ/ssh_proxy
${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true && \
fail "match permitopen deny proto $p"
stop_client
done
trace "match permitopen proxy"
start_client -F $OBJ/ssh_proxy
${SSH} -q -p $fwdport -F $OBJ/ssh_config somehost true && \
fail "match permitopen deny"
stop_client
# Retry previous with key option, should also be denied.
cp /dev/null $OBJ/authorized_keys_$USER
@ -79,23 +75,19 @@ for t in ${SSH_KEYTYPES}; do
printf 'permitopen="127.0.0.1:'$PORT'" ' >> $OBJ/authorized_keys_$USER
cat $OBJ/$t.pub >> $OBJ/authorized_keys_$USER
done
for p in ${SSH_PROTOCOLS}; do
trace "match permitopen proxy w/key opts proto $p"
start_client -F $OBJ/ssh_proxy
${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true && \
fail "match permitopen deny w/key opt proto $p"
stop_client
done
trace "match permitopen proxy w/key opts"
start_client -F $OBJ/ssh_proxy
${SSH} -q -p $fwdport -F $OBJ/ssh_config somehost true && \
fail "match permitopen deny w/key opt"
stop_client
# Test both sshd_config and key options permitting the same dst/port pair.
# Should be permitted.
for p in ${SSH_PROTOCOLS}; do
trace "match permitopen localhost proto $p"
start_client -F $OBJ/ssh_config
${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true || \
fail "match permitopen permit proto $p"
stop_client
done
trace "match permitopen localhost"
start_client -F $OBJ/ssh_config
${SSH} -q -p $fwdport -F $OBJ/ssh_config somehost true || \
fail "match permitopen permit"
stop_client
cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy
echo "PermitOpen 127.0.0.1:1 127.0.0.1:$PORT 127.0.0.2:2" >>$OBJ/sshd_proxy
@ -103,13 +95,11 @@ echo "Match User $USER" >>$OBJ/sshd_proxy
echo "PermitOpen 127.0.0.1:1 127.0.0.1:2" >>$OBJ/sshd_proxy
# Test that a Match overrides a PermitOpen in the global section
for p in ${SSH_PROTOCOLS}; do
trace "match permitopen proxy w/key opts proto $p"
start_client -F $OBJ/ssh_proxy
${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true && \
fail "match override permitopen proto $p"
stop_client
done
trace "match permitopen proxy w/key opts"
start_client -F $OBJ/ssh_proxy
${SSH} -q -p $fwdport -F $OBJ/ssh_config somehost true && \
fail "match override permitopen"
stop_client
cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy
echo "PermitOpen 127.0.0.1:1 127.0.0.1:$PORT 127.0.0.2:2" >>$OBJ/sshd_proxy
@ -118,10 +108,8 @@ echo "PermitOpen 127.0.0.1:1 127.0.0.1:2" >>$OBJ/sshd_proxy
# Test that a rule that doesn't match doesn't override, plus test a
# PermitOpen entry that's not at the start of the list
for p in ${SSH_PROTOCOLS}; do
trace "nomatch permitopen proxy w/key opts proto $p"
start_client -F $OBJ/ssh_proxy
${SSH} -q -$p -p $fwdport -F $OBJ/ssh_config somehost true || \
fail "nomatch override permitopen proto $p"
stop_client
done
trace "nomatch permitopen proxy w/key opts"
start_client -F $OBJ/ssh_proxy
${SSH} -q -p $fwdport -F $OBJ/ssh_config somehost true || \
fail "nomatch override permitopen"
stop_client

View File

@ -1,4 +1,4 @@
# $OpenBSD: cipher-speed.sh,v 1.13 2015/03/24 20:22:17 markus Exp $
# $OpenBSD: cipher-speed.sh,v 1.14 2017/04/30 23:34:55 djm Exp $
# Placed in the Public Domain.
tid="cipher speed"
@ -12,16 +12,16 @@ getbytes ()
tries="1 2"
for c in `${SSH} -Q cipher`; do n=0; for m in `${SSH} -Q mac`; do
trace "proto 2 cipher $c mac $m"
trace "cipher $c mac $m"
for x in $tries; do
printf "%-60s" "$c/$m:"
( ${SSH} -o 'compression no' \
-F $OBJ/ssh_proxy -2 -m $m -c $c somehost \
-F $OBJ/ssh_proxy -m $m -c $c somehost \
exec sh -c \'"dd of=/dev/null obs=32k"\' \
< ${DATA} ) 2>&1 | getbytes
if [ $? -ne 0 ]; then
fail "ssh -2 failed with mac $m cipher $c"
fail "ssh failed with mac $m cipher $c"
fi
done
# No point trying all MACs for AEAD ciphers since they are ignored.
@ -30,22 +30,3 @@ for c in `${SSH} -Q cipher`; do n=0; for m in `${SSH} -Q mac`; do
fi
n=`expr $n + 1`
done; done
if ssh_version 1; then
ciphers="3des blowfish"
else
ciphers=""
fi
for c in $ciphers; do
trace "proto 1 cipher $c"
for x in $tries; do
printf "%-60s" "$c:"
( ${SSH} -o 'compression no' \
-F $OBJ/ssh_proxy -1 -c $c somehost \
exec sh -c \'"dd of=/dev/null obs=32k"\' \
< ${DATA} ) 2>&1 | getbytes
if [ $? -ne 0 ]; then
fail "ssh -1 failed with cipher $c"
fi
done
done

View File

@ -1,4 +1,4 @@
# $OpenBSD: connect-privsep.sh,v 1.8 2016/11/01 13:43:27 tb Exp $
# $OpenBSD: connect-privsep.sh,v 1.9 2017/04/30 23:34:55 djm Exp $
# Placed in the Public Domain.
tid="proxy connect with privsep"
@ -6,23 +6,19 @@ tid="proxy connect with privsep"
cp $OBJ/sshd_proxy $OBJ/sshd_proxy.orig
echo 'UsePrivilegeSeparation yes' >> $OBJ/sshd_proxy
for p in ${SSH_PROTOCOLS}; do
${SSH} -$p -F $OBJ/ssh_proxy 999.999.999.999 true
if [ $? -ne 0 ]; then
fail "ssh privsep+proxyconnect protocol $p failed"
fi
done
${SSH} -F $OBJ/ssh_proxy 999.999.999.999 true
if [ $? -ne 0 ]; then
fail "ssh privsep+proxyconnect failed"
fi
cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy
echo 'UsePrivilegeSeparation sandbox' >> $OBJ/sshd_proxy
for p in ${SSH_PROTOCOLS}; do
${SSH} -$p -F $OBJ/ssh_proxy 999.999.999.999 true
if [ $? -ne 0 ]; then
# XXX replace this with fail once sandbox has stabilised
warn "ssh privsep/sandbox+proxyconnect protocol $p failed"
fi
done
${SSH} -F $OBJ/ssh_proxy 999.999.999.999 true
if [ $? -ne 0 ]; then
# XXX replace this with fail once sandbox has stabilised
warn "ssh privsep/sandbox+proxyconnect failed"
fi
# Because sandbox is sensitive to changes in libc, especially malloc, retest
# with every malloc.conf option (and none).
@ -32,10 +28,8 @@ else
mopts=`echo $TEST_MALLOC_OPTIONS | sed 's/./& /g'`
fi
for m in '' $mopts ; do
for p in ${SSH_PROTOCOLS}; do
env MALLOC_OPTIONS="$m" ${SSH} -$p -F $OBJ/ssh_proxy 999.999.999.999 true
env MALLOC_OPTIONS="$m" ${SSH} -F $OBJ/ssh_proxy 999.999.999.999 true
if [ $? -ne 0 ]; then
fail "ssh privsep/sandbox+proxyconnect protocol $p mopt '$m' failed"
fail "ssh privsep/sandbox+proxyconnect mopt '$m' failed"
fi
done
done

Some files were not shown because too many files have changed in this diff Show More