diff --git a/contrib/win32/openssh/MicrosoftTelemetry.h b/contrib/win32/openssh/MicrosoftTelemetry.h
new file mode 100644
index 00000000000..b5e6944af99
--- /dev/null
+++ b/contrib/win32/openssh/MicrosoftTelemetry.h
@@ -0,0 +1,87 @@
+/* ++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+Licensed under the MIT License. See LICENSE in the project root for license information.
+
+Module Name:
+
+ TraceLoggingConfig.h
+
+Abstract:
+
+ Macro definitions used by this project's TraceLogging ETW providers:
+
+ - Configuration macros that select the ETW Provider Groups to be used by
+ this project.
+ - Constants for tags that are commonly used in Microsoft's
+ TraceLogging-based ETW.
+
+ Different versions of this file use different definitions for the
+ TraceLoggingOption configuration macros. The definitions in this file are
+ empty. As a result, providers using this configuration file will not join
+ any ETW Provider Groups and will not be given any special treatment by
+ group-sensitive ETW listeners.
+
+Environment:
+
+ User mode or kernel mode.
+
+--*/
+
+#pragma once
+
+// Configuration macro for use in TRACELOGGING_DEFINE_PROVIDER. The definition
+// in this file configures the provider as a normal (non-telemetry) provider.
+#define TraceLoggingOptionMicrosoftTelemetry() \
+ // Empty definition for TraceLoggingOptionMicrosoftTelemetry
+
+// Configuration macro for use in TRACELOGGING_DEFINE_PROVIDER. The definition
+// in this file configures the provider as a normal (non-telemetry) provider.
+#define TraceLoggingOptionWindowsCoreTelemetry() \
+ // Empty definition for TraceLoggingOptionWindowsCoreTelemetry
+
+// Event privacy tags. Use the PDT macro values for the tag parameter, e.g.:
+// TraceLoggingWrite(...,
+// TelemetryPrivacyDataTag(PDT_BrowsingHistory | PDT_ProductAndServiceUsage),
+// ...);
+#define TelemetryPrivacyDataTag(tag) TraceLoggingUInt64((tag), "PartA_PrivTags")
+#define PDT_BrowsingHistory 0x0000000000000002u
+#define PDT_DeviceConnectivityAndConfiguration 0x0000000000000800u
+#define PDT_InkingTypingAndSpeechUtterance 0x0000000000020000u
+#define PDT_ProductAndServicePerformance 0x0000000001000000u
+#define PDT_ProductAndServiceUsage 0x0000000002000000u
+#define PDT_SoftwareSetupAndInventory 0x0000000080000000u
+
+// Event categories specified via keywords, e.g.:
+// TraceLoggingWrite(...,
+// TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
+// ...);
+#define MICROSOFT_KEYWORD_CRITICAL_DATA 0x0000800000000000 // Bit 47
+#define MICROSOFT_KEYWORD_MEASURES 0x0000400000000000 // Bit 46
+#define MICROSOFT_KEYWORD_TELEMETRY 0x0000200000000000 // Bit 45
+#define MICROSOFT_KEYWORD_RESERVED_44 0x0000100000000000 // Bit 44 (reserved for future assignment)
+
+// Event categories specified via event tags, e.g.:
+// TraceLoggingWrite(...,
+// TraceLoggingEventTag(MICROSOFT_EVENTTAG_REALTIME_LATENCY),
+// ...);
+#define MICROSOFT_EVENTTAG_DROP_USER_IDS 0x00008000
+#define MICROSOFT_EVENTTAG_AGGREGATE 0x00010000
+#define MICROSOFT_EVENTTAG_DROP_PII_EXCEPT_IP 0x00020000
+#define MICROSOFT_EVENTTAG_COSTDEFERRED_LATENCY 0x00040000
+#define MICROSOFT_EVENTTAG_CORE_DATA 0x00080000
+#define MICROSOFT_EVENTTAG_INJECT_XTOKEN 0x00100000
+#define MICROSOFT_EVENTTAG_REALTIME_LATENCY 0x00200000
+#define MICROSOFT_EVENTTAG_NORMAL_LATENCY 0x00400000
+#define MICROSOFT_EVENTTAG_CRITICAL_PERSISTENCE 0x00800000
+#define MICROSOFT_EVENTTAG_NORMAL_PERSISTENCE 0x01000000
+#define MICROSOFT_EVENTTAG_DROP_PII 0x02000000
+#define MICROSOFT_EVENTTAG_HASH_PII 0x04000000
+#define MICROSOFT_EVENTTAG_MARK_PII 0x08000000
+
+// Field categories specified via field tags, e.g.:
+// TraceLoggingWrite(...,
+// TraceLoggingString(szUser, "UserName", "User's name", MICROSOFT_FIELDTAG_HASH_PII),
+// ...);
+#define MICROSOFT_FIELDTAG_DROP_PII 0x04000000
+#define MICROSOFT_FIELDTAG_HASH_PII 0x08000000
diff --git a/contrib/win32/openssh/OpenSSHBuildHelper.psm1 b/contrib/win32/openssh/OpenSSHBuildHelper.psm1
index 5c9f2f165b4..a6b66409e6a 100644
--- a/contrib/win32/openssh/OpenSSHBuildHelper.psm1
+++ b/contrib/win32/openssh/OpenSSHBuildHelper.psm1
@@ -1,4 +1,4 @@
-Set-StrictMode -Version 2.0
+Set-StrictMode -Version 2.0
If ($PSVersiontable.PSVersion.Major -le 2) {$PSScriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Path}
Import-Module $PSScriptRoot\OpenSSHCommonUtils.psm1 -Force
@@ -150,6 +150,7 @@ function Start-OpenSSHBootstrap
[bool] $silent = -not $script:Verbose
Write-BuildMsg -AsInfo -Message "Checking tools and dependencies" -Silent:$silent
+ $Win10SDKVerChoco = "10.1.17763.1"
$machinePath = [Environment]::GetEnvironmentVariable('Path', 'MACHINE')
$newMachineEnvironmentPath = $machinePath
@@ -205,26 +206,36 @@ function Start-OpenSSHBootstrap
}
$vcVars = "${env:ProgramFiles(x86)}\Microsoft Visual Studio 14.0\Common7\Tools\vsvars32.bat"
- $sdkPath = "${env:ProgramFiles(x86)}\Windows Kits\8.1\bin\x86\register_app.vbs"
+ $sdkVersion = Get-Windows10SDKVersion
+ $env:vctargetspath = "${env:ProgramFiles(x86)}\MSBuild\Microsoft.Cpp\v4.0\v140"
+
+ if ($sdkVersion -eq $null)
+ {
+ $packageName = "windows-sdk-10.1"
+ Write-BuildMsg -AsInfo -Message "$packageName not present. Installing $packageName ..."
+ choco install $packageName --version=$Win10SDKVerChoco -y --force --limitoutput --execution-timeout 120 2>&1 >> $script:BuildLogFile
+ }
+
+ if (-not (Test-Path $env:vctargetspath))
+ {
+ Write-BuildMsg -AsInfo -Message "installing visualcpp-build-tools"
+ choco install visualcpp-build-tools --version 14.0.25420.1 -y --force --limitoutput --execution-timeout 120 2>&1 >> $script:BuildLogFile
+ }
+
#use vs2017 build tool if exists
if($VS2017Path -ne $null)
{
- If (-not (Test-Path $sdkPath))
- {
- $packageName = "windows-sdk-8.1"
- Write-BuildMsg -AsInfo -Message "$packageName not present. Installing $packageName ..."
- choco install $packageName -y --force --limitoutput --execution-timeout 10000 2>&1 >> $script:BuildLogFile
- }
+
if(-not (Test-Path $VcVars))
{
Write-BuildMsg -AsError -ErrorAction Stop -Message "VC++ 2015.3 v140 toolset are not installed."
}
}
- elseIf (($VS2015Path -eq $null) -or (-not (Test-Path $VcVars)) -or (-not (Test-Path $sdkPath))) {
+ elseIf (($VS2015Path -eq $null) -or (-not (Test-Path $VcVars))) {
$packageName = "vcbuildtools"
Write-BuildMsg -AsInfo -Message "$packageName not present. Installing $packageName ..."
- choco install $packageName -ia "/InstallSelectableItems VisualCppBuildTools_ATLMFC_SDK;VisualCppBuildTools_NETFX_SDK;Win81SDK_CppBuildSKUV1" -y --force --limitoutput --execution-timeout 10000 2>&1 >> $script:BuildLogFile
+ choco install $packageName -ia "/InstallSelectableItems VisualCppBuildTools_ATLMFC_SDK;VisualCppBuildTools_NETFX_SDK" -y --force --limitoutput --execution-timeout 120 2>&1 >> $script:BuildLogFile
$errorCode = $LASTEXITCODE
if ($errorCode -eq 3010)
{
@@ -272,7 +283,7 @@ function Start-OpenSSHBootstrap
{
$packageName = "windows-sdk-10.1"
Write-BuildMsg -AsInfo -Message "$packageName not present. Installing $packageName ..."
- choco install $packageName --force --limitoutput --execution-timeout 10000 2>&1 >> $script:BuildLogFile
+ choco install $packageName --version=$Win10SDKVerChoco --force --limitoutput --execution-timeout 120 2>&1 >> $script:BuildLogFile
}
}
@@ -577,6 +588,7 @@ function Start-OpenSSHBuild
}
Write-BuildMsg -AsInfo -Message "Starting Open SSH build; Build Log: $($script:BuildLogFile)."
+ Write-BuildMsg -AsInfo -Message "$msbuildCmd $cmdMsg"
& "$msbuildCmd" $cmdMsg
$errorCode = $LASTEXITCODE
@@ -622,20 +634,17 @@ function Get-VS2015BuildToolPath
}
function Get-Windows10SDKVersion
-{
+{
+ #Temporary fix - Onecore builds are failing with latest windows 10 SDK (10.0.18362.0)
+ $requiredSDKVersion = [version]"10.0.17763.0"
## Search for latest windows sdk available on the machine
- $windowsSDKPath = Join-Path ${env:ProgramFiles(x86)} "Windows Kits\10\Lib"
- $minSDKVersion = [version]"10.0.14393.0"
- $versionsAvailable = @()
- #Temporary fix - Onecore builds are failing with latest widows 10 SDK (10.0.18362.0)
- $maxSDKVersion = [version]"10.0.17763.0"
- $versionsAvailable = Get-ChildItem $windowsSDKPath | ? {$_.Name.StartsWith("10.")} | % {$version = [version]$_.Name; if(($version.CompareTo($minSDKVersion) -ge 0) -and ($version.CompareTo($maxSDKVersion) -le 0)) {$version}}
- if(0 -eq $versionsAvailable.count)
- {
- return $null
+ $windowsSDKPath = Join-Path ${env:ProgramFiles(x86)} "Windows Kits\10\bin\$requiredSDKVersion\x86\register_app.vbs"
+ if (test-path $windowsSDKPath) {
+ return $requiredSDKVersion
+ }
+ else {
+ return $null
}
- $versionsAvailable = $versionsAvailable | Sort-Object -Descending
- return $versionsAvailable[0]
}
function Get-BuildLogFile
diff --git a/contrib/win32/openssh/paths.targets b/contrib/win32/openssh/paths.targets
index 0ab26fb0903..74212fb5259 100644
--- a/contrib/win32/openssh/paths.targets
+++ b/contrib/win32/openssh/paths.targets
@@ -18,7 +18,7 @@
$(SolutionDir)\ZLib\bin\arm\
true
libcrypto.lib;
- 8.1
+ 10.0.17763.0
bcrypt.lib;Userenv.lib;Crypt32.lib;Ws2_32.lib;Secur32.lib;Shlwapi.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;Netapi32.lib;Rpcrt4.lib;ntdll.lib
false
diff --git a/contrib/win32/openssh/sshTelemetry.c b/contrib/win32/openssh/sshTelemetry.c
new file mode 100644
index 00000000000..2ebe55c3e34
--- /dev/null
+++ b/contrib/win32/openssh/sshTelemetry.c
@@ -0,0 +1,218 @@
+/*
+* Author: Tess Gauthier
+*
+* Copyright(c) 2021 Microsoft Corp.
+* All rights reserved
+*
+* Misc Unix POSIX routine implementations for Windows
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met :
+*
+* 1. Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* 2. Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and / or other materials provided with the distribution.
+*
+* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT
+* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*
+this file defines functions to collect Microsoft Telemetry,
+which will only be sent for Windows In-Box releases.
+GitHub releases will not send any Telemetry.
+*/
+
+#include
+#include
+#include
+
+#include "sshTelemetry.h"
+#include "sshTelemetryInternal.h"
+
+// {0d986661-0dd7-561a-b15b-fcc1cd46d2bb}
+TRACELOGGING_DEFINE_PROVIDER(
+ g_hProvider1,
+ "Microsoft.Windows.Win32OpenSSH",
+ (0x0d986661, 0x0dd7, 0x561a, 0xb1, 0x5b, 0xfc, 0xc1, 0xcd, 0x46, 0xd2, 0xbb),
+ TraceLoggingOptionMicrosoftTelemetry());
+
+void send_auth_telemetry(const int status, const char* auth_type)
+{
+ /*
+ registering only needs to be done once per process but
+ since these functions are used by multiple processes
+ and we need to unregister so the ETW process knows
+ not to do any callbacks, registering and unregistering
+ is done after each tracelogging call for safety
+ */
+ TraceLoggingRegister(g_hProvider1);
+ TraceLoggingWrite(
+ g_hProvider1,
+ "Auth",
+ TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage),
+ TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
+ TraceLoggingInt16(status, "success"),
+ TraceLoggingString(auth_type, "authType")
+ );
+ TraceLoggingUnregister(g_hProvider1);
+}
+
+void send_encryption_telemetry(const char* direction,
+ const char* cipher, const char* kex, const char* mac,
+ const char* comp, const char* host_key,
+ const char** cproposal, const char** sproposal)
+{
+ TraceLoggingRegister(g_hProvider1);
+ TraceLoggingWrite(
+ g_hProvider1,
+ "Encryption",
+ TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage),
+ TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
+ TraceLoggingString(direction, "direction"),
+ TraceLoggingString(cipher, "cipher"),
+ TraceLoggingString(kex, "kex"),
+ TraceLoggingString(mac, "mac"),
+ TraceLoggingString(comp, "compression"),
+ TraceLoggingString(host_key, "hostKey"),
+ TraceLoggingString(cproposal[0], "clientProposedKex"),
+ TraceLoggingString(cproposal[1], "clientProposedHostKeys"),
+ TraceLoggingString(cproposal[2], "clientProposedCiphersCtos"),
+ TraceLoggingString(cproposal[3], "clientProposedCiphersStoc"),
+ TraceLoggingString(cproposal[4], "clientProposedMACsCtos"),
+ TraceLoggingString(cproposal[5], "clientProposedMACsStoc"),
+ TraceLoggingString(cproposal[6], "clientProposedCompressionCtos"),
+ TraceLoggingString(cproposal[7], "clientProposedCompressionStoc"),
+ TraceLoggingString(sproposal[0], "serverProposedKex"),
+ TraceLoggingString(sproposal[1], "serverProposedHostKeys"),
+ TraceLoggingString(sproposal[2], "serverProposedCiphersCtos"),
+ TraceLoggingString(sproposal[3], "serverProposedCiphersStoc"),
+ TraceLoggingString(sproposal[4], "serverProposedMACsCtos"),
+ TraceLoggingString(sproposal[5], "serverProposedMACsCtoc"),
+ TraceLoggingString(sproposal[6], "serverProposedCompressionCtos"),
+ TraceLoggingString(sproposal[7], "serverProposedCompressionStoc")
+ );
+ TraceLoggingUnregister(g_hProvider1);
+}
+
+void send_pubkey_telemetry(const char* pubKeyStatus)
+{
+ TraceLoggingRegister(g_hProvider1);
+ TraceLoggingWrite(
+ g_hProvider1,
+ "PublicKey",
+ TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage),
+ TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
+ TraceLoggingString(pubKeyStatus, "status")
+ );
+ TraceLoggingUnregister(g_hProvider1);
+}
+
+void send_shell_telemetry(const int pty, const int shell_type)
+{
+ TraceLoggingRegister(g_hProvider1);
+ TraceLoggingWrite(
+ g_hProvider1,
+ "Shell",
+ TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage),
+ TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
+ TraceLoggingInt16(pty, "PTY"),
+ TraceLoggingInt16(shell_type, "type")
+ );
+ TraceLoggingUnregister(g_hProvider1);
+}
+
+void send_pubkey_sign_telemetry(const char* pubKeySignStatus)
+{
+ TraceLoggingRegister(g_hProvider1);
+ TraceLoggingWrite(
+ g_hProvider1,
+ "PubkeySigning",
+ TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage),
+ TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
+ TraceLoggingString(pubKeySignStatus, "status")
+ );
+ TraceLoggingUnregister(g_hProvider1);
+}
+
+void send_ssh_connection_telemetry(const char* conn, const char* port)
+{
+ int isCustomPort = 0;
+ if (strcmp(port, "22") != 0) {
+ isCustomPort = 1;
+ }
+ TraceLoggingRegister(g_hProvider1);
+ TraceLoggingWrite(
+ g_hProvider1,
+ "Connection",
+ TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage),
+ TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
+ TraceLoggingString(conn, "status"),
+ TraceLoggingBool(isCustomPort, "isCustomSSHServerPort")
+ );
+ TraceLoggingUnregister(g_hProvider1);
+}
+
+void send_sshd_config_telemetry(const int num_auth_methods,
+ const char** auth_methods)
+{
+ char* auth_buffer = NULL;
+ if (num_auth_methods == 0) {
+ auth_buffer = (char*)malloc(5 * sizeof(char));
+ strcpy_s(auth_buffer, 5, "none");
+ }
+ else {
+ // concatenate all the auth methods into a
+ // single string to pass to tracelogging
+ size_t buffer_size = (size_t)num_auth_methods;
+ for (int i = 0; i < num_auth_methods; i++) {
+ buffer_size += strlen(auth_methods[i]);
+ }
+ auth_buffer = (char*)malloc((buffer_size + 1) * sizeof(char));
+ auth_buffer[0] = '\0';
+ for (int i = 0; i < num_auth_methods; i++) {
+ strcat_s(auth_buffer, buffer_size, auth_methods[i]);
+ if (i < num_auth_methods - 1) {
+ strcat_s(auth_buffer, buffer_size, ",");
+ }
+ }
+ }
+ TraceLoggingRegister(g_hProvider1);
+ TraceLoggingWrite(
+ g_hProvider1,
+ "SSHD",
+ TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage),
+ TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
+ TraceLoggingString(auth_buffer, "authMethods")
+ );
+ TraceLoggingUnregister(g_hProvider1);
+ free(auth_buffer);
+}
+
+void send_ssh_version_telemetry(const char* ssh_version, const char* peer_version,
+ const char* remote_protocol_supported)
+{
+ TraceLoggingRegister(g_hProvider1);
+ TraceLoggingWrite(
+ g_hProvider1,
+ "Startup",
+ TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage),
+ TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
+ TraceLoggingString(ssh_version, "ourVersion"),
+ TraceLoggingString(remote_protocol_supported, "remoteProtocolError"),
+ TraceLoggingString(peer_version, "peerVersion")
+ );
+ TraceLoggingUnregister(g_hProvider1);
+}
+
diff --git a/contrib/win32/openssh/sshTelemetry.h b/contrib/win32/openssh/sshTelemetry.h
new file mode 100644
index 00000000000..d63c7df4e61
--- /dev/null
+++ b/contrib/win32/openssh/sshTelemetry.h
@@ -0,0 +1,30 @@
+#pragma once
+
+// sends authentication type and status
+void send_auth_telemetry(const int status, const char* auth_type);
+
+// sends crypto information like cipher, kex, and mac
+void send_encryption_telemetry(const char* direction,
+ const char* cipher, const char* kex, const char* mac,
+ const char* comp, const char* host_key,
+ const char** cproposal, const char** sproposal);
+
+// sends status if using key-based auth
+void send_pubkey_telemetry(const char* pubKeyStatus);
+
+// sends shell configuration and if pty session is used
+void send_shell_telemetry(const int pty, const int shell_type);
+
+// sends signing status if using key-based auth
+void send_pubkey_sign_telemetry(const char* pubKeySignStatus);
+
+// sends connection status from ssh client
+void send_ssh_connection_telemetry(const char* conn, const char* port);
+
+// sends ports and auth methods configured by sshd
+void send_sshd_config_telemetry(const int num_auth_methods,
+ const char** auth_methods);
+
+// sends version and peer version from ssh & sshd
+void send_ssh_version_telemetry(const char* ssh_version,
+ const char* peer_version, const char* remote_protocol_supported);
diff --git a/contrib/win32/openssh/sshTelemetryInternal.h b/contrib/win32/openssh/sshTelemetryInternal.h
new file mode 100644
index 00000000000..0d04e13aa0d
--- /dev/null
+++ b/contrib/win32/openssh/sshTelemetryInternal.h
@@ -0,0 +1,8 @@
+#pragma once
+
+#include // Defines macros used by TraceLoggingProvider.h
+#include "TraceLoggingProvider.h" // The native TraceLogging API
+#include "MicrosoftTelemetry.h"
+
+// Forward-declare the g_hProvider1 variable that you will use for tracing
+TRACELOGGING_DECLARE_PROVIDER(g_hProvider1);
\ No newline at end of file
diff --git a/contrib/win32/openssh/win32iocompat.vcxproj b/contrib/win32/openssh/win32iocompat.vcxproj
index ad06c481c43..910a4059565 100644
--- a/contrib/win32/openssh/win32iocompat.vcxproj
+++ b/contrib/win32/openssh/win32iocompat.vcxproj
@@ -312,6 +312,7 @@
+
@@ -361,6 +362,9 @@
+
+
+
diff --git a/contrib/win32/openssh/win32iocompat.vcxproj.filters b/contrib/win32/openssh/win32iocompat.vcxproj.filters
index 1ed3e930775..c727e636bca 100644
--- a/contrib/win32/openssh/win32iocompat.vcxproj.filters
+++ b/contrib/win32/openssh/win32iocompat.vcxproj.filters
@@ -24,6 +24,7 @@
+
@@ -155,6 +156,9 @@
inc
+
+
+
diff --git a/contrib/win32/win32compat/w32-doexec.c b/contrib/win32/win32compat/w32-doexec.c
index e3a94de744a..fdbd8898aab 100644
--- a/contrib/win32/win32compat/w32-doexec.c
+++ b/contrib/win32/win32compat/w32-doexec.c
@@ -38,6 +38,7 @@
#include "servconf.h"
#include "pal_doexec.h"
#include "misc_internal.h"
+#include "sshTelemetry.h"
#ifndef SUBSYSTEM_NONE
#define SUBSYSTEM_NONE 0
@@ -315,6 +316,7 @@ int do_exec_windows(struct ssh *ssh, Session *s, const char *command, int pty) {
else
shell_command_option_local = "-c";
debug3("shell_option: %s", shell_command_option_local);
+ send_shell_telemetry(pty, shell_type);
if (pty) {
fcntl(s->ptyfd, F_SETFD, FD_CLOEXEC);
diff --git a/kex.c b/kex.c
index 709a0ec63aa..c01c5228ec1 100644
--- a/kex.c
+++ b/kex.c
@@ -42,6 +42,10 @@
#include
#endif
+#ifdef WINDOWS
+#include "sshTelemetry.h"
+#endif
+
#include "ssh.h"
#include "ssh2.h"
#include "atomicio.h"
@@ -965,6 +969,14 @@ kex_choose_conf(struct ssh *ssh)
newkeys->enc.name,
authlen == 0 ? newkeys->mac.name : "",
newkeys->comp.name);
+#ifdef WINDOWS
+ send_encryption_telemetry(ctos ? "ctos" : "stoc",
+ newkeys->enc.name, kex->name ? kex->name : "(no match)",
+ authlen == 0 ? newkeys->mac.name : "",
+ newkeys->comp.name,
+ kex->hostkey_alg ? kex->hostkey_alg : "(no match)",
+ my, peer);
+#endif
}
need = dh_need = 0;
for (mode = 0; mode < MODE_MAX; mode++) {
@@ -1319,6 +1331,11 @@ kex_exchange_identification(struct ssh *ssh, int timeout_ms,
&remote_major, &remote_minor, remote_version) != 3) {
error("Bad remote protocol version identification: '%.100s'",
peer_version_string);
+#ifdef WINDOWS
+ send_ssh_version_telemetry(our_version_string, peer_version_string,
+ "Bad remote protocol version identification");
+#endif
+
invalid:
send_error(ssh, "Invalid SSH identification string.");
r = SSH_ERR_INVALID_FORMAT;
@@ -1344,6 +1361,10 @@ kex_exchange_identification(struct ssh *ssh, int timeout_ms,
error("Protocol major versions differ: %d vs. %d",
PROTOCOL_MAJOR_2, remote_major);
send_error(ssh, "Protocol major versions differ.");
+#ifdef WINDOWS
+ send_ssh_version_telemetry(our_version_string,
+ peer_version_string, "Protocol major versions differ");
+#endif
r = SSH_ERR_NO_PROTOCOL_VERSION;
goto out;
}
@@ -1366,6 +1387,11 @@ kex_exchange_identification(struct ssh *ssh, int timeout_ms,
logit("Remote version \"%.100s\" uses unsafe RSA signature "
"scheme; disabling use of RSA keys", remote_version);
}
+
+#ifdef WINDOWS
+ send_ssh_version_telemetry(our_version_string,
+ peer_version_string, "none");
+#endif
/* success */
r = 0;
out:
diff --git a/sshconnect.c b/sshconnect.c
index 087d2c3734a..1ae69ef4d6b 100644
--- a/sshconnect.c
+++ b/sshconnect.c
@@ -49,6 +49,10 @@
# include
#endif
+#ifdef WINDOWS
+#include "sshTelemetry.h"
+#endif
+
#include "xmalloc.h"
#include "hostfile.h"
#include "ssh.h"
@@ -543,10 +547,16 @@ ssh_connect_direct(struct ssh *ssh, const char *host, struct addrinfo *aitop,
if (sock == -1) {
error("ssh: connect to host %s port %s: %s",
host, strport, errno == 0 ? "failure" : strerror(errno));
+#ifdef WINDOWS
+ send_ssh_connection_telemetry(strerror(errno), strport);
+#endif
return -1;
}
debug("Connection established.");
+#ifdef WINDOWS
+ send_ssh_connection_telemetry("Connection established.", strport);
+#endif
/* Set SO_KEEPALIVE if requested. */
if (want_keepalive &&
diff --git a/sshconnect2.c b/sshconnect2.c
index a53ab95dbb2..a33daa5fa72 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -76,6 +76,10 @@
#include "ssh-sk.h"
#include "sk-api.h"
+#ifdef WINDOWS
+#include "sshTelemetry.h"
+#endif
+
#ifdef GSSAPI
#include "ssh-gss.h"
#endif
@@ -487,6 +491,9 @@ ssh_userauth2(struct ssh *ssh, const char *local_user,
ssh_dispatch_range(ssh, SSH2_MSG_USERAUTH_MIN, SSH2_MSG_USERAUTH_MAX, NULL);
+#ifdef WINDOWS
+ send_auth_telemetry(authctxt.success, authctxt.success ? authctxt.method->name : "NULL");
+#endif
if (!authctxt.success)
fatal("Authentication failed.");
debug("Authentication succeeded (%s).", authctxt.method->name);
@@ -704,22 +711,45 @@ input_userauth_pk_ok(int type, u_int32_t seq, struct ssh *ssh)
int r;
if (authctxt == NULL)
+#ifdef WINDOWS
+ {
+ send_pubkey_telemetry("input_userauth_pk_ok: no authentication context");
fatal("input_userauth_pk_ok: no authentication context");
+ }
+#else
+ fatal("input_userauth_pk_ok: no authentication context");
+#endif
if ((r = sshpkt_get_cstring(ssh, &pkalg, NULL)) != 0 ||
(r = sshpkt_get_string(ssh, &pkblob, &blen)) != 0 ||
(r = sshpkt_get_end(ssh)) != 0)
+#ifdef WINDOWS
+ {
+ send_pubkey_telemetry("failure");
+ goto done;
+ }
+#else
goto done;
+#endif
if ((pktype = sshkey_type_from_name(pkalg)) == KEY_UNSPEC) {
+#ifdef WINDOWS
+ send_pubkey_telemetry("server sent unknown pkalg");
+#endif
debug_f("server sent unknown pkalg %s", pkalg);
goto done;
}
if ((r = sshkey_from_blob(pkblob, blen, &key)) != 0) {
+#ifdef WINDOWS
+ send_pubkey_telemetry("no key from blob");
+#endif
debug_r(r, "no key from blob. pkalg %s", pkalg);
goto done;
}
if (key->type != pktype) {
+#ifdef WINDOWS
+ send_pubkey_telemetry("type mistmatch for decoded key");
+#endif
error("input_userauth_pk_ok: type mismatch "
"for decoded key (received %d, expected %d)",
key->type, pktype);
@@ -746,6 +776,9 @@ input_userauth_pk_ok(int type, u_int32_t seq, struct ssh *ssh)
}
ident = format_identity(id);
debug("Server accepts key: %s", ident);
+#ifdef WINDOWS
+ send_pubkey_telemetry("success");
+#endif
sent = sign_and_send_pubkey(ssh, id);
r = 0;
done:
@@ -1395,6 +1428,9 @@ sign_and_send_pubkey(struct ssh *ssh, Identity *id)
signature = NULL;
if ((alg = key_sig_algorithm(fallback_sigtype ? NULL : ssh,
id->key)) == NULL) {
+#ifdef WINDOWS
+ send_pubkey_sign_telemetry("no mutual signature supported");
+#endif
error_f("no mutual signature supported");
goto out;
}
@@ -1439,6 +1475,9 @@ sign_and_send_pubkey(struct ssh *ssh, Identity *id)
loc, sshkey_type(id->key), fp);
continue;
}
+#ifdef WINDOWS
+ send_pubkey_sign_telemetry("signing failed");
+#endif
error_fr(r, "signing failed for %s \"%s\"%s",
sshkey_type(sign_id->key), sign_id->filename,
id->agent_fd != -1 ? " from agent" : "");
@@ -1466,6 +1505,9 @@ sign_and_send_pubkey(struct ssh *ssh, Identity *id)
/* success */
sent = 1;
+#ifdef WINDOWS
+ send_pubkey_sign_telemetry("success");
+#endif
out:
free(fp);
diff --git a/sshd.c b/sshd.c
index 915f3a23b92..44a1557ca81 100644
--- a/sshd.c
+++ b/sshd.c
@@ -85,6 +85,10 @@
#include
#endif
+#ifdef WINDOWS
+#include "sshTelemetry.h"
+#endif
+
#include "xmalloc.h"
#include "ssh.h"
#include "ssh2.h"
@@ -2226,6 +2230,10 @@ main(int ac, char **av)
debug("sshd version %s, %s", SSH_VERSION, SSH_OPENSSL_VERSION);
+#ifdef WINDOWS
+ send_sshd_config_telemetry(options.num_auth_methods,
+ options.auth_methods);
+#endif
/* Store privilege separation user for later use if required. */
privsep_chroot = use_privsep && (getuid() == 0 || geteuid() == 0);
if ((privsep_pw = getpwnam(SSH_PRIVSEP_USER)) == NULL) {