internal static SftpClient CreateSftpClient(this string connectionString) { if (connectionString == null) { throw new ArgumentNullException("connectionString"); } // get parts of connection string var csb = new DbConnectionStringBuilder { ConnectionString = connectionString }; var host = csb["host"] as string; var username = csb["username"] as string; var password = csb["password"] as string; var hostkey = csb["hostkey"] as string; var port = Attempt.Get(() => Convert.ToInt32(csb["port"])); // do this when connstring is bad Action <string> badConnString = detail => { throw new FormatException( string.Format( "SFTP connection string invalid. {0} Example: username=USERNAME;password=PASSWORD;host=HOSTNAME;hostkey=ssh-dss 1024 3b:1c:20:aa:27:00:83:4f:7a:49:9c:9f:e7:67:ab:03", detail ?? "")); }; // check required conn string params if (new[] { host, username, password, hostkey }.Any(string.IsNullOrWhiteSpace)) { badConnString("Missing required parameter."); } // check format of host key var hostKeyParts = hostkey.Split().Where(x => !string.IsNullOrWhiteSpace(x)).Select(x => x.Trim().ToLower()).ToArray(); // host key needs 3 parts: name, length, fingerprint if (hostKeyParts.Length != 3) { badConnString(string.Format("Host key '{0}' is incorrectly formatted.", hostkey)); } // length neeeds to be an int int hostKeyLength; if (!int.TryParse(hostKeyParts[1], out hostKeyLength)) { badConnString(string.Format("Host key length '{0}' is not an integer.", hostKeyParts[1])); } // finter print needs to be a byte array as hex string var hostKeyPrint = Attempt.Get(() => SoapHexBinary.Parse(string.Concat(hostKeyParts[2].Where(char.IsLetterOrDigit))).Value); if (!hostKeyPrint.Succeeded) { badConnString(string.Format("Invalid host key fingerprint '{0}'.", hostKeyParts[2])); } // using only pw auth for time being var pwAuthMethod = new PasswordAuthenticationMethod(username, password); var connInfo = port.Succeeded ? new ConnectionInfo(host, port.Value, username, pwAuthMethod) : new ConnectionInfo(host, username, pwAuthMethod); var sftpClient = new SftpClient(connInfo); // validate host key sftpClient.HostKeyReceived += (s, e) => { e.CanTrust = hostKeyParts[0].Equals(e.HostKeyName.Trim(), StringComparison.OrdinalIgnoreCase) && hostKeyLength == e.KeyLength && hostKeyPrint.Value.SequenceEqual(e.FingerPrint); }; return(sftpClient); }