MelonVPN base commit

This commit is contained in:
Melon 2020-09-22 23:10:16 +01:00
commit e572273de9
37 changed files with 1845 additions and 0 deletions

373
.gitignore vendored Normal file
View File

@ -0,0 +1,373 @@
# Just throw the Visual Studio and Mono Develop gitignores in the same file and hope for the best
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
[Ll]ogs/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# ASP.NET Scaffolding
ScaffoldingReadMe.txt
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Coverlet is a free, cross platform Code Coverage Tool
coverage*.json
coverage*.xml
coverage*.info
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
# Fody - auto-generated XML schema
FodyWeavers.xsd
#User Specific
*.userprefs
*.usertasks
#Mono Project Files
*.pidb
*.resources
test-results/

42
MelonVPN.sln Normal file
View File

@ -0,0 +1,42 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MelonVPNClient", "MelonVPNClient\MelonVPNClient.csproj", "{071B91A9-6C1D-4A80-98EA-5077E4F66468}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MelonVPNDaemon", "MelonVPNDaemon\MelonVPNDaemon.csproj", "{AFF161B8-AF8E-4A16-9AA4-B692EB0D838E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MelonVPNCore", "MelonVPNCore\MelonVPNCore.csproj", "{B2F2F96C-3E5D-4176-9D66-479F357BC078}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MelonVPNConnectedClientUpdate", "MelonVPNConnectedClientUpdate\MelonVPNConnectedClientUpdate.csproj", "{B318A58E-028B-43A2-A753-2D7FBCA4EE40}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x86 = Debug|x86
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{071B91A9-6C1D-4A80-98EA-5077E4F66468}.Debug|x86.ActiveCfg = Debug|x86
{071B91A9-6C1D-4A80-98EA-5077E4F66468}.Debug|x86.Build.0 = Debug|x86
{071B91A9-6C1D-4A80-98EA-5077E4F66468}.Release|x86.ActiveCfg = Release|x86
{071B91A9-6C1D-4A80-98EA-5077E4F66468}.Release|x86.Build.0 = Release|x86
{AFF161B8-AF8E-4A16-9AA4-B692EB0D838E}.Debug|x86.ActiveCfg = Debug|x86
{AFF161B8-AF8E-4A16-9AA4-B692EB0D838E}.Debug|x86.Build.0 = Debug|x86
{AFF161B8-AF8E-4A16-9AA4-B692EB0D838E}.Release|x86.ActiveCfg = Release|x86
{AFF161B8-AF8E-4A16-9AA4-B692EB0D838E}.Release|x86.Build.0 = Release|x86
{B2F2F96C-3E5D-4176-9D66-479F357BC078}.Debug|x86.ActiveCfg = Debug|x86
{B2F2F96C-3E5D-4176-9D66-479F357BC078}.Debug|x86.Build.0 = Debug|x86
{B2F2F96C-3E5D-4176-9D66-479F357BC078}.Release|x86.ActiveCfg = Release|x86
{B2F2F96C-3E5D-4176-9D66-479F357BC078}.Release|x86.Build.0 = Release|x86
{B318A58E-028B-43A2-A753-2D7FBCA4EE40}.Debug|x86.ActiveCfg = Debug|x86
{B318A58E-028B-43A2-A753-2D7FBCA4EE40}.Debug|x86.Build.0 = Debug|x86
{B318A58E-028B-43A2-A753-2D7FBCA4EE40}.Release|x86.ActiveCfg = Release|x86
{B318A58E-028B-43A2-A753-2D7FBCA4EE40}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(MonoDevelopProperties) = preSolution
Policies = $0
$0.DotNetNamingPolicy = $1
$1.DirectoryNamespaceAssociation = PrefixedHierarchical
$0.StandardHeader = $2
version = 1.0
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,230 @@
using System;
using System.Net.NetworkInformation;
using System.Threading;
using Gtk;
using MelonVPNCore;
public partial class MainWindow : Window
{
private Label statusLabel;
private Button startBtn;
private Button stopBtn;
private Button refreshBtn;
private Button viewClientsBtn;
private Thread startupCheckThread;
private ThreadWrapper wrapper;
public MainWindow() : base(WindowType.Toplevel)
{
Build();
Title = "Melon VPN";
SetSizeRequest(300, 300);
SetDefaultSize(300, 300);
SetPosition(WindowPosition.Center);
Resizable = false;
TypeHint = Gdk.WindowTypeHint.Normal;
Present();
statusLabel = new Label
{
Visible = true,
Text = "Loading..."
};
fixed1.Put(statusLabel, 10, 10);
startBtn = new Button
{
Visible = true,
Label = "Start"
};
startBtn.SetSizeRequest(80, 30);
startBtn.Clicked += OnStartClicked;
fixed1.Put(startBtn, 10, 40);
stopBtn = new Button
{
Visible = true,
Label = "Stop"
};
stopBtn.SetSizeRequest(80, 30);
stopBtn.Clicked += OnStopClicked;
fixed1.Put(stopBtn, 100, 40);
refreshBtn = new Button
{
Visible = true,
Label = "Refresh"
};
refreshBtn.SetSizeRequest(80, 30);
refreshBtn.Clicked += OnRefreshClicked;
fixed1.Put(refreshBtn, 190, 40);
viewClientsBtn = new Button
{
Visible = true,
Label = "View Clients"
};
viewClientsBtn.SetSizeRequest(100, 30);
viewClientsBtn.Clicked += OnViewClientsClicked;
fixed1.Put(viewClientsBtn, 10, 80);
GUISocketServer.Receive += delegate (object sender, ClientResponseState s)
{
Console.WriteLine(s);
Application.Invoke(delegate
{
UpdateStatus(s);
});
};
GUISocketServer.ClientListUpdate += delegate (object sender, ConnectedClient[] clients)
{
Console.WriteLine(clients.Length);
foreach (ConnectedClient c in clients)
{
Console.WriteLine(c.name + "--" + c.ip);
}
};
wrapper = new ThreadWrapper(GUISocketServer.StartServer);
startupCheckThread = new Thread(StartupCheckMethod)
{
IsBackground = true
};
startupCheckThread.Start();
}
string GetVpnInternalIp()
{
if (NetworkInterface.GetIsNetworkAvailable())
{
foreach (NetworkInterface f in NetworkInterface.GetAllNetworkInterfaces())
{
IPInterfaceProperties p = f.GetIPProperties();
IPAddressInformationCollection addressesColl = p.AnycastAddresses;
foreach (IPAddressInformation ip in addressesColl)
{
if (ip.Address.ToString().StartsWith("10.137.248.", StringComparison.CurrentCulture))
{
return ip.Address.ToString();
}
}
}
}
return "";
}
void StartupCheckMethod()
{
ClientResponseState s = Client.SendDataMessage(DataMessage.Status);
Console.WriteLine(s);
Application.Invoke(delegate
{
UpdateStatus(s);
});
}
void Refresh()
{
ClientResponseState s = Client.SendDataMessage(DataMessage.Status);
switch (s)
{
case ClientResponseState.Error:
case ClientResponseState.ServerError:
UpdateStatus(s);
MessageDialog md = new MessageDialog(this,
DialogFlags.DestroyWithParent, MessageType.Error,
ButtonsType.Ok, "Error stopping VPN. Is the daemon running?");
md.Run();
md.Destroy();
break;
case ClientResponseState.Online:
case ClientResponseState.Offline:
UpdateStatus(s);
break;
}
}
void UpdateStatus(ClientResponseState s)
{
switch (s)
{
case ClientResponseState.Error:
statusLabel.Text = "Client Error";
break;
case ClientResponseState.ServerError:
statusLabel.Text = "Server Error";
break;
case ClientResponseState.Blank:
statusLabel.Text = "No reply";
break;
case ClientResponseState.Online:
statusLabel.Text = "Online - " + GetVpnInternalIp();
break;
case ClientResponseState.Offline:
statusLabel.Text = "Offline";
break;
default:
statusLabel.Text = "Unknown";
break;
}
}
protected void OnDeleteEvent(object sender, DeleteEventArgs a)
{
if (wrapper != null)
{
wrapper.Kill();
wrapper.Join();
}
Application.Quit();
a.RetVal = true;
}
void OnStartClicked(object sender, EventArgs e)
{
ClientResponseState s = Client.SendDataMessage(DataMessage.Start);
switch (s)
{
case ClientResponseState.Error:
case ClientResponseState.ServerError:
case ClientResponseState.Offline:
UpdateStatus(s);
MessageDialog md = new MessageDialog(this,
DialogFlags.DestroyWithParent, MessageType.Error,
ButtonsType.Ok, "Error starting VPN. Is the daemon running?");
md.Run();
md.Destroy();
break;
}
}
void OnStopClicked(object sender, EventArgs e)
{
ClientResponseState s = Client.SendDataMessage(DataMessage.Stop);
switch (s)
{
case ClientResponseState.Error:
case ClientResponseState.ServerError:
case ClientResponseState.Online:
UpdateStatus(s);
MessageDialog md = new MessageDialog(this,
DialogFlags.DestroyWithParent, MessageType.Error,
ButtonsType.Ok, "Error stopping VPN. Is the daemon running?");
md.Run();
md.Destroy();
break;
}
}
void OnRefreshClicked(object sender, EventArgs e)
{
Refresh();
}
void OnViewClientsClicked(object sender, EventArgs e)
{
Refresh();
}
}

View File

@ -0,0 +1,90 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProjectGuid>{071B91A9-6C1D-4A80-98EA-5077E4F66468}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>MelonVPNClient</RootNamespace>
<AssemblyName>MelonVPNClient</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<ReleaseVersion>1.0</ReleaseVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="gtk-sharp, Version=2.4.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
<SpecificVersion>False</SpecificVersion>
<Package>gtk-sharp-2.0</Package>
</Reference>
<Reference Include="gdk-sharp, Version=2.4.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
<SpecificVersion>False</SpecificVersion>
<Package>gtk-sharp-2.0</Package>
</Reference>
<Reference Include="glib-sharp, Version=2.4.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
<SpecificVersion>False</SpecificVersion>
<Package>glib-sharp-3.0</Package>
</Reference>
<Reference Include="glade-sharp, Version=2.4.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
<SpecificVersion>False</SpecificVersion>
<Package>glade-sharp-2.0</Package>
</Reference>
<Reference Include="pango-sharp, Version=2.4.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
<SpecificVersion>False</SpecificVersion>
<Package>gtk-sharp-3.0</Package>
</Reference>
<Reference Include="atk-sharp, Version=2.4.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
<SpecificVersion>False</SpecificVersion>
<Package>gtk-sharp-2.0</Package>
</Reference>
<Reference Include="Mono.Posix" />
<Reference Include="gio-sharp, Version=3.0.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
<Package>gio-sharp-3.0</Package>
</Reference>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="gtk-gui\gui.stetic">
<LogicalName>gui.stetic</LogicalName>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<Compile Include="gtk-gui\generated.cs" />
<Compile Include="MainWindow.cs" />
<Compile Include="gtk-gui\MainWindow.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MelonVPNCore\MelonVPNCore.csproj">
<Project>{B2F2F96C-3E5D-4176-9D66-479F357BC078}</Project>
<Name>MelonVPNCore</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="melonvpnclient">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<None Include="melonvpn.desktop">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>

15
MelonVPNClient/Program.cs Normal file
View File

@ -0,0 +1,15 @@
using Gtk;
namespace MelonVPNClient
{
class MainClass
{
public static void Main(string[] args)
{
Application.Init();
MainWindow win = new MainWindow();
win.Show();
Application.Run();
}
}
}

View File

@ -0,0 +1,26 @@
using System.Reflection;
using System.Runtime.CompilerServices;
// Information about this assembly is defined by the following attributes.
// Change them to the values specific to your project.
[assembly: AssemblyTitle("MelonVPNClient")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("${AuthorCopyright}")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
// The form "{Major}.{Minor}.*" will automatically update the build and revision,
// and "{Major}.{Minor}.{Build}.*" will update just the revision.
[assembly: AssemblyVersion("1.0.*")]
// The following attributes are used to specify the signing key for the assembly,
// if desired. See the Mono documentation for more information about signing.
//[assembly: AssemblyDelaySign(false)]
//[assembly: AssemblyKeyFile("")]

View File

@ -0,0 +1,29 @@
// This file has been generated by the GUI designer. Do not modify.
public partial class MainWindow
{
private global::Gtk.Fixed fixed1;
protected virtual void Build()
{
global::Stetic.Gui.Initialize(this);
// Widget MainWindow
this.Name = "MainWindow";
this.Title = global::Mono.Unix.Catalog.GetString("MainWindow");
this.WindowPosition = ((global::Gtk.WindowPosition)(4));
// Container child MainWindow.Gtk.Container+ContainerChild
this.fixed1 = new global::Gtk.Fixed();
this.fixed1.Name = "fixed1";
this.fixed1.HasWindow = false;
this.Add(this.fixed1);
if ((this.Child != null))
{
this.Child.ShowAll();
}
this.DefaultWidth = 204;
this.DefaultHeight = 86;
this.Show();
this.DeleteEvent += new global::Gtk.DeleteEventHandler(this.OnDeleteEvent);
}
}

View File

@ -0,0 +1,30 @@
// This file has been generated by the GUI designer. Do not modify.
namespace Stetic
{
internal class Gui
{
private static bool initialized;
internal static void Initialize(Gtk.Widget iconRenderer)
{
if ((Stetic.Gui.initialized == false))
{
Stetic.Gui.initialized = true;
}
}
}
internal class ActionGroups
{
public static Gtk.ActionGroup GetActionGroup(System.Type type)
{
return Stetic.ActionGroups.GetActionGroup(type.FullName);
}
public static Gtk.ActionGroup GetActionGroup(string name)
{
return null;
}
}
}

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<stetic-interface>
<configuration>
<images-root-path>..</images-root-path>
</configuration>
<import>
<widget-library name="glade-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
<widget-library name="../bin/Release/MelonVPNClient.exe" internal="true" />
</import>
<widget class="Gtk.Window" id="MainWindow" design-size="204 86">
<property name="MemberName" />
<property name="Title" translatable="yes">MainWindow</property>
<property name="WindowPosition">CenterOnParent</property>
<signal name="DeleteEvent" handler="OnDeleteEvent" />
<child>
<widget class="Gtk.Fixed" id="fixed1">
<property name="MemberName" />
<property name="HasWindow">False</property>
</widget>
</child>
</widget>
</stetic-interface>

View File

@ -0,0 +1,8 @@
[Desktop Entry]
Categories=Network;
Icon=
Name=Melon VPN
Path=
Terminal=false
Type=Application
Exec=/usr/bin/melonvpnclient

1
MelonVPNClient/melonvpnclient Executable file
View File

@ -0,0 +1 @@
mono /usr/lib/melon-vpn/MelonVPNClient.exe

View File

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProjectGuid>{B318A58E-028B-43A2-A753-2D7FBCA4EE40}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>MelonVPNConnectedClientUpdate</RootNamespace>
<AssemblyName>MelonVPNConnectedClientUpdate</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<ReleaseVersion>1.0</ReleaseVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ExternalConsole>true</ExternalConsole>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ExternalConsole>true</ExternalConsole>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MelonVPNCore\MelonVPNCore.csproj">
<Project>{B2F2F96C-3E5D-4176-9D66-479F357BC078}</Project>
<Name>MelonVPNCore</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>

View File

@ -0,0 +1,13 @@
using System;
using MelonVPNCore;
namespace MelonVPNConnectedClientUpdate
{
class MainClass
{
public static void Main(string[] args)
{
Client.SendCustomMessage(Messages.GetClientListMessage(Console.ReadLine()));
}
}
}

View File

@ -0,0 +1,26 @@
using System.Reflection;
using System.Runtime.CompilerServices;
// Information about this assembly is defined by the following attributes.
// Change them to the values specific to your project.
[assembly: AssemblyTitle("MelonVPNConnectedClientUpdate")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("${AuthorCopyright}")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
// The form "{Major}.{Minor}.*" will automatically update the build and revision,
// and "{Major}.{Minor}.{Build}.*" will update just the revision.
[assembly: AssemblyVersion("1.0.*")]
// The following attributes are used to specify the signing key for the assembly,
// if desired. See the Mono documentation for more information about signing.
//[assembly: AssemblyDelaySign(false)]
//[assembly: AssemblyKeyFile("")]

41
MelonVPNCore/Client.cs Normal file
View File

@ -0,0 +1,41 @@
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace MelonVPNCore
{
public static class Client
{
public static ClientResponseState SendDataMessage(DataMessage msg) => SendDataMessage(msg, false);
public static ClientResponseState SendDataMessage(DataMessage msg, bool IsSendingFromDaemon) => SendCustomMessage(Messages.GetMessage(msg), IsSendingFromDaemon);
public static ClientResponseState SendCustomMessage(string msg) => SendCustomMessage(msg, false);
public static ClientResponseState SendCustomMessage(string msg, bool IsSendingFromDaemon)
{
IPHostEntry host = Dns.GetHostEntry("localhost");
IPAddress ipAddress = host.AddressList[0];
IPEndPoint remoteEndPoint = new IPEndPoint(ipAddress, IsSendingFromDaemon ? 22036 : 22035);
try
{
if (msg == Messages.EOF || msg == "") return ClientResponseState.Blank;
Socket client = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
client.Connect(remoteEndPoint);
client.ReceiveTimeout = 5000;
client.SendTimeout = 5000;
byte[] bytes = Encoding.ASCII.GetBytes(msg);
client.Send(bytes);
client.Close();
return ClientResponseState.Sent;
}
catch (Exception e)
{
Console.WriteLine(e);
return ClientResponseState.Error;
}
}
}
}

View File

@ -0,0 +1,20 @@
using System.Collections.Generic;
using Newtonsoft.Json.Linq;
namespace MelonVPNCore
{
public static class ClientListParser
{
public static ConnectedClient[] Parse(string json)
{
List<ConnectedClient> clients = new List<ConnectedClient>();
JArray a = JArray.Parse(json);
foreach (JObject o in a.Children<JObject>())
{
clients.Add(new ConnectedClient(o.GetValue("Name").ToString(), o.GetValue("IP").ToString()));
}
return clients.ToArray();
}
}
}

View File

@ -0,0 +1,13 @@
namespace MelonVPNCore
{
public enum ClientResponseState
{
Online,
Offline,
Error,
ServerError,
None,
Blank,
Sent
}
}

View File

@ -0,0 +1,14 @@
namespace MelonVPNCore
{
public class ConnectedClient
{
public readonly string name;
public readonly string ip;
public ConnectedClient(string name, string ip)
{
this.name = name;
this.ip = ip;
}
}
}

View File

@ -0,0 +1,136 @@
using System;
using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
namespace MelonVPNCore
{
public static class DaemonSocketServer
{
public static void StartServer()
{
IPHostEntry host = Dns.GetHostEntry("localhost");
IPAddress ipAddress = host.AddressList[0];
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 22035);
try
{
Socket listener = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
listener.Bind(localEndPoint);
listener.Listen(10);
Process currentVpnProcess = null;
string lastClientUpdate = Messages.EOF;
while (true)
{
Socket handler = listener.Accept();
string data = null;
byte[] bytes = null;
while (true)
{
bytes = new byte[1024];
int bytesRec = handler.Receive(bytes);
data += Encoding.ASCII.GetString(bytes, 0, bytesRec);
if (data.IndexOf(Messages.EOF, StringComparison.CurrentCulture) > -1) break;
}
if (data.StartsWith(Messages.ClientListStartMsg, StringComparison.CurrentCulture))
{
lastClientUpdate = data;
Client.SendCustomMessage(lastClientUpdate, true);
}
else if (data == Messages.StatusMsg)
{
Console.WriteLine("Status requested");
if (currentVpnProcess != null && !currentVpnProcess.HasExited)
{
Console.WriteLine("Sending response: online");
Client.SendDataMessage(DataMessage.Online, true);
Client.SendCustomMessage(lastClientUpdate, true);
}
else
{
Console.WriteLine("Sending response: offline");
Client.SendDataMessage(DataMessage.Offline, true);
}
}
else if (data == Messages.StartMsg)
{
if (currentVpnProcess == null)
{
Console.WriteLine("Starting VPN");
try
{
Console.WriteLine("Starting embedded process");
currentVpnProcess = new Process
{
StartInfo = new ProcessStartInfo("simple-vpn", "client /etc/melon-vpn/client.cfg")
};
currentVpnProcess.Exited += delegate
{
Client.SendDataMessage(DataMessage.Offline, true);
currentVpnProcess = null;
};
currentVpnProcess.Start();
Console.WriteLine("Sending online reply");
Thread.Sleep(1500);
Client.SendDataMessage(DataMessage.Online, true);
}
catch (Exception e)
{
Console.WriteLine("There was an error. But I fixed it.");
Console.WriteLine("It looked like this: " + e);
currentVpnProcess = null;
Client.SendDataMessage(DataMessage.Error, true);
}
}
else
{
Console.WriteLine("VPN already started");
}
}
else if (data == Messages.StopMsg)
{
if (currentVpnProcess != null)
{
Console.WriteLine("Stopping VPN");
try
{
Console.WriteLine("Stopping embedded process");
currentVpnProcess.Kill();
currentVpnProcess = null;
Console.WriteLine("Sending offline reply");
Client.SendDataMessage(DataMessage.Offline, true);
}
catch (Exception e)
{
Console.WriteLine("There was an error. But I fixed it.");
Console.WriteLine("It looked like this: " + e);
currentVpnProcess = null;
Client.SendDataMessage(DataMessage.Error, true);
}
}
else
{
Console.WriteLine("VPN already stopped");
}
}
Client.SendDataMessage(DataMessage.Blank, true);
handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
}
}

View File

@ -0,0 +1,13 @@
namespace MelonVPNCore
{
public enum DataMessage
{
Status,
Online,
Offline,
Start,
Stop,
Blank,
Error
}
}

View File

@ -0,0 +1,68 @@
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace MelonVPNCore
{
public static class GUISocketServer
{
public static event EventHandler<ClientResponseState> Receive;
public static event EventHandler<ConnectedClient[]> ClientListUpdate;
public static void StartServer()
{
IPHostEntry host = Dns.GetHostEntry("localhost");
IPAddress ipAddress = host.AddressList[0];
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 22036);
try
{
Socket listener = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
listener.Bind(localEndPoint);
listener.Listen(10);
while (true)
{
Socket handler = listener.Accept();
string data = "";
byte[] bytes = null;
while (true)
{
bytes = new byte[1024];
int bytesRec = handler.Receive(bytes);
data += Encoding.ASCII.GetString(bytes, 0, bytesRec);
if (data.IndexOf(Messages.EOF, StringComparison.CurrentCulture) > -1) break;
}
ClientResponseState ret = ClientResponseState.None;
if (data == Messages.OnlineMsg) ret = ClientResponseState.Online;
if (data == Messages.OfflineMsg) ret = ClientResponseState.Offline;
if (data == Messages.ErrorMsg) ret = ClientResponseState.ServerError;
Console.WriteLine(data);
if (data.StartsWith(Messages.ClientListStartMsg, StringComparison.CurrentCulture))
{
string jsonWithEof = data.Substring(Messages.ClientListStartMsg.Length);
string jsonData = data.Substring(0, jsonWithEof.Length - Messages.EOF.Length);
Console.WriteLine("clients: " + jsonData);
//ClientListParser.Parse(jsonData);
ConnectedClient[] clients = new ConnectedClient[0];
ClientListUpdate?.Invoke(null, clients);
}
handler.Shutdown(SocketShutdown.Both);
handler.Close();
Receive?.Invoke(null, ret);
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
Console.WriteLine("GUI socket server reathed the end");
}
}
}

View File

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{B2F2F96C-3E5D-4176-9D66-479F357BC078}</ProjectGuid>
<OutputType>Library</OutputType>
<RootNamespace>MelonVPNCore</RootNamespace>
<AssemblyName>MelonVPNCore</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<ReleaseVersion>1.0</ReleaseVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<Compile Include="DaemonSocketServer.cs" />
<Compile Include="ThreadWrapper.cs" />
<Compile Include="Messages.cs" />
<Compile Include="Client.cs" />
<Compile Include="DataMessage.cs" />
<Compile Include="ClientResponseState.cs" />
<Compile Include="GUISocketServer.cs" />
<Compile Include="ClientListParser.cs" />
<Compile Include="ConnectedClient.cs" />
</ItemGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="Newtonsoft.Json">
<HintPath>..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>

29
MelonVPNCore/Messages.cs Normal file
View File

@ -0,0 +1,29 @@
namespace MelonVPNCore
{
public static class Messages
{
public static string EOF = "<EOF>";
public static string Code = "80d168e76f6bd40efe897881f35bcd895459e42a";
public static string StatusMsg = "STATUS::" + Code + EOF;
public static string OnlineMsg = "ONLINE::" + Code + EOF;
public static string OfflineMsg = "OFFLINE::" + Code + EOF;
public static string StartMsg = "START::" + Code + EOF;
public static string StopMsg = "STOP::" + Code + EOF;
public static string ErrorMsg = "ERROR::" + Code + EOF;
public static string ClientListStartMsg = "CLIENTLIST::" + Code + "::";
public static string GetMessage(DataMessage a)
{
if (a == DataMessage.Status) return StatusMsg;
if (a == DataMessage.Online) return OnlineMsg;
if (a == DataMessage.Offline) return OfflineMsg;
if (a == DataMessage.Start) return StartMsg;
if (a == DataMessage.Stop) return StopMsg;
if (a == DataMessage.Error) return ErrorMsg;
if (a == DataMessage.Blank) return EOF;
return EOF;
}
public static string GetClientListMessage(string a) => ClientListStartMsg + a + EOF;
}
}

View File

@ -0,0 +1,140 @@
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
namespace MelonVPNCore
{
public class AsynchronousClient
{
private const int port = 22035;
private ManualResetEvent connectDone = new ManualResetEvent(false);
private ManualResetEvent receiveDone = new ManualResetEvent(false);
private string response = "";
private Socket client;
private void StartClient()
{
// Connect to a remote device.
try
{
IPHostEntry ipHostInfo = Dns.GetHostEntry("127.0.0.1");
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);
client = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
client.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), client);
connectDone.WaitOne();
// Receive the response from the remote device.
Receive(client);
receiveDone.WaitOne();
// Write the response to the console.
Console.WriteLine("Response received : {0}", response);
// Release the socket.
client.Shutdown(SocketShutdown.Both);
client.Close();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
public void Send(string msg)
{
Send(client, msg + "<EOF>");
}
public string Receive()
{
if (client == null) return null;
Receive(client);
receiveDone.WaitOne();
return response;
}
private void ConnectCallback(IAsyncResult ar)
{
try
{
Socket client = (Socket)ar.AsyncState;
client.EndConnect(ar);
Console.WriteLine("Socket connected to {0}", client.RemoteEndPoint.ToString());
connectDone.Set();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
public string Receive()
{
try
{
StateObject state = new StateObject
{
workSocket = client
};
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
}
catch (Exception e)
{
Console.WriteLine(e);
}
receiveDone.WaitOne();
}
private static void ReceiveCallback(IAsyncResult ar)
{
try
{
StateObject state = (StateObject)ar.AsyncState;
Socket client = state.workSocket;
int bytesRead = client.EndReceive(ar);
if (bytesRead > 0)
{
state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
}
else
{
if (state.sb.Length > 1) response = state.sb.ToString();
if (receiveDone != null) receiveDone.Set();
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
private static void Send(Socket client, string data)
{
byte[] byteData = Encoding.ASCII.GetBytes(data);
client.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), client);
}
private static void SendCallback(IAsyncResult ar)
{
try
{
Socket client = (Socket)ar.AsyncState;
int bytesSent = client.EndSend(ar);
Console.WriteLine("Sent {0} bytes to server.", bytesSent);
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
}
}

View File

@ -0,0 +1,10 @@
using System;
namespace MelonVPNCore
{
public class SocketServer
{
public SocketServer()
{
}
}
}

View File

@ -0,0 +1,21 @@
using System.Threading;
namespace MelonVPNCore
{
public class ThreadWrapper
{
private Thread wrapper;
public ThreadWrapper(ThreadStart action)
{
wrapper = new Thread(action)
{
IsBackground = true
};
wrapper.Start();
}
public void Join() => wrapper.Join();
public void Kill() => wrapper.Abort();
}
}

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Newtonsoft.Json" version="12.0.3" targetFramework="net48" />
</packages>

View File

@ -0,0 +1,54 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProjectGuid>{AFF161B8-AF8E-4A16-9AA4-B692EB0D838E}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>MelonVPNDaemon</RootNamespace>
<AssemblyName>MelonVPNDaemon</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<ReleaseVersion>1.0</ReleaseVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ExternalConsole>true</ExternalConsole>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ExternalConsole>true</ExternalConsole>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MelonVPNCore\MelonVPNCore.csproj">
<Project>{B2F2F96C-3E5D-4176-9D66-479F357BC078}</Project>
<Name>MelonVPNCore</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="melonvpndaemon.service">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="client.cfg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>

14
MelonVPNDaemon/Program.cs Normal file
View File

@ -0,0 +1,14 @@
using MelonVPNCore;
namespace MelonVPNDaemon
{
class Program
{
public static int Main(string[] args)
{
ThreadWrapper wrapper = new ThreadWrapper(DaemonSocketServer.StartServer);
wrapper.Join();
return 1;
}
}
}

View File

@ -0,0 +1,26 @@
using System.Reflection;
using System.Runtime.CompilerServices;
// Information about this assembly is defined by the following attributes.
// Change them to the values specific to your project.
[assembly: AssemblyTitle("MelonVPNDaemon")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("${AuthorCopyright}")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
// The form "{Major}.{Minor}.*" will automatically update the build and revision,
// and "{Major}.{Minor}.{Build}.*" will update just the revision.
[assembly: AssemblyVersion("1.0.*")]
// The following attributes are used to specify the signing key for the assembly,
// if desired. See the Mono documentation for more information about signing.
//[assembly: AssemblyDelaySign(false)]
//[assembly: AssemblyKeyFile("")]

155
MelonVPNDaemon/Server.cs Normal file
View File

@ -0,0 +1,155 @@
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
namespace MelonVPNDaemon {
public class AsynchronousSocketListener
{
// Thread signal.
public static ManualResetEvent allDone = new ManualResetEvent(false);
public AsynchronousSocketListener()
{
}
public static void StartListening()
{
// Establish the local endpoint for the socket.
// The DNS name of the computer
// running the listener is "host.contoso.com".
IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000);
// Create a TCP/IP socket.
Socket listener = new Socket(ipAddress.AddressFamily,
SocketType.Stream, ProtocolType.Tcp);
// Bind the socket to the local endpoint and listen for incoming connections.
try
{
listener.Bind(localEndPoint);
listener.Listen(100);
while (true)
{
// Set the event to nonsignaled state.
allDone.Reset();
// Start an asynchronous socket to listen for connections.
Console.WriteLine("Waiting for a connection...");
listener.BeginAccept(
new AsyncCallback(AcceptCallback),
listener);
// Wait until a connection is made before continuing.
allDone.WaitOne();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
Console.WriteLine("\nPress ENTER to continue...");
Console.Read();
}
public static void AcceptCallback(IAsyncResult ar)
{
// Signal the main thread to continue.
allDone.Set();
// Get the socket that handles the client request.
Socket listener = (Socket)ar.AsyncState;
Socket handler = listener.EndAccept(ar);
// Create the state object.
StateObject state = new StateObject();
state.workSocket = handler;
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReadCallback), state);
}
public static void ReadCallback(IAsyncResult ar)
{
String content = String.Empty;
// Retrieve the state object and the handler socket
// from the asynchronous state object.
StateObject state = (StateObject)ar.AsyncState;
Socket handler = state.workSocket;
// Read data from the client socket.
int bytesRead = handler.EndReceive(ar);
if (bytesRead > 0)
{
// There might be more data, so store the data received so far.
state.sb.Append(Encoding.ASCII.GetString(
state.buffer, 0, bytesRead));
// Check for end-of-file tag. If it is not there, read
// more data.
content = state.sb.ToString();
if (content.IndexOf("<EOF>") > -1)
{
// All the data has been read from the
// client. Display it on the console.
Console.WriteLine("Read {0} bytes from socket. \n Data : {1}",
content.Length, content);
// Echo the data back to the client.
Send(handler, content);
}
else
{
// Not all data received. Get more.
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReadCallback), state);
}
}
}
private static void Send(Socket handler, String data)
{
// Convert the string data to byte data using ASCII encoding.
byte[] byteData = Encoding.ASCII.GetBytes(data);
// Begin sending the data to the remote device.
handler.BeginSend(byteData, 0, byteData.Length, 0,
new AsyncCallback(SendCallback), handler);
}
private static void SendCallback(IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object.
Socket handler = (Socket)ar.AsyncState;
// Complete sending the data to the remote device.
int bytesSent = handler.EndSend(ar);
Console.WriteLine("Sent {0} bytes to client.", bytesSent);
handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
public static int Main(String[] args)
{
StartListening();
return 0;
}
}

View File

@ -0,0 +1,4 @@
vpn = wss://example.com
key = 1234
name = temp
peers = mono /usr/lib/melon-vpn/MelonVPNConnectedClientUpdate.exe

View File

@ -0,0 +1,16 @@
# Melon VPN Daemon
[Unit]
Description=Manage Melon VPN Service
After=network.target
[Service]
WorkingDirectory=/
ExecStart=mono /usr/lib/melon-vpn/MelonVPNDaemon.exe
User=root
Group=root
Type=simple
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target

8
build Executable file
View File

@ -0,0 +1,8 @@
#!/bin/bash
echo "[info] Preparing to setup dependencies"
./install-dependencies
echo "[info] Preparing to build projects from source"
./build-source
echo "[info] Preparing to install components"
./install-components
echo "[info] Build process finished"

4
build-source Executable file
View File

@ -0,0 +1,4 @@
#!/bin/bash
echo "Preparing to build MelonVPN"
msbuild MelonVPN.sln -m /t:MelonVPNCore /t:MelonVPNConnectedClientUpdate /t:MelonVPNDaemon /t:MelonVPNClient /p:Configuration=Release /p:Platform=x86
echo "Run \"./install\" to install all the components for MelonVPN"

33
install-components Executable file
View File

@ -0,0 +1,33 @@
#!/bin/bash
sudo mkdir -p /usr/lib/melon-vpn/
sudo cp MelonVPNCore/bin/Release/MelonVPNCore.dll /usr/lib/melon-vpn/
sudo cp MelonVPNConnectedClientUpdate/bin/Release/MelonVPNConnectedClientUpdate.exe /usr/lib/melon-vpn/
sudo cp MelonVPNDaemon/bin/Release/MelonVPNDaemon.exe /usr/lib/melon-vpn/
if [ -f /etc/systemd/system/melonvpndaemon.service ]; then
echo "[info] Found daemon service at \"/etc/systemd/system/melonvpndaemon.service\" delete this to reinstall the default service"
else
sudo cp MelonVPNDaemon/bin/Release/melonvpndaemon.service /etc/systemd/system/
fi
sudo mkdir -p /etc/melon-vpn/
if [ -f /etc/melon-vpn/client.cfg ]; then
echo "[info] Found config at \"/etc/melon-vpn/client.cfg\" delete this to reinstall the default config"
else
sudo cp MelonVPNDaemon/bin/Release/client.cfg /etc/melon-vpn/
fi
if [ -f /usr/share/applications/melonvpn.desktop ]; then
echo "[info] Found desktop file at \"/usr/share/applications/melonvpn.desktop\" delete this to reinstall the default one"
else
sudo cp MelonVPNClient/bin/Release/melonvpn.desktop /usr/share/applications/
fi
sudo chown root:root /etc/melon-vpn/client.cfg
sudo cp MelonVPNClient/bin/Release/MelonVPNClient.exe /usr/lib/melon-vpn/
sudo cp MelonVPNClient/bin/Release/MelonVPNClient.exe.config /usr/lib/melon-vpn/
sudo cp MelonVPNClient/bin/Release/melonvpnclient /usr/bin/
sudo chmod +x /usr/bin/melonvpnclient
echo "[info] Restarting daemon"
sudo systemctl stop melonvpndaemon
sudo systemctl disable melonvpndaemon
sudo systemctl daemon-reload
sudo systemctl enable melonvpndaemon
sudo systemctl start melonvpndaemon
echo "[info] Remember to setup \"/etc/melon-vpn/client.cfg\""

22
install-dependencies Executable file
View File

@ -0,0 +1,22 @@
#!/bin/bash
if [ "$(go version | head -c 13)" == "go version go" ]; then
echo "Assuming go is installed"
if [ -f /usr/bin/simple-vpn ]; then
echo "Found \"/usr/bin/simple-vpn\" assuming it is installed correctly"
else
echo "Cloning simple-vpn"
git clone https://github.com/skx/simple-vpn
cd simple-vpn
echo "Installing simple-vpn"
go build
sudo cp ./simple-vpn /usr/bin/ -i
cd ..
echo "Cleaning up"
rm simple-vpn -rf
echo "Components installed..."
fi
else
echo "Please install golang before continuing"
exit
fi
echo "Run \"./build\" to continue with installing MelonVPN"