You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
280 lines
9.8 KiB
C#
280 lines
9.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Globalization;
|
|
using System.Net;
|
|
using System.Net.Sockets;
|
|
using System.Text;
|
|
using Renci.SshNet.Abstractions;
|
|
using Renci.SshNet.Common;
|
|
using Renci.SshNet.Messages;
|
|
|
|
namespace Renci.SshNet
|
|
{
|
|
/// <summary>
|
|
/// Collection of different extension method
|
|
/// </summary>
|
|
internal static partial class Extensions
|
|
{
|
|
/// <summary>
|
|
/// Determines whether [is null or white space] [the specified value].
|
|
/// </summary>
|
|
/// <param name="value">The value.</param>
|
|
/// <returns>
|
|
/// <c>true</c> if [is null or white space] [the specified value]; otherwise, <c>false</c>.
|
|
/// </returns>
|
|
public static bool IsNullOrWhiteSpace(this string value)
|
|
{
|
|
if (string.IsNullOrEmpty(value)) return true;
|
|
|
|
for (var i = 0; i < value.Length; i++)
|
|
{
|
|
if (!char.IsWhiteSpace(value[i]))
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
internal static byte[] ToArray(this ServiceName serviceName)
|
|
{
|
|
switch (serviceName)
|
|
{
|
|
case ServiceName.UserAuthentication:
|
|
return SshData.Ascii.GetBytes("ssh-userauth");
|
|
case ServiceName.Connection:
|
|
return SshData.Ascii.GetBytes("ssh-connection");
|
|
default:
|
|
throw new NotSupportedException(string.Format("Service name '{0}' is not supported.", serviceName));
|
|
}
|
|
}
|
|
|
|
internal static ServiceName ToServiceName(this byte[] data)
|
|
{
|
|
var sshServiceName = SshData.Ascii.GetString(data, 0, data.Length);
|
|
switch (sshServiceName)
|
|
{
|
|
case "ssh-userauth":
|
|
return ServiceName.UserAuthentication;
|
|
case "ssh-connection":
|
|
return ServiceName.Connection;
|
|
default:
|
|
throw new NotSupportedException(string.Format("Service name '{0}' is not supported.", sshServiceName));
|
|
}
|
|
}
|
|
|
|
internal static BigInteger ToBigInteger(this byte[] data)
|
|
{
|
|
var reversed = new byte[data.Length];
|
|
Buffer.BlockCopy(data, 0, reversed, 0, data.Length);
|
|
return new BigInteger(reversed.Reverse());
|
|
}
|
|
|
|
/// <summary>
|
|
/// Reverses the sequence of the elements in the entire one-dimensional <see cref="Array"/>.
|
|
/// </summary>
|
|
/// <param name="array">The one-dimensional <see cref="Array"/> to reverse.</param>
|
|
/// <returns>
|
|
/// The <see cref="Array"/> with its elements reversed.
|
|
/// </returns>
|
|
internal static T[] Reverse<T>(this T[] array)
|
|
{
|
|
Array.Reverse(array);
|
|
return array;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Prints out
|
|
/// </summary>
|
|
/// <param name="bytes">The bytes.</param>
|
|
internal static void DebugPrint(this IEnumerable<byte> bytes)
|
|
{
|
|
var sb = new StringBuilder();
|
|
|
|
foreach (var b in bytes)
|
|
{
|
|
sb.AppendFormat(CultureInfo.CurrentCulture, "0x{0:x2}, ", b);
|
|
}
|
|
Debug.WriteLine(sb.ToString());
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates an instance of the specified type using that type's default constructor.
|
|
/// </summary>
|
|
/// <typeparam name="T">The type to create.</typeparam>
|
|
/// <param name="type">Type of the instance to create.</param>
|
|
/// <returns>A reference to the newly created object.</returns>
|
|
internal static T CreateInstance<T>(this Type type) where T : class
|
|
{
|
|
if (type == null)
|
|
return null;
|
|
return Activator.CreateInstance(type) as T;
|
|
}
|
|
|
|
internal static void ValidatePort(this uint value, string argument)
|
|
{
|
|
if (value > IPEndPoint.MaxPort)
|
|
throw new ArgumentOutOfRangeException(argument,
|
|
string.Format(CultureInfo.InvariantCulture, "Specified value cannot be greater than {0}.",
|
|
IPEndPoint.MaxPort));
|
|
}
|
|
|
|
internal static void ValidatePort(this int value, string argument)
|
|
{
|
|
if (value < IPEndPoint.MinPort)
|
|
throw new ArgumentOutOfRangeException(argument,
|
|
string.Format(CultureInfo.InvariantCulture, "Specified value cannot be less than {0}.",
|
|
IPEndPoint.MinPort));
|
|
|
|
if (value > IPEndPoint.MaxPort)
|
|
throw new ArgumentOutOfRangeException(argument,
|
|
string.Format(CultureInfo.InvariantCulture, "Specified value cannot be greater than {0}.",
|
|
IPEndPoint.MaxPort));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns a specified number of contiguous bytes from a given offset.
|
|
/// </summary>
|
|
/// <param name="value">The array to return a number of bytes from.</param>
|
|
/// <param name="offset">The zero-based offset in <paramref name="value"/> at which to begin taking bytes.</param>
|
|
/// <param name="count">The number of bytes to take from <paramref name="value"/>.</param>
|
|
/// <returns>
|
|
/// A <see cref="byte"/> array that contains the specified number of bytes at the specified offset
|
|
/// of the input array.
|
|
/// </returns>
|
|
/// <exception cref="ArgumentNullException"><paramref name="value"/> is <c>null</c>.</exception>
|
|
/// <remarks>
|
|
/// When <paramref name="offset"/> is zero and <paramref name="count"/> equals the length of <paramref name="value"/>,
|
|
/// then <paramref name="value"/> is returned.
|
|
/// </remarks>
|
|
public static byte[] Take(this byte[] value, int offset, int count)
|
|
{
|
|
if (value == null)
|
|
throw new ArgumentNullException("value");
|
|
|
|
if (count == 0)
|
|
return Array<byte>.Empty;
|
|
|
|
if (offset == 0 && value.Length == count)
|
|
return value;
|
|
|
|
var taken = new byte[count];
|
|
Buffer.BlockCopy(value, offset, taken, 0, count);
|
|
return taken;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns a specified number of contiguous bytes from the start of the specified byte array.
|
|
/// </summary>
|
|
/// <param name="value">The array to return a number of bytes from.</param>
|
|
/// <param name="count">The number of bytes to take from <paramref name="value"/>.</param>
|
|
/// <returns>
|
|
/// A <see cref="byte"/> array that contains the specified number of bytes at the start of the input array.
|
|
/// </returns>
|
|
/// <exception cref="ArgumentNullException"><paramref name="value"/> is <c>null</c>.</exception>
|
|
/// <remarks>
|
|
/// When <paramref name="count"/> equals the length of <paramref name="value"/>, then <paramref name="value"/>
|
|
/// is returned.
|
|
/// </remarks>
|
|
public static byte[] Take(this byte[] value, int count)
|
|
{
|
|
if (value == null)
|
|
throw new ArgumentNullException("value");
|
|
|
|
if (count == 0)
|
|
return Array<byte>.Empty;
|
|
|
|
if (value.Length == count)
|
|
return value;
|
|
|
|
var taken = new byte[count];
|
|
Buffer.BlockCopy(value, 0, taken, 0, count);
|
|
return taken;
|
|
}
|
|
|
|
public static bool IsEqualTo(this byte[] left, byte[] right)
|
|
{
|
|
if (left == null)
|
|
throw new ArgumentNullException("left");
|
|
if (right == null)
|
|
throw new ArgumentNullException("right");
|
|
|
|
if (left == right)
|
|
return true;
|
|
|
|
if (left.Length != right.Length)
|
|
return false;
|
|
|
|
for (var i = 0; i < left.Length; i++)
|
|
{
|
|
if (left[i] != right[i])
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Trims the leading zero from a byte array.
|
|
/// </summary>
|
|
/// <param name="value">The value.</param>
|
|
/// <returns>
|
|
/// <paramref name="value"/> without leading zeros.
|
|
/// </returns>
|
|
public static byte[] TrimLeadingZeros(this byte[] value)
|
|
{
|
|
if (value == null)
|
|
throw new ArgumentNullException("value");
|
|
|
|
for (var i = 0; i < value.Length; i++)
|
|
{
|
|
if (value[i] == 0)
|
|
continue;
|
|
|
|
// if the first byte is non-zero, then we return the byte array as is
|
|
if (i == 0)
|
|
return value;
|
|
|
|
var remainingBytes = value.Length - i;
|
|
|
|
var cleaned = new byte[remainingBytes];
|
|
Buffer.BlockCopy(value, i, cleaned, 0, remainingBytes);
|
|
return cleaned;
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
public static byte[] Concat(this byte[] first, byte[] second)
|
|
{
|
|
if (first == null || first.Length == 0)
|
|
return second;
|
|
|
|
if (second == null || second.Length == 0)
|
|
return first;
|
|
|
|
var concat = new byte[first.Length + second.Length];
|
|
Buffer.BlockCopy(first, 0, concat, 0, first.Length);
|
|
Buffer.BlockCopy(second, 0, concat, first.Length, second.Length);
|
|
return concat;
|
|
}
|
|
|
|
internal static bool CanRead(this Socket socket)
|
|
{
|
|
return SocketAbstraction.CanRead(socket);
|
|
}
|
|
|
|
internal static bool CanWrite(this Socket socket)
|
|
{
|
|
return SocketAbstraction.CanWrite(socket);
|
|
}
|
|
|
|
internal static bool IsConnected(this Socket socket)
|
|
{
|
|
if (socket == null)
|
|
return false;
|
|
return socket.Connected;
|
|
}
|
|
}
|
|
}
|