diff --git a/OCUploadDownloadServer/OCDaemonHoster/OCDaemonHoster.csproj b/OCUploadDownloadServer/OCDaemonHoster/OCDaemonHoster.csproj new file mode 100644 index 0000000..26a5dff --- /dev/null +++ b/OCUploadDownloadServer/OCDaemonHoster/OCDaemonHoster.csproj @@ -0,0 +1,61 @@ + + + + {08F6D48F-9EAB-4861-9D50-F9F1BC10C074} + Debug + AnyCPU + Exe + OCDaemonHoster + OCDaemonHoster + v4.0 + Properties + ..\Icon2.ico + False + + + x86 + + + bin\Debug\ + True + Full + False + True + DEBUG;TRACE + + + bin\Release\ + False + None + True + False + TRACE + + + + + 3.5 + + + + 3.5 + + + 3.5 + + + + 3.5 + + + + + + + + + + + + + \ No newline at end of file diff --git a/OCUploadDownloadServer/OCDaemonHoster/OCNetworkClient.cs b/OCUploadDownloadServer/OCDaemonHoster/OCNetworkClient.cs new file mode 100644 index 0000000..ad921af --- /dev/null +++ b/OCUploadDownloadServer/OCDaemonHoster/OCNetworkClient.cs @@ -0,0 +1,179 @@ +/* + * Created by SharpDevelop. + * User: Alfred + * Date: 28/12/2019 + * Time: 18:34 + * + * To change this template use Tools | Options | Coding | Edit Standard Headers. + */ +using System; +using System.Net; +using System.Net.Sockets; +using System.Threading; + +namespace captainalm.network.oc +{ + public class OCNetworkClient { + private Socket sock; + private IPEndPoint remoteAddress; + private IPEndPoint localAddress; + private Boolean connected; + + internal OCNetworkClient(Socket socketIn) { + sock = socketIn; + if (sock != null) { + if (sock.Connected) { + remoteAddress = (IPEndPoint) sock.RemoteEndPoint; + localAddress = (IPEndPoint) sock.LocalEndPoint; + connected = true; + } else { + connected = false; + } + } else { + connected = false; + } + } + + public IPEndPoint getRemoteAddress() { + return remoteAddress; + } + + public IPEndPoint getLocalAddress() { + return localAddress; + } + + public Socket getSocket() { + return sock; + } + + public Boolean sendHandshake(String chIn) { + if (chIn == null) { + return false; + } + if (connected && chIn.Length == 1) { + try { + var bts = System.Text.Encoding.ASCII.GetBytes(chIn.Substring(0,1)); + sock.Send(bts,bts.Length, SocketFlags.None); + return true; + } catch (SocketException e) { + connected = false; + } + } + return false; + } + + public String receiveProtocol() { + if (connected) { + try { + var bts = new Byte[1]; + sock.Receive(bts,1,SocketFlags.None); + String prot = System.Text.Encoding.ASCII.GetString(bts); + return prot; + } catch (SocketException e) { + connected = false; + } + } + return ""; + } + + public Boolean receiveHandshake(String chIn) { + if (chIn == null) { + return false; + } + if (connected && chIn.Length == 1) { + try { + var bts = new Byte[1]; + sock.Receive(bts,1,SocketFlags.None); + Boolean test = System.Text.Encoding.ASCII.GetString(bts).Equals(chIn.Substring(0,1)); + return test; + } catch (SocketException e) { + connected = false; + } + } + return false; + } + + public Boolean sendData(String data) { + if (data == null) { + return false; + } + if (connected && data.Length > 0) { + try { + var bts = System.Text.Encoding.ASCII.GetBytes(data); + sock.Send(bts,bts.Length, SocketFlags.None); + return true; + } catch (SocketException e) { + connected = false; + } + } + return false; + } + + public String receiveData() { + String toret = ""; + if (connected) { + try { + int lout = 0; + while (sock.Available < 1 && lout < 50) { + try { + Thread.Sleep(100); + } catch (ThreadInterruptedException e) { + } + lout++; + } + int len = sock.Available; + byte[] bufferIn = new byte[len]; + int res = sock.Receive(bufferIn,len,SocketFlags.None); + if (res == 0 && len != 0) { + connected = false; + } else { + connected = true; + } + toret = System.Text.Encoding.ASCII.GetString(bufferIn); + } catch (SocketException e) { + connected = false; + toret = ""; + } + } + return toret; + } + + public void invokeConnectionCheck() { + try { + byte[] bufferIn = new byte[1]; + int res = sock.Receive(bufferIn,1,SocketFlags.None); + if (res == 0) { + connected = false; + } else { + connected = true; + } + } catch (SocketException e) { + connected = false; + } + } + + public Boolean getIsConnected() { + return connected; + } + + public void shutdown() { + if (connected) { + try { + sock.Shutdown(SocketShutdown.Both); + } catch (SocketException e) { + } + } + } + + public void close() { + if (connected) { + try { + sock.Close(); + } catch (SocketException e) { + } + } + connected = false; + sock = null; + } + } +} diff --git a/OCUploadDownloadServer/OCDaemonHoster/OCNetworkListener.cs b/OCUploadDownloadServer/OCDaemonHoster/OCNetworkListener.cs new file mode 100644 index 0000000..4e8e53b --- /dev/null +++ b/OCUploadDownloadServer/OCDaemonHoster/OCNetworkListener.cs @@ -0,0 +1,146 @@ +/* + * Created by SharpDevelop. + * User: Alfred + * Date: 28/12/2019 + * Time: 19:08 + * + * To change this template use Tools | Options | Coding | Edit Standard Headers. + */ +using System; +using System.Net; +using System.Net.NetworkInformation; +using System.Net.Sockets; +using System.Threading; + +namespace captainalm.network.oc +{ + public class OCNetworkListener { + private Socket sSock; + private Thread lThread; + private Boolean listening; + private OCNetworkClient acceptedClient; + private Boolean cWaiting; + private Boolean cExists; + private Object slockcl = new Object(); + private IPEndPoint listeningAddress; + + public OCNetworkListener(IPEndPoint addressIn) { + lThread = new Thread(new ThreadStart(this.run)); + lThread.IsBackground = true; + listening = false; + listeningAddress = addressIn; + try { + if (Environment.OSVersion.Version.Major >= 6 && addressIn.Address.Equals(IPAddress.IPv6Any)) { + sSock = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp); + sSock.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, false); + } else { + sSock = new Socket(addressIn.AddressFamily, SocketType.Stream, ProtocolType.Tcp); + } + sSock.ReceiveBufferSize = Int16.MaxValue; + sSock.SendBufferSize = Int16.MaxValue; + sSock.ReceiveTimeout = 5000; + sSock.SendTimeout = 5000; + } catch (SocketException e) { + sSock = null; + } + try { + if (sSock == null) { + throw new SocketException(0); + } + sSock.Bind(addressIn); + sSock.Listen(1); + listening = true; + } catch (SocketException e) { + } + if (listening) { + lThread.Start(); + } + } + + public OCNetworkClient getAcceptedClient() { + OCNetworkClient toret = null; + lock (slockcl) { + if (cWaiting && acceptedClient != null) { + cExists = true; + cWaiting = false; + toret = acceptedClient; + } + } + return toret; + } + + public void returnAcceptedClient(OCNetworkClient toRet) { + lock (slockcl) { + if (cExists && toRet == acceptedClient) { + toRet.shutdown(); + toRet.close(); + toRet = null; + cExists = false; + } + } + } + + public IPEndPoint getListeningAddress() { + return listeningAddress; + } + + public Boolean getIsThereGottenClient() { + return cExists; + } + + public Boolean getIsThereAcceptedClient() { + return cWaiting; + } + + public Boolean getIsListening() { + return listening; + } + + public void close() { + if (acceptedClient != null && (cWaiting == true)) { + this.getAcceptedClient(); + } + if (acceptedClient != null && (cExists == true)) { + this.returnAcceptedClient(acceptedClient); + } + if (listening) { + sSock.Close(); + } + listening = false; + while (lThread.IsAlive) { + try { + Thread.Sleep(100); + } catch (ThreadInterruptedException e) { + } + } + sSock = null; + } + + protected void run() { + while (listening) { + while (cExists) { + try { + Thread.Sleep(100); + } catch (ThreadInterruptedException e) { + } + } + try { + Socket sa = sSock.Accept(); + sa.ReceiveBufferSize = Int16.MaxValue; + sa.SendBufferSize = Int16.MaxValue; + sa.ReceiveTimeout = 5000; + sa.SendTimeout = 5000; + acceptedClient = new OCNetworkClient(sa); + cWaiting = true; + while (cWaiting) { + try { + Thread.Sleep(100); + } catch (ThreadInterruptedException e) { + } + } + } catch (SocketException e) { + } + } + } + } +} diff --git a/OCUploadDownloadServer/OCDaemonHoster/Program.cs b/OCUploadDownloadServer/OCDaemonHoster/Program.cs new file mode 100644 index 0000000..fe0e3d6 --- /dev/null +++ b/OCUploadDownloadServer/OCDaemonHoster/Program.cs @@ -0,0 +1,318 @@ +/* + * Created by SharpDevelop. + * User: Alfred + * Date: 28/12/2019 + * Time: 17:53 + * + * To change this template use Tools | Options | Coding | Edit Standard Headers. + */ +using System; +using System.Collections.Generic; +using System.IO; +using System.Net; +using System.Net.NetworkInformation; +using System.Net.Sockets; +using System.Threading; + +using captainalm.network.oc; + +namespace OCDaemonHoster +{ + public class Program { + public static String ipAddress; + public static int port; + public static int version = 0; + + public static Dictionary settings = new Dictionary(); + public static String cache; + public static List addrsv4; + public static List addrsv6; + + public static void Main(String[] args) { + writeLine("Open Computers Daemon Hoster (OCDH) : (C) Captain ALM 2019."); + writeLine("License: BSD 2-Clause."); + addrsv4 = getInterfaceAddresses(4); + addrsv6 = getInterfaceAddresses(6); + if (args != null) { + if (args.Length < 2) { + printUsage(); + Environment.Exit(1); + } else { + decryptArgs(args); + if (settings.ContainsKey("mode")) { + if (settings["mode"].ToLower().Equals("h")) { + hoster(); + } else if (settings["mode"].ToLower().Equals("a")) { + accessor(); + } + } + } + } else { + printUsage(); + Environment.Exit(1); + } + Environment.Exit(0); + } + + public static void hoster() { + writeLine("Hosting Mode!"); + IPEndPoint address = new IPEndPoint(IPAddress.Parse(ipAddress),port); + writeLine("[INFO] : Address Setup!"); + if (settings.ContainsKey("target")) { + writeLine("[INFO] : Target File : " + settings["target"]); + } + cache = ""; + if (settings.ContainsKey("cache") && settings.ContainsKey("target")) { + try { + cache = loadFile(settings["target"]); + writeLine("[INFO] : File Cached!"); + } catch (IOException e) { + } + } + OCNetworkListener server = new OCNetworkListener(address); + writeLine("[INFO] : Listener Started!"); + writeLine("[INFO] : Listener 'Address:Port' : " + server.getListeningAddress().Address.ToString() + + ":" + server.getListeningAddress().Port); + writeLine("[INFO] : Open Addresses 'Address:Port' :"); + if (version == 4 && ipAddress.Equals(IPAddress.Any.ToString())) { + foreach (String c in addrsv4) { + writeLine(c + ":" + port); + } + } else if (version == 6 && ipAddress.Equals(IPAddress.IPv6Any.ToString())) { + foreach (String c in addrsv6) { + writeLine(c + ":" + port); + } + } else if (version == 0 && ipAddress.Equals(IPAddress.IPv6Any.ToString())) { + List addrsT = new List(); + addrsT.AddRange(addrsv4); + addrsT.AddRange(addrsv6); + foreach (String c in addrsT) { + writeLine(c + ":" + port); + } + addrsT.Clear(); + addrsT = null; + } else { + writeLine(ipAddress + ":" + port); + } + Boolean exec = true; + while (exec) { + if (server.getIsThereAcceptedClient()) { + OCNetworkClient client = server.getAcceptedClient(); + writeLine("[INFO] : Client Accepted!"); + writeLine("[INFO] : Client 'Address:Port' : " + client.getRemoteAddress().Address.ToString() + + ":" + client.getRemoteAddress().Port); + handleProtocol(client); + server.returnAcceptedClient(client); + writeLine("[INFO] : Client Disposed!"); + } + try { + Thread.Sleep(100); + } catch (ThreadInterruptedException e) { + } + } + server.close(); + server = null; + } + + public static void accessor() { + throw new NotImplementedException("Method not Implemented."); + } + + public static void handleProtocol(OCNetworkClient clientIn) { + String prot = clientIn.receiveProtocol(); + if (prot.Equals("1")) { + writeLine("[INFO] : Sending..."); + String data = ""; + if (settings.ContainsKey("target") && !settings.ContainsKey("cache")) { + writeLine("[INFO] : Sending : Loading Data..."); + try { + data = loadFile(settings["target"]); + } catch (IOException e) { + data = ""; + } + } else if (settings.ContainsKey("cache")) { + writeLine("[INFO] : Sending : Retrieving Data..."); + data = cache; + } + writeLine("[INFO] : Sending : Sending Handshake..."); + clientIn.sendHandshake("1"); + writeLine("[INFO] : Sending : Waiting For Handshake..."); + Boolean hand1Succ = clientIn.receiveHandshake("1"); + if (hand1Succ) { + writeLine("[INFO] : Sending : Sending Data..."); + clientIn.sendData(data); + writeLine("[INFO] : Sending : Waiting For Handshake..."); + clientIn.receiveHandshake("1"); + } + } else if (prot.Equals("2")) { + writeLine("[INFO] : Receiving..."); + writeLine("[INFO] : Receiving : Sending Handshake..."); + clientIn.sendHandshake("1"); + writeLine("[INFO] : Receiving : Waiting For Data..."); + String data = clientIn.receiveData(); + writeLine("[INFO] : Receiving : Processing Data..."); + if (data.Contains("\r") && !data.Contains("\n")) { + data = data.Replace("\r", "\r\n"); + } + if (data.Contains("\n") && !data.Contains("\r")) { + data = data.Replace("\n", "\r\n"); + } + if (settings.ContainsKey("cache")) { + writeLine("[INFO] : Receiving : Caching Data..."); + cache = data; + } + if (settings.ContainsKey("target")) { + writeLine("[INFO] : Receiving : Saving Data..."); + try { + saveFile(settings["target"], data); + } catch (IOException e) { + } + } + writeLine("[INFO] : Receiving : Sending Handshake..."); + clientIn.sendHandshake("1"); + } + } + + public static String loadFile(String target) { + return System.IO.File.ReadAllText(target, System.Text.Encoding.ASCII); + } + + public static void saveFile(String target, String contents) { + System.IO.File.WriteAllText(target,contents,System.Text.Encoding.ASCII); + } + + public static void decryptArgs(String[] args) { + try { + port = Int32.Parse(args[1]); + } catch (FormatException e) { + port = 0; + } + for (int i = 2; i < args.Length; i++) { + String carg = args[i]; + Boolean hasEquals = carg.Contains("="); + Boolean isSwitch = carg.StartsWith("-"); + String cSwitch = ""; + String cValue = ""; + if (isSwitch && !hasEquals) { + cSwitch = carg.Substring(1).ToLower(); + } else if (isSwitch && hasEquals) { + cSwitch = carg.Substring(1, carg.IndexOf("=")).ToLower(); + cValue = carg.Substring(carg.IndexOf("=") + 1); + } + if (!settings.ContainsKey(cSwitch)) { + settings.Add(cSwitch, cValue); + } + } + try { + var ip = IPAddress.Parse(args[0]); + if (ip.AddressFamily == AddressFamily.InterNetworkV6 && ! args[0].Equals(IPAddress.IPv6Any.ToString())) { + version = 6; + } else if (ip.AddressFamily == AddressFamily.InterNetworkV6 && args[0].Equals(IPAddress.IPv6Any.ToString()) && Environment.OSVersion.Version.Major >= 6) { + version = 0; + } else if (ip.AddressFamily == AddressFamily.InterNetworkV6 && args[0].Equals(IPAddress.IPv6Any.ToString()) && Environment.OSVersion.Version.Major < 6) { + version = 6; + } else { + version = 4; + } + } catch (FormatException ex) { + if (Environment.OSVersion.Version.Major >= 6) { + version = 0; + } else { + version = 4; + } + } + try { + ipAddress = verifyInterface(args[0], version); + } catch (SocketException ex) { + ipAddress = IPAddress.IPv6Any.ToString(); + } + } + + public static List getInterfaceAddresses(int ver) { + List toret = new List(); + var allNetworkInterfaces = NetworkInterface.GetAllNetworkInterfaces(); + foreach (NetworkInterface netc in allNetworkInterfaces) { + if (netc.OperationalStatus == OperationalStatus.Up) { + var ipInfo = netc.GetIPProperties().UnicastAddresses; + foreach (UnicastIPAddressInformation cadd in ipInfo) { + String sadd = ""; + if (cadd.Address.AddressFamily == AddressFamily.InterNetwork && (ver == 4 || ver == 0)) { + sadd = cadd.Address.ToString(); + } else if (cadd.Address.AddressFamily == AddressFamily.InterNetworkV6 && (ver == 6 || ver == 0)) { + sadd = cadd.Address.ToString(); + } + if (sadd != "") { + if (sadd.Contains("%")) { + sadd = sadd.Substring(0, sadd.IndexOf("%")); + } + toret.Add(sadd); + } + } + } + } + return toret; + } + + public static String verifyInterface(String inF, int ver) { + Boolean isContained = false; + List addrsT = new List(); + if (ver == 4 || ver == 0) { + addrsT.AddRange(addrsv4); + } else if (ver == 6 || ver == 0) { + addrsT.AddRange(addrsv6); + } + foreach (String c in addrsT) { + if (c.Equals(inF)) { + isContained = true; + break; + } + } + if (! isContained) { + if (inF.Equals(IPAddress.Any.ToString()) && ver == 4) { + return IPAddress.Any.ToString(); + } + } + addrsT.Clear(); + addrsT = null; + if (isContained) { + return inF; + } else { + return IPAddress.IPv6Any.ToString(); + } + } + + public static void printUsage() { + writeLine(""); + writeLine("Usage:"); + writeLine( + "OCDH.exe [-mode=] [-target=] [-cache] [-enumeration] [-creation] [-deletion]"); + writeLine(""); + writeLine("-mode= : allows to select a Hosting Mode."); + writeLine("-target= : allows to select a file for hosting (File Host Mode Only)."); + writeLine("-cache : caches the target file once (File Host Mode Only)."); + writeLine("-enumeration : allows for file/directory enumeration (File Access Mode Only)."); + writeLine("-creation : allows for file/directory creation (File Access Mode Only)."); + writeLine("-deletion : allows for file/directory deletion (File Access Mode Only)."); + writeLine(""); + writeLine("MODE:"); + writeLine("H : File Host Mode, Hosts a single file for access."); + writeLine("A : File Access Mode, Allows file system access."); + } + + public static void write(String stringIn) { + Console.Out.Write(stringIn); + } + + public static void writeLine(String stringIn) { + Console.Out.WriteLine(stringIn); + } + + public static void writeError(String stringIn) { + Console.Error.Write(stringIn); + } + + public static void writeErrorLine(String stringIn) { + Console.Error.WriteLine(stringIn); + } + } +} \ No newline at end of file diff --git a/OCUploadDownloadServer/OCDaemonHoster/Properties/AssemblyInfo.cs b/OCUploadDownloadServer/OCDaemonHoster/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..19df51b --- /dev/null +++ b/OCUploadDownloadServer/OCDaemonHoster/Properties/AssemblyInfo.cs @@ -0,0 +1,31 @@ +#region Using directives + +using System; +using System.Reflection; +using System.Runtime.InteropServices; + +#endregion + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("OCDaemonHoster")] +[assembly: AssemblyDescription("Open Computers Daemon Hoster")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Captain ALM")] +[assembly: AssemblyProduct("Open Computers Daemon Hoster")] +[assembly: AssemblyCopyright("Copyright (C) Captain ALM 2019")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// This sets the default COM visibility of types in the assembly to invisible. +// If you need to expose a type to COM, use [ComVisible(true)] on that type. +[assembly: ComVisible(false)] + +// The assembly version has following format : +// +// Major.Minor.Build.Revision +// +// You can specify all the values or you can use the default the Revision and +// Build Numbers by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.*")] diff --git a/OCUploadDownloadServer/OCDaemonHoster/app.config b/OCUploadDownloadServer/OCDaemonHoster/app.config new file mode 100644 index 0000000..970c80b --- /dev/null +++ b/OCUploadDownloadServer/OCDaemonHoster/app.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file