add unix socket proxy to http

This commit is contained in:
seroquel 2021-10-21 19:29:07 -07:00
parent 0be549b2de
commit 38eccc69d8
36 changed files with 161 additions and 62 deletions

@ -1,3 +1,4 @@
using System.Linq;
using cloud.insecurity.docker;
using cloud.insecurity.http;
@ -5,44 +6,47 @@ namespace cloud.insecurity.docker.ipam
{
public static class HttpHandler
{
private static Scope[] RootScopes;
[HttpRequestHandler(IHttpRequest.RequestMethod.Post, "/Plugin.Activate")]
public static void Activate()
{
throw new System.NotImplementedException();
public static IHttpResponse Activate(HttpRequest request)
{
RootScopes = Scope.GetParentScopes().ToArray();
return new HttpResponse(request).Ok();
}
[HttpRequestHandler(IHttpRequest.RequestMethod.Post, "/IpamDriver.GetCapabilities")]
public static void GetCapabilities()
public static IHttpResponse GetCapabilities(HttpRequest request)
{
throw new System.NotImplementedException();
}
[HttpRequestHandler(IHttpRequest.RequestMethod.Post, "/IpamDriver.GetDefaultAddressSpaces")]
public static void GetDefaultAddressSpaces()
public static IHttpResponse GetDefaultAddressSpaces(HttpRequest request)
{
throw new System.NotImplementedException();
}
[HttpRequestHandler(IHttpRequest.RequestMethod.Post, "/IpamDriver.RequestPool")]
public static void RequestPool()
public static IHttpResponse RequestPool(HttpRequest request)
{
throw new System.NotImplementedException();
}
[HttpRequestHandler(IHttpRequest.RequestMethod.Post, "/IpamDriver.ReleasePool")]
public static void ReleasePool()
public static IHttpResponse ReleasePool(HttpRequest request)
{
throw new System.NotImplementedException();
}
[HttpRequestHandler(IHttpRequest.RequestMethod.Post, "/IpamDriver.RequestAddress")]
public static void RequestAddress()
public static IHttpResponse RequestAddress(HttpRequest request)
{
throw new System.NotImplementedException();
}
[HttpRequestHandler(IHttpRequest.RequestMethod.Post, "/IpamDriver.ReleaseAddress")]
public static void ReleaseAddress()
public static IHttpResponse ReleaseAddress(HttpRequest request)
{
throw new System.NotImplementedException();
}

@ -1,9 +1,16 @@
using System;
using System.Collections.Generic;
using System.IO.Pipes;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using cloud.insecurity.http;
using log4net;
namespace cloud.insecurity.docker.ipam
{
internal class Ipam
@ -17,28 +24,95 @@ namespace cloud.insecurity.docker.ipam
}
internal static void Main(string[] args)
{
Task<Task> UnixSocketProxy;
log4net.Config.XmlConfigurator.Configure();
Task server = HttpServer.Server.Start(new string[]
var tasks = new Task<Task>[]
{
"http://127.0.0.1:8000/",
});
Scope.GetParentScopes().ToList().ForEach(f => Console.WriteLine(
string.Format("{0}", f.ToString())));
HttpServer.Server.Start(new string[]
{
@"http://127.0.0.1:65467/",
}),
ProxyRequestsFromUnixSocket()
};
Console.CancelKeyPress += (sender, eventArgs) =>
{
Console.WriteLine("shutting down");
Console.WriteLine("shutting down, waiting for unfinished tasks..");
HttpServer.Server.Stop();
server.Wait();
tasks.ToList().ForEach(t => t.Wait());
Environment.Exit(0);
};
ReadKey:
switch (Console.ReadKey().Key)
cKey:
switch (Console.ReadKey())
{
default:
goto ReadKey;
goto cKey;
}
}
private static async Task<Task> ProxyRequestsFromUnixSocket()
{
var listeningPort = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP);
var endPoint = new UnixDomainSocketEndPoint(@"/run/cloud.insecurity.docker/ipam.sock");
listeningPort.Bind(endPoint);
listeningPort.Listen(0);
ManualResetEvent AcceptFinished = new ManualResetEvent(false);
while (HttpServer.Server.Running)
{
listeningPort.BeginAccept(ConnectionAccepted,
new Tuple<Socket, ManualResetEvent>(listeningPort, AcceptFinished));
AcceptFinished.WaitOne();
}
return Task.CompletedTask;
}
private static void ConnectionAccepted(IAsyncResult ar)
{
ManualResetEvent ReceiveFinished = new ManualResetEvent(false);
var socket = (ar.AsyncState as Tuple<Socket, ManualResetEvent>)?.Item1;
var finished = (ar.AsyncState as Tuple<Socket, ManualResetEvent>)?.Item2;
var ProxySocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
ProxySocket.Connect(new IPEndPoint(0x7f000001, 0xffbb));
var buffer = new List<ArraySegment<byte>>();
bool ReceivedFromClient = false;
recv:
while (!Encoding.UTF8.GetString(buffer.SelectMany(bytes => bytes)
.ToArray())
.EndsWith("\r\n\r\n"))
{
(ReceivedFromClient ? ProxySocket : socket)?.BeginReceive(buffer,
SocketFlags.None, result =>
{
(result.AsyncState as ManualResetEvent)?.Set();
}, ReceiveFinished);
ReceiveFinished.WaitOne();
}
if (ReceivedFromClient)
{
socket?.Send(buffer);
finished?.Set();
}
else
{
ProxySocket.Send(buffer);
buffer = new List<ArraySegment<byte>>();
ReceivedFromClient = true;
goto recv;
}
}
}

