diff --git a/Source/v2/Meadow.Cli/Commands/Current/Device/DeviceProvisionCommand.cs b/Source/v2/Meadow.Cli/Commands/Current/Device/DeviceProvisionCommand.cs index 1dcf1810..fd59ef20 100644 --- a/Source/v2/Meadow.Cli/Commands/Current/Device/DeviceProvisionCommand.cs +++ b/Source/v2/Meadow.Cli/Commands/Current/Device/DeviceProvisionCommand.cs @@ -21,7 +21,7 @@ public class DeviceProvisionCommand : BaseDeviceCommand [CommandOption("name", 'n', Description = "Device friendly name", IsRequired = false)] public string? Name { get; set; } - [CommandOption("host", 'e', Description = "Optionally set a host (default is https://www.meadowcloud.co)", IsRequired = false)] + [CommandOption("host", 'h', Description = "Optionally set a host (default is https://www.meadowcloud.co)", IsRequired = false)] public string? Host { get; set; } public DeviceProvisionCommand(DeviceService deviceService, MeadowConnectionManager connectionManager, ILoggerFactory loggerFactory) @@ -82,54 +82,16 @@ protected override async ValueTask ExecuteCommand() var info = await connection.Device!.GetDeviceInfo(CancellationToken); - if (info == null) - { - Logger?.LogError($"Unable to get device info"); - return; - } - Logger?.LogInformation("Requesting device public key (this will take a minute)..."); var publicKey = await connection.Device.GetPublicKey(CancellationToken); - var delimList = new string[] - { - "-----END PUBLIC KEY-----", - "-----END RSA PUBLIC KEY-----" - }; + var delim = "-----END RSA PUBLIC KEY-----\n"; + publicKey = publicKey.Substring(0, publicKey.IndexOf(delim) + delim.Length); - foreach (var delim in delimList) - { - var i = publicKey.IndexOf(delim); - if (i >= 0) - { - publicKey = publicKey.Substring(0, publicKey.IndexOf(delim) + delim.Length); - break; - } - } Logger?.LogInformation("Provisioning device with Meadow.Cloud..."); - string provisioningID; - - // prefer processorID (since the F7 works that way) - if (!string.IsNullOrEmpty(info.ProcessorId)) - { - provisioningID = info.ProcessorId; - } - else - { - if (info.SerialNumber == null) - { - Logger?.LogError($"Unable to get device serial number or processor ID"); - return; - } - - provisioningID = info.SerialNumber; - } - - // upper-case to prevent issues where clients and provisioning differ - provisioningID = provisioningID.ToUpper(); - + var provisioningID = !string.IsNullOrWhiteSpace(info?.ProcessorId) ? info.ProcessorId : info?.SerialNumber; var provisioningName = !string.IsNullOrWhiteSpace(Name) ? Name : info?.DeviceName; var result = await _deviceService.AddDevice(org.Id!, provisioningID!, publicKey, CollectionId, provisioningName, Host, CancellationToken); diff --git a/Source/v2/Meadow.Hcom/Connections/LocalConnection.cs b/Source/v2/Meadow.Hcom/Connections/LocalConnection.cs index b8fe5204..f42afbb7 100644 --- a/Source/v2/Meadow.Hcom/Connections/LocalConnection.cs +++ b/Source/v2/Meadow.Hcom/Connections/LocalConnection.cs @@ -39,7 +39,7 @@ public LocalConnection() } using (var key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Cryptography\")) { - info.Add("SerialNo", (key?.GetValue("MachineGuid")?.ToString() ?? "Unknown").Trim().ToUpper()); + info.Add("SerialNo", (key?.GetValue("MachineGuid")?.ToString() ?? "Unknown").Trim()); } } else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) @@ -58,7 +58,7 @@ public LocalConnection() _deviceInfo = new DeviceInfo(info); } - return Task.FromResult(_deviceInfo); + return Task.FromResult< DeviceInfo?>(_deviceInfo); } private string ExecuteBashCommandLine(string command) @@ -68,6 +68,7 @@ private string ExecuteBashCommandLine(string command) FileName = "/bin/bash", Arguments = $"-c \"{command}\"", RedirectStandardOutput = true, + RedirectStandardError = true, UseShellExecute = false, CreateNoWindow = true }; @@ -76,30 +77,14 @@ private string ExecuteBashCommandLine(string command) process?.WaitForExit(); - return process?.StandardOutput.ReadToEnd() ?? string.Empty; - } - - private string ExecuteWindowsCommandLine(string command, string args) - { - var psi = new ProcessStartInfo() - { - FileName = command, - Arguments = args, - RedirectStandardOutput = true, - UseShellExecute = false, - CreateNoWindow = true - }; + var stdout = process?.StandardOutput.ReadToEnd() ?? string.Empty; + var stderr = process?.StandardError.ReadToEnd() ?? string.Empty; - using var process = Process.Start(psi); - - process?.WaitForExit(); - - return process?.StandardOutput.ReadToEnd() ?? string.Empty; + return stdout; } public override Task GetPublicKey(CancellationToken? cancellationToken = null) { - // DEV NOTE: this *must* be in PEM format: i.e. -----BEGIN RSA PUBLIC KEY----- ... -----END RSA PUBLIC KEY---- if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { @@ -117,37 +102,25 @@ public override Task GetPublicKey(CancellationToken? cancellationToken = throw new Exception("Public key not found"); } - var pkFileContent = File.ReadAllText(pkFile); - if (!pkFileContent.Contains("BEGIN RSA PUBLIC KEY", StringComparison.OrdinalIgnoreCase)) - { - // need to convert - pkFileContent = ExecuteWindowsCommandLine("ssh-keygen", $"-e -m pem -f {pkFile}"); - } - - return Task.FromResult(pkFileContent); + return Task.FromResult(File.ReadAllText(pkFile)); } } else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { - // this will generate a PEM output *assuming* the key has already been created - var keygenOutput = ExecuteBashCommandLine("ssh-keygen -f id_rsa -e -m pem"); - if (!keygenOutput.Contains("BEGIN RSA PUBLIC KEY", StringComparison.OrdinalIgnoreCase)) - { - // probably no key generated - throw new Exception("Unable to retrieve a public key. Please run 'ssh-keygen -t rsa'"); - } - - return Task.FromResult(keygenOutput); + // ssh-agent sh -c 'ssh-add; ssh-add -L' + throw new PlatformNotSupportedException(); } else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { // ssh-agent sh -c 'ssh-add; ssh-add -L' var pubkey = this.ExecuteBashCommandLine("ssh-agent sh -c 'ssh-add; ssh-add -L'"); - if (!pubkey.Contains("BEGIN RSA PUBLIC KEY", StringComparison.OrdinalIgnoreCase)) + + if (pubkey.StartsWith("ssh-rsa")) { - var path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".ssh", "id_rsa.pub"); - pubkey = ExecuteBashCommandLine($"ssh-keygen -f {path} -e -m pem"); + // convert to PEM format + pubkey = this.ExecuteBashCommandLine("ssh-keygen -f ~/.ssh/id_rsa.pub -m 'PEM' -e"); } + return Task.FromResult(pubkey); } else