Исходные коды
Серверная часть.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.Net;
using System.Net.Sockets;
using System.Net.Security;
using System.Diagnostics;
using System.Security;
using System.ComponentModel;
using System.Security.Principal;
using System.Security.Authentication;
namespace Volovich_1_lab_server
{
class Program
{
static void Main(string[] args)
{
int counter = 0;
string ipStr = "127.0.0.1";
int MaxThreadsCount = Environment.ProcessorCount * 4;
ThreadPool.SetMaxThreads(MaxThreadsCount, MaxThreadsCount);
ThreadPool.SetMinThreads(2, 2);
IPAddress ipAddr = IPAddress.Parse(ipStr);
Int32 port = 13234;
IPEndPoint endPoint = new IPEndPoint(ipAddr, port);
TcpListener tcpServer = new TcpListener(endPoint);
try {
tcpServer.Start();
while (true)
{
Console.Write("\nWaiting for a connection... ");
ThreadPool.QueueUserWorkItem(NewClient, tcpServer.AcceptTcpClient());
counter++;
Console.Write("\nConnection №" + counter.ToString() + "!");
}
}
catch(Exception ex)
{
Console.WriteLine("Не удалось запустить сервер: "+ex.Message);
}
tcpServer.Stop();
Console.ReadLine();
}
static void NewClient(object client_obj)
{
TcpClient client = client_obj as TcpClient;
bool auth = false;
string domain = "", login = "", password = "";
try
{
NetworkStream tcpStream = client.GetStream();
// Аутентификация клиента
WindowsIdentity wi = null;
byte[] bt = new byte[2048];
NegotiateStream secStream = new NegotiateStream(client.GetStream());
NetworkCredential nc = (NetworkCredential)CredentialCache.DefaultCredentials;
secStream.AuthenticateAsServer(nc, ProtectionLevel.None, TokenImpersonationLevel.Impersonation);
wi = (WindowsIdentity)secStream.RemoteIdentity;
IIdentity id = secStream.RemoteIdentity;
string username = id.Name;
if (wi.IsAuthenticated)
{
username = wi.Name;
Console.WriteLine("Клиент аутентифицирован");
int bytesRead = 0;
byte[] authByte;
authByte = new byte[client.ReceiveBufferSize];
bytesRead = secStream.Read(authByte, 0, client.ReceiveBufferSize);
domain = Encoding.Unicode.GetString(authByte).Replace("\0","").Trim();
Console.WriteLine("Клиент-домен:" + domain);
byte[] sendByte2 = Encoding.Unicode.GetBytes("OK\n");
secStream.Write(sendByte2, 0, sendByte2.Length);
Array.Clear(authByte, 0, authByte.Length);
authByte = new byte[0];
authByte = new byte[client.ReceiveBufferSize];
bytesRead = secStream.Read(authByte, 0, client.ReceiveBufferSize);
login = Encoding.Unicode.GetString(authByte).Replace("\0", "").Trim();
Console.WriteLine("Клиент-логин:" + login);
sendByte2 = Encoding.Unicode.GetBytes("OK\n");
secStream.Write(sendByte2, 0, sendByte2.Length);
Array.Clear(authByte, 0, authByte.Length);
authByte = new byte[0];
authByte = new byte[client.ReceiveBufferSize];
bytesRead = secStream.Read(authByte, 0, client.ReceiveBufferSize);
password = Encoding.Unicode.GetString(authByte).Replace("\0", "").Trim();
Console.WriteLine("Клиент-пароль:" + password);
sendByte2 = Encoding.Unicode.GetBytes("OK\n");
secStream.Write(sendByte2, 0, sendByte2.Length);
}
else
{
Console.WriteLine("Клиент не аутентифицирован");
return;
}
bool nslookup = false;
System.Diagnostics.Process proc = new System.Diagnostics.Process();
try
{
proc.StartInfo.FileName = @"C:\Windows\System32\cmd.exe";
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.RedirectStandardInput = true;
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.WorkingDirectory = @"C:\Windows\System32";
proc.StartInfo.Domain = domain;
proc.StartInfo.UserName = login;
SecureString pass = new SecureString();
for (int j = 0; j < password.Length; j++)
pass.AppendChar(password[j]);
proc.StartInfo.Password = pass;
proc.Start();
byte[] sendByte = Encoding.Unicode.GetBytes("success auth");
secStream.Write(sendByte, 0, sendByte.Length);
Console.WriteLine("Успешный запуск консоли. Пользователь:"+login);
}
catch (Exception ex)
{
Console.WriteLine("Ошибка запуска консоли:" + ex.Message);
byte[] sendByte = Encoding.Unicode.GetBytes(ex.Message);
secStream.Write(sendByte, 0, sendByte.Length);
client.Close();
return;
}
Thread writer = new Thread(func);
MyClass myc = new MyClass();
myc.proc = proc;
myc.stream = secStream;
writer.Start(myc);
Thread writerErr = new Thread(funcErr);
MyClass mycErr = new MyClass();
mycErr.proc = proc;
mycErr.stream = secStream;
writerErr.Start(mycErr);
while (true)
{
string Data;
byte[] recievByte;
int bytesRead;
recievByte = new byte[client.ReceiveBufferSize];
Array.Clear(recievByte, 0, recievByte.Length);
bytesRead = secStream.Read(recievByte, 0, client.ReceiveBufferSize);
Data = Encoding.Unicode.GetString(recievByte);
Data = Data.Trim();
Data = Data.Replace("\0", "");
Data = Data.ToLower();
Console.WriteLine("\nКоманда: " + Data + "\n");
proc.StandardInput.WriteLine(Data);
proc.StandardInput.Flush();
if (Data.Split(' ')[0] == "exit")
{
Console.WriteLine("Введена команда exit");
if (proc.HasExited)
{
byte[] sendByte2 = Encoding.Unicode.GetBytes("\nexit\n");
secStream.Write(sendByte2, 0, sendByte2.Length);
break;
}
}
}
proc.WaitForExit();
if (tcpStream!=null)
tcpStream.Close();
if (secStream != null)
secStream.Close();
}
catch (Exception ex)
{
Console.WriteLine("Ошибка подключения клиента: " + ex.Message);
}
Console.WriteLine("вышли");
client.Close();
}
private static void func(object obj)
{
MyClass myc = (MyClass)obj;
Process process = (Process)myc.proc;
NegotiateStream stream = (NegotiateStream)myc.stream;
string outputString = "";
while (!(process.StandardOutput.EndOfStream))
{
if (process.HasExited)
{
process.Close();
stream.Close();
break;
}
outputString = process.StandardOutput.ReadLine()+"\n";
Console.WriteLine(outputString);
byte[] sendByte2 = Encoding.Unicode.GetBytes(outputString);
try
{
stream.Write(sendByte2, 0, sendByte2.Length);
}
catch (Exception ex)
{
Console.WriteLine("func exception: "+ex.Message);
process.Close();
stream.Close();
break;
}
}
}
private static void funcErr(object obj)
{
MyClass myc = (MyClass)obj;
Process process = (Process)myc.proc;
NegotiateStream stream = (NegotiateStream)myc.stream;
string outputString = "";
while (!(process.StandardError.EndOfStream))
{
if (process.HasExited)
{
process.Close();
stream.Close();
break;
}
outputString = process.StandardError.ReadLine() + "\n";
Console.WriteLine(outputString);
byte[] sendByte2 = Encoding.Unicode.GetBytes(outputString);
try
{
stream.Write(sendByte2, 0, sendByte2.Length);
}
catch (Exception ex)
{
Console.WriteLine("func exception: " + ex.Message);
process.Close();
stream.Close();
break;
}
}
}
private class MyClass
{
public Process proc;
public NegotiateStream stream;
public MyClass()
{
proc = null;
stream = null;
}
}
}
}
Клиентская часть.
using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.Security.Principal;
using System.Security;
using System.Net.Security;
using System.Security.Authentication;
using System.Security.Principal;
namespace ClientConsole
{
class Program
{
private static TcpClient client;
private static NegotiateStream secStream;
private static bool auth = false;
private static string domain = "";
private static string login = "";
private static string password = "";
static void Main(string[] args)
{
string command="";
Console.WriteLine("Начинайте вводить команды");
while (true)
{
Console.Write("->:");
if ((command = Console.ReadLine()) == "disconnect") {
Console.WriteLine("Разлогинились.");
if (client.Connected)
client.Close();
if (secStream != null)
secStream.Close();
auth = false;
continue; }
if (command == "q") break;
if (auth == false)
{
string ipStr = "172.22.121.196";
Console.Write("IP-адрес:");
ipStr = Console.ReadLine();
if(ipStr!=""){
Console.WriteLine("Будет использован IP-адресс:" + ipStr);
}else{
ipStr = "172.22.121.196";
Console.WriteLine("Будет использован локальный IP-адресс:"+ipStr);
}
do{
Console.Write("Домен:");
domain = Console.ReadLine();
} while (domain == "");
do{
Console.Write("Логин:");
login = Console.ReadLine();
} while (login == "");
do
{
Console.Write("Пароль:");
password = Console.ReadLine();
} while (password == "");
client = new TcpClient();
try {
Console.WriteLine("Будет использован IP-адресс:" + ipStr);
client.Connect(ipStr, 13234);
}
catch (Exception exx){
Console.WriteLine("Server exceprion: " + exx.Message);
continue;
}
try{
secStream = new NegotiateStream(client.GetStream());
NetworkCredential cred = (NetworkCredential)CredentialCache.DefaultCredentials;
secStream.WriteTimeout = 3000;
secStream.ReadTimeout = 3000;
try{
secStream.AuthenticateAsClient(cred, "user-pc", ProtectionLevel.None, TokenImpersonationLevel.Impersonation); // Если аутентификация не пройдена, то выбрасывается исключение
}
catch (System.IO.IOException iex){
Console.WriteLine("Аутентификация не пройдена. "+iex.Message);
continue;
}
Console.WriteLine("Аутентификация пройдена");
byte[] sendByte = Encoding.Unicode.GetBytes(domain);
secStream.Write(sendByte, 0, sendByte.Length);
byte[] recievByte = new byte[client.ReceiveBufferSize];
int bread = secStream.Read(recievByte, 0, client.ReceiveBufferSize);
Array.Clear(sendByte, 0, sendByte.Length);
sendByte = new byte[0];
Array.Clear(recievByte, 0, recievByte.Length);
recievByte = new byte[0];
sendByte = Encoding.Unicode.GetBytes(login);
secStream.Write(sendByte, 0, sendByte.Length);
recievByte = new byte[client.ReceiveBufferSize];
bread = secStream.Read(recievByte, 0, client.ReceiveBufferSize);
Array.Clear(sendByte, 0, sendByte.Length);
sendByte = new byte[0];
Array.Clear(recievByte, 0, recievByte.Length);
recievByte = new byte[0];
sendByte = Encoding.Unicode.GetBytes(password);
secStream.Write(sendByte, 0, sendByte.Length);
recievByte = new byte[client.ReceiveBufferSize];
bread = secStream.Read(recievByte, 0, client.ReceiveBufferSize);
Array.Clear(recievByte, 0, recievByte.Length);
recievByte = new byte[0];
recievByte = new byte[client.ReceiveBufferSize];
bread = secStream.Read(recievByte, 0, client.ReceiveBufferSize);
string result = Encoding.Unicode.GetString(recievByte).Replace("\0","").Trim();
if (result == "success auth"){
Console.WriteLine("Успешная авторизация. Запуск удаленной консоли.");
auth = true;}
else{
Console.WriteLine("Ошибка авторизации." + result);
continue;}
}
catch (InvalidCredentialException) // Аутентификация на сервере не пройдена
{
Console.WriteLine("Аутентификация на сервере не пройдена");
}
}
else
if (auth)
{
try
{
if (command != "")
{
byte[] sendByte = Encoding.Unicode.GetBytes(command);
secStream.Write(sendByte, 0, sendByte.Length);
DateTime dt = DateTime.Now;
Console.WriteLine("");
Console.WriteLine("Время: " + dt.ToString() + " КОМАНДА:" + command);
Thread.Sleep(2000);
}
int bytesRead = 0;
while (true){
Thread.Sleep(1500);
byte[] recievByte = new byte[client.ReceiveBufferSize];
try{
if ((bytesRead = secStream.Read(recievByte, 0, client.ReceiveBufferSize)) <= 0){ break;}
string Data = "";
Data = Encoding.Unicode.GetString(recievByte).Replace("\0","").Trim();
string[] values = Data.Split('\n');
foreach (string value in values)
{
if (value.Trim() == ""){
Console.WriteLine("");
continue;
}
if (value.ToLower() == "exit") {
if (client.Connected) {
client.Close();
auth = false;
break;
}
}
Console.WriteLine(value.Trim());
}
}
catch (Exception tEx){break;}
}
}
catch (Exception ex)
{
Console.WriteLine("Exceprion2: " + ex.Message);
}
}
if (!client.Connected && !auth)
{
Console.WriteLine("Отключились.");
break;
}
}
Console.WriteLine("Завершение программы.");
Console.ReadKey();
}
}
}
