mirror of
https://github.com/PowerShell/Win32-OpenSSH.git
synced 2025-07-31 01:45:10 +02:00
Source snapshot from Powershell/openssh-portable:latestw_all
This commit is contained in:
parent
9fd0cdab04
commit
2c3a1a95d0
50
.gitignore
vendored
50
.gitignore
vendored
@ -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/
|
||||
|
@ -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
23
LICENCE
@ -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 $
|
||||
|
25
Makefile.in
25
Makefile.in
@ -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
|
||||
|
@ -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 $
|
||||
|
@ -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
3
auth.c
@ -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
169
authfd.c
@ -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)
|
||||
|
5
authfd.h
5
authfd.h
@ -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);
|
||||
|
66
authfile.c
66
authfile.c
@ -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 */
|
||||
|
3
bitmap.c
3
bitmap.c
@ -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
42
bufbn.c
@ -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)
|
||||
{
|
||||
|
6
buffer.h
6
buffer.h
@ -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 *);
|
||||
|
684
channels.c
684
channels.c
@ -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();
|
||||
}
|
||||
|
14
channels.h
14
channels.h
@ -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
303
cipher.c
@ -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;
|
||||
}
|
||||
|
||||
|
29
cipher.h
29
cipher.h
@ -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 */
|
||||
|
623
clientloop.c
623
clientloop.c
@ -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)
|
||||
{
|
||||
|
25
compat.c
25
compat.c
@ -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;
|
||||
|
6
compat.h
6
compat.h
@ -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
|
||||
|
28
configure.ac
28
configure.ac
@ -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],
|
||||
|
52
contrib/win32/openssh/FixHostFilePermissions.ps1
Normal file
52
contrib/win32/openssh/FixHostFilePermissions.ps1
Normal 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 " "
|
14
contrib/win32/openssh/FixUserFilePermissions.ps1
Normal file
14
contrib/win32/openssh/FixUserFilePermissions.ps1
Normal 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 " "
|
@ -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;", '')
|
||||
}
|
||||
|
||||
|
@ -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
|
@ -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) {
|
||||
|
474
contrib/win32/openssh/OpenSSHUtils.psm1
Normal file
474
contrib/win32/openssh/OpenSSHUtils.psm1
Normal 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
|
@ -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
|
||||
|
@ -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)\ & copy /Y $(SolutionDir)uninstall-ssh*ps1 $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\ & 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)\ & copy /Y $(SolutionDir)uninstall-ssh*ps1 $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\ & 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)\ & copy /Y $(SolutionDir)uninstall-ssh*ps1 $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\ & 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)\ & copy /Y $(SolutionDir)uninstall-ssh*ps1 $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\ & 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" />
|
||||
|
@ -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))
|
||||
{
|
||||
|
@ -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" />
|
||||
|
@ -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>
|
205
contrib/win32/openssh/ssh-keyscan.vcxproj
Normal file
205
contrib/win32/openssh/ssh-keyscan.vcxproj
Normal 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>
|
30
contrib/win32/openssh/ssh-keyscan.vcxproj.filters
Normal file
30
contrib/win32/openssh/ssh-keyscan.vcxproj.filters
Normal 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>
|
@ -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>
|
||||
|
@ -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>
|
@ -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>
|
@ -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" />
|
||||
|
@ -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>
|
||||
|
@ -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" />
|
||||
|
@ -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.
@ -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" />
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 *);
|
@ -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
|
||||
|
@ -3,6 +3,7 @@
|
||||
*
|
||||
* UTF-16 <--> UTF-8 definitions
|
||||
*/
|
||||
#pragma once
|
||||
#ifndef UTF_H
|
||||
#define UTF_H 1
|
||||
|
||||
|
@ -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, §orsPerCluster, &bytesPerSector,
|
||||
&freeClusters, &totalClusters) == TRUE) {
|
||||
if (path_utf16 && (GetDiskFreeSpaceW(path_utf16, §orsPerCluster, &bytesPerSector,
|
||||
&freeClusters, &totalClusters) == TRUE)) {
|
||||
debug5("path : [%s]", path);
|
||||
debug5("sectorsPerCluster : [%lu]", sectorsPerCluster);
|
||||
debug5("bytesPerSector : [%lu]", bytesPerSector);
|
||||
|
@ -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 *);
|
||||
|
@ -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, ®_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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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)
|
@ -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)
|
@ -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, ®_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, ®_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)
|
@ -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, ®, 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)
|
@ -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
|
||||
|
@ -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;*/
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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*/
|
||||
}
|
||||
|
||||
|
||||
|
22
defines.h
22
defines.h
@ -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
|
||||
|
@ -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",
|
||||
|
@ -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 },
|
||||
|
13
digest.h
13
digest.h
@ -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;
|
||||
|
@ -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 ||
|
||||
|
31
hostfile.c
31
hostfile.c
@ -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
43
kex.c
@ -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
5
kex.h
@ -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
|
||||
|
@ -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
35
log.c
@ -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
4
log.h
@ -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
9
mac.c
@ -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 },
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
309
nchan.c
@ -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) {
|
||||
|
20
opacket.c
20
opacket.c
@ -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
|
||||
|
@ -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
627
packet.c
@ -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;
|
||||
}
|
||||
|
||||
|
7
packet.h
7
packet.h
@ -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);
|
||||
|
@ -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"
|
||||
|
136
readconf.c
136
readconf.c
@ -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);
|
||||
|
10
readconf.h
10
readconf.h
@ -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. */
|
||||
|
@ -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}
|
||||
|
||||
|
@ -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)"
|
||||
|
@ -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
|
||||
|
@ -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)"
|
||||
|
||||
|
@ -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
|
||||
|
@ -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}
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
Loading…
x
Reference in New Issue
Block a user