first real commit
This commit is contained in:
372
SSH.cs
Normal file
372
SSH.cs
Normal file
@@ -0,0 +1,372 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using Renci.SshNet;
|
||||
|
||||
namespace cdrtool
|
||||
{
|
||||
public class sftp
|
||||
{
|
||||
private static SftpClient CreateClient(
|
||||
string host,
|
||||
int port,
|
||||
string username,
|
||||
string password)
|
||||
{
|
||||
var client = new SftpClient(host, port, username, password);
|
||||
|
||||
client.ConnectionInfo.Timeout = System.TimeSpan.FromSeconds(15);
|
||||
client.OperationTimeout = System.TimeSpan.FromSeconds(30);
|
||||
client.KeepAliveInterval = System.TimeSpan.FromSeconds(10);
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
public static Renci.SshNet.ConnectionInfo BuildConnectionInfo(
|
||||
string host,
|
||||
int port,
|
||||
string username,
|
||||
string password,
|
||||
Renci.SshNet.PrivateKeyFile privateKeyFile = null)
|
||||
{
|
||||
var auth = new System.Collections.Generic.List<Renci.SshNet.AuthenticationMethod>();
|
||||
|
||||
if (privateKeyFile != null)
|
||||
auth.Add(new Renci.SshNet.PrivateKeyAuthenticationMethod(username, privateKeyFile));
|
||||
|
||||
if (!string.IsNullOrEmpty(password))
|
||||
{
|
||||
var kb = new Renci.SshNet.KeyboardInteractiveAuthenticationMethod(username);
|
||||
kb.AuthenticationPrompt += (s, e) =>
|
||||
{
|
||||
foreach (var p in e.Prompts)
|
||||
p.Response = password;
|
||||
};
|
||||
auth.Add(kb);
|
||||
|
||||
auth.Add(new Renci.SshNet.PasswordAuthenticationMethod(username, password));
|
||||
}
|
||||
|
||||
return new Renci.SshNet.ConnectionInfo(host, port, username, auth.ToArray())
|
||||
{
|
||||
Timeout = System.TimeSpan.FromSeconds(30),
|
||||
RetryAttempts = 1
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
public static bool ConnectWithRetries(
|
||||
Renci.SshNet.ConnectionInfo info,
|
||||
int maxAttempts,
|
||||
int timeoutSeconds)
|
||||
{
|
||||
for (int i = 0; i < maxAttempts; i++)
|
||||
{
|
||||
if (TrySftpConnectWithHardTimeout(info, timeoutSeconds))
|
||||
return true;
|
||||
|
||||
System.Threading.Thread.Sleep(5000);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
public static Renci.SshNet.SftpClient TrySftpConnectWithHardTimeout(
|
||||
Renci.SshNet.ConnectionInfo connectionInfo,
|
||||
int maxAttempts,
|
||||
int timeoutSeconds)
|
||||
{
|
||||
for (int i = 0; i < maxAttempts; i++)
|
||||
{
|
||||
|
||||
Renci.SshNet.SftpClient client = null;
|
||||
|
||||
try
|
||||
{
|
||||
var task = System.Threading.Tasks.Task.Run(() =>
|
||||
{
|
||||
client = new Renci.SshNet.SftpClient(connectionInfo);
|
||||
|
||||
// These are still useful, but not sufficient alone
|
||||
client.ConnectionInfo.Timeout =
|
||||
System.TimeSpan.FromSeconds(30);
|
||||
|
||||
client.KeepAliveInterval =
|
||||
System.TimeSpan.FromSeconds(15);
|
||||
|
||||
client.Connect();
|
||||
});
|
||||
|
||||
bool completed =
|
||||
task.Wait(System.TimeSpan.FromSeconds(timeoutSeconds));
|
||||
|
||||
if (!completed)
|
||||
{
|
||||
// HARD TIMEOUT
|
||||
try
|
||||
{
|
||||
client?.Dispose();
|
||||
}
|
||||
catch { }
|
||||
|
||||
//return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return client;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
try
|
||||
{
|
||||
client?.Dispose();
|
||||
}
|
||||
catch { }
|
||||
|
||||
//return null;
|
||||
}
|
||||
|
||||
System.Threading.Thread.Sleep(5000);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static void Upload_stream(MemoryStream ms, string filename, string host, int port, string username, string password)
|
||||
{
|
||||
int maxAttempts = 5;
|
||||
int timeout = 120; //seconds
|
||||
|
||||
try
|
||||
{
|
||||
//using (var sftpClient = CreateClient(host, port, username, password))
|
||||
var sftpInfo = BuildConnectionInfo(host, port, username, password);
|
||||
Renci.SshNet.SftpClient sftpClient = null;
|
||||
try
|
||||
{
|
||||
sftpClient = TrySftpConnectWithHardTimeout(sftpInfo, maxAttempts, timeout);
|
||||
}
|
||||
catch (Renci.SshNet.Common.SshConnectionException e)
|
||||
{
|
||||
Logger.Log(1, " connection exception ({0}) : {1}", "", e.Message);
|
||||
}
|
||||
|
||||
if ( sftpClient == null)
|
||||
{
|
||||
Logger.Log(1, " null connection exception. Transfer failed.");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
sftpClient.UploadFile(
|
||||
ms,
|
||||
filename,
|
||||
uploaded =>
|
||||
{
|
||||
Logger.Log(5, $"Uploaded {(double)uploaded / ms.Length * 100}% of the file.");
|
||||
});
|
||||
}
|
||||
catch (Renci.SshNet.Common.SshException e)
|
||||
{
|
||||
Logger.Log(0, " SSH upload Exception {0}:{1}", e.Message, e.InnerException.Message);
|
||||
}
|
||||
Logger.Log(1, " -- uploaded: {0} ({3}KB) to {1}:{2}", filename, host, port, (ms.Length / 1024));
|
||||
|
||||
sftpClient.Disconnect();
|
||||
Logger.Log(" SSH Disconnected");
|
||||
try
|
||||
{
|
||||
sftpClient?.Dispose();
|
||||
}
|
||||
catch { }
|
||||
|
||||
return; // success
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Log(0, "SFTP exception {0}:{1}", e.Message, e.InnerException.Message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static void Upload_stream_linear(MemoryStream ms, string filename, string host, int port, string username, string password)
|
||||
{
|
||||
|
||||
int attempts = 0;
|
||||
int maxAttempts = 5;
|
||||
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var sftpClient = CreateClient(host, port, username, password))
|
||||
{
|
||||
attempts++;
|
||||
try
|
||||
{
|
||||
sftpClient.Connect();
|
||||
}
|
||||
catch (Renci.SshNet.Common.SshConnectionException e)
|
||||
{
|
||||
Logger.Log(1, " connection exception ({0}) : {1}", attempts, e.Message);
|
||||
}
|
||||
|
||||
//------------
|
||||
if (!sftpClient.IsConnected)
|
||||
{
|
||||
Logger.Log(1, " connection failure {0}", attempts);
|
||||
if (attempts < 10) { Thread.Sleep(TimeSpan.FromSeconds(5)); continue; } else { break; };
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
sftpClient.UploadFile(
|
||||
ms,
|
||||
filename,
|
||||
uploaded =>
|
||||
{
|
||||
Logger.Log(5, $"Uploaded {(double)uploaded / ms.Length * 100}% of the file.");
|
||||
});
|
||||
}
|
||||
catch (Renci.SshNet.Common.SshException e)
|
||||
{
|
||||
Logger.Log(0, " SSH upload Exception {0}:{1}", e.Message, e.InnerException.Message);
|
||||
}
|
||||
Logger.Log(1, " -- uploaded: {0} ({3}KB) to {1}:{2}", filename, host, port, (ms.Length / 1024));
|
||||
sftpClient.Disconnect();
|
||||
Logger.Log(" SSH Disconnected");
|
||||
return; // success
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Log(0, "SFTP exception {0}:{1}", e.Message, e.InnerException.Message);
|
||||
}
|
||||
|
||||
attempts++;
|
||||
if (attempts >= maxAttempts)
|
||||
{
|
||||
Logger.Log(0, ("Failed to Connect after 10 attempts."));
|
||||
return;
|
||||
}
|
||||
Logger.Log(1, " ...retrying ({0})", attempts);
|
||||
Thread.Sleep(TimeSpan.FromSeconds(5));
|
||||
} // end of while true/do forever
|
||||
}
|
||||
|
||||
public static void Upload_stream_old( MemoryStream ms, string filename, string host, int port, string username, string password)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var sftpClient = new SftpClient(host, port, username, password))
|
||||
//using (var fs = new FileStream(fileToUpload, FileMode.Open))
|
||||
{
|
||||
sftpClient.OperationTimeout = TimeSpan.FromSeconds(30);
|
||||
sftpClient.ConnectionInfo.Timeout = TimeSpan.FromSeconds(30);
|
||||
|
||||
int attempts = 0;
|
||||
do
|
||||
{
|
||||
attempts++;
|
||||
try
|
||||
{
|
||||
sftpClient.Connect();
|
||||
}
|
||||
catch (Renci.SshNet.Common.SshConnectionException e)
|
||||
{
|
||||
Logger.Log(1," retrying ({0}) : {1}",attempts, e.Message);
|
||||
Thread.Sleep(TimeSpan.FromSeconds(5));
|
||||
}
|
||||
}
|
||||
while (attempts < 10 && !sftpClient.IsConnected);
|
||||
|
||||
if (attempts >= 10)
|
||||
{
|
||||
throw new Exception("Failed to Connect after 10 attempts.");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Logger.Log(" SSH Connected");
|
||||
|
||||
try
|
||||
{
|
||||
sftpClient.UploadFile(
|
||||
ms,
|
||||
filename,
|
||||
uploaded =>
|
||||
{
|
||||
Logger.Log(5, $"Uploaded {(double)uploaded / ms.Length * 100}% of the file.");
|
||||
});
|
||||
}
|
||||
catch (Renci.SshNet.Common.SshException e)
|
||||
{
|
||||
Logger.Log(0, " SSH upload Exception {0}:{1}", e.Message, e.InnerException.Message);
|
||||
}
|
||||
Logger.Log(" SSH Disconnected");
|
||||
sftpClient.Disconnect();
|
||||
}
|
||||
|
||||
}
|
||||
Logger.Log(1, " -- uploaded: {0} ({3}KB) to {1}:{2}", filename, host, port, ( ms.Length/1024) );
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Log(e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Upload_file(string fileToUpload, string host, int port, string username, string password)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var sftpClient = new SftpClient(host, port, username, password))
|
||||
using (var fs = new FileStream(fileToUpload, FileMode.Open))
|
||||
{
|
||||
sftpClient.OperationTimeout = TimeSpan.FromSeconds(30);
|
||||
int attempts = 0;
|
||||
do
|
||||
{
|
||||
try
|
||||
{
|
||||
attempts += 1;
|
||||
sftpClient.Connect();
|
||||
}
|
||||
catch (Renci.SshNet.Common.SshConnectionException e)
|
||||
{
|
||||
Logger.Log(1, " retrying in 5s ({0}) : {1}", attempts, e.Message);
|
||||
Thread.Sleep(TimeSpan.FromSeconds(5));
|
||||
}
|
||||
} while (attempts < 10 && !sftpClient.IsConnected);
|
||||
Logger.Log(" SSH Connected");
|
||||
|
||||
try
|
||||
{
|
||||
sftpClient.UploadFile(
|
||||
fs,
|
||||
"/Doug/" + Path.GetFileName(fileToUpload),
|
||||
uploaded =>
|
||||
{
|
||||
Logger.Log(5,$"Uploaded {(double)uploaded / fs.Length * 100}% of the file.");
|
||||
});
|
||||
}
|
||||
catch (Renci.SshNet.Common.SshException e)
|
||||
{
|
||||
Logger.Log(0, " SSH Exception {0}:{1}", e.Message, e.InnerException.Message);
|
||||
}
|
||||
|
||||
sftpClient.Disconnect();
|
||||
}
|
||||
Logger.Log(1," uploaded: {0}", fileToUpload);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user