@ -29,6 +29,8 @@ namespace cloud.insecurity.docker.ipam
public int PrefixLen { get; set; }
public List<string>? Tags { get; set; }
public int? TcpIpVersion { get; set; }
public bool Allocated { get; set; }
private static LiteDatabase Db = new LiteDatabase(@"IPAM.db");
private static log4net.ILog Log
@ -92,12 +94,7 @@ namespace cloud.insecurity.docker.ipam
{
}
public override bool Equals(object? obj)
{
return (GetHashCode() == obj.GetHashCode());
}
public static IPNetwork GetNetworkObject(string network, int prefixLen)
{
return IPNetwork.Parse(string.Format("{0}/{1}", network, prefixLen.ToString()));
@ -115,7 +112,7 @@ namespace cloud.insecurity.docker.ipam
if (bytes.Length == 4)
{
bytes = new byte[] {0, 0, 0, 0}.Concat(bytes).ToArray()
.Concat(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0}).ToArray();
.Concat(new byte[] {0, 0, 0, 0, 0, 0, 0, 0}).ToArray();
}
//bytes = bytes.Select(b => Convert.ToByte(b ^ prefixLen)).ToArray();
@ -126,17 +123,17 @@ namespace cloud.insecurity.docker.ipam
{
// https://en.wikipedia.org/wiki/Universally_unique_identifier#History
return new Guid(
b.ReadUInt32(), // time low
b.ReadUInt16(), // time mid
b.ReadUInt16(), // time hi and version
b.ReadByte(), // clock seq hi and res?
b.ReadByte(), // clock seq lo?
b.ReadUInt32(),
b.ReadUInt16(),
b.ReadUInt16(),
b.ReadByte(),
b.ReadByte(),
b.ReadByte(),
b.ReadByte(),
b.ReadByte(),
b.ReadByte(),
b.ReadByte(),
b.ReadByte() /* 48-bit node id */);
b.ReadByte());
// however this is RFC4122 (g)UUID and the information
// is definitely not relevant but a nice piece of
// nostalgia.
@ -144,24 +141,24 @@ namespace cloud.insecurity.docker.ipam
}
}
}
new public int GetHashCode()
{
return GetUniqueId(Net, PrefixLen).GetHashCode();
}
public Scope GetUnassignedScope()
{
if (Locked)
throw new InvalidOperationException("scope is locked");
// Network.Subnet(Convert.ToByte(Schema.child_prefix)).Where(p =>
// {
// using (var db = new LiteDatabase(@"IPAM.db"))
// {
// var col = db.GetCollection<Scope>("Scopes");
//
// }
// });
throw new NotImplementedException();;
return Network.Subnet(Convert.ToByte(Schema.child_prefix)).Where(s =>
{
return !Db.GetCollection<Scope>("Scopes")
.Find(scope => scope.Id == GetUniqueId(s.Network.ToString(), s.Cidr)
&& scope.Allocated)
.Any();
}).Select(s => new Scope()
{
Net = s.Network.ToString(),
PrefixLen = Schema.child_prefix.GetValueOrDefault(),
ParentScope = this,
}).Single();
}
public IPAddress LeaseNetworkAddress()
@ -183,7 +180,8 @@ namespace cloud.insecurity.docker.ipam
return EnumerateSchemaScopes(enumerable);
}
private static IEnumerable<Scope> EnumerateSchemaScopes(IEnumerable<schema.Scope> enumerable, Scope? parent = null)
private static IEnumerable<Scope> EnumerateSchemaScopes(IEnumerable<schema.Scope> enumerable,
Scope? parent = null)
{
foreach (var scope in enumerable)
{
@ -203,7 +201,7 @@ namespace cloud.insecurity.docker.ipam
Log.Debug("DB not initialized?", ex);
}
if (newScope == null)
if (newScope == null)
{
newScope = new Scope()
{
@ -216,7 +214,6 @@ namespace cloud.insecurity.docker.ipam
TcpIpVersion = scope.tcp_ip_version,
Locked = (scope.lock_down.GetValueOrDefault()) ? true : false,
ParentScope = parent
};
Db.GetCollection<Scope>("Scopes")

@ -5,7 +5,7 @@ namespace cloud.insecurity.http
{
public class HttpRequest : IHttpRequest
{
private readonly HttpListenerContext Context;
internal readonly HttpListenerContext Context;
public IHttpRequest.RequestMethod Method

@ -6,44 +6,50 @@ namespace cloud.insecurity.http
{
public class HttpResponse : IHttpResponse
{
HttpListenerContext Context;
internal HttpRequest Request;
public WebHeaderCollection Headers = new WebHeaderCollection()
{
{"Server", "insecurity"},
};
public HttpResponse(HttpListenerContext context)
public HttpResponse(HttpRequest request)
{
Context = context;
Context.Response.Headers = Headers;
Request = request;
}
public void Dispose()
{
DefaultHttpResponse.New(Context).Dispose();
DefaultHttpResponse.New(Request.Context).Dispose();
}
public IHttpResponse SendResponse()
{
return DefaultHttpResponse.New(Context)
return DefaultHttpResponse.New(Request.Context)
.SendResponse();
}
public IHttpResponse NotFound()
{
return DefaultHttpResponse.New(Context)
return DefaultHttpResponse.New(Request.Context)
.NotFound();
}
public IHttpResponse InternalServerError()
{
return DefaultHttpResponse.New(Context)
return DefaultHttpResponse.New(Request.Context)
.InternalServerError();
}
public IHttpResponse NotImplemented()
{
return DefaultHttpResponse.New(Context)
return DefaultHttpResponse.New(Request.Context)
.NotImplemented();
}
public IHttpResponse Ok()
{
return DefaultHttpResponse
.New(Request.Context)
.Ok();
}
}
}

@ -45,6 +45,12 @@ namespace cloud.insecurity.http
return this;
}
public IHttpResponse Ok()
{
Context.Response.StatusCode = (int) IHttpResponse.ResponseCodes.Ok;
return this;
}
public static IHttpResponse New(HttpListenerContext context)
{
return new DefaultHttpResponse(context);

@ -20,6 +20,15 @@ namespace cloud.insecurity.http
private readonly HttpListener Listener = new HttpListener();
private readonly static HttpServer Instance = new HttpServer();
private readonly Tuple<MethodInfo, HttpRequestHandler>[] Handlers;
public bool Running
{
get
{
return Listener.IsListening;
}
}
public static HttpServer Server
{
@ -58,7 +67,7 @@ namespace cloud.insecurity.http
Listener.Close();
}
public async Task Start(string[] listeners)
public async Task<Task> Start(string[] listeners)
{
listeners.ToList().ForEach(l => Listener.Prefixes.Add(l));
@ -98,6 +107,8 @@ namespace cloud.insecurity.http
}, Listener.GetContext());
}
});
return Task.CompletedTask;
}
private IHttpResponse HandleContext(HttpListenerContext ctx)

@ -71,5 +71,6 @@ namespace cloud.insecurity.http
public IHttpResponse NotFound();
public IHttpResponse InternalServerError();
public IHttpResponse NotImplemented();
public IHttpResponse Ok();
}
}