public static HttpRoutingCookie DecodeHttpRoutingCookie(byte[] key, string msg) { byte[] data = DecodeHttpRoutingCookieEx(key, msg); if (data == null) { return(null); } HttpRoutingCookie cookie = new HttpRoutingCookie(); try { if (data[0] == 1) // Automatic routing cookie { cookie.version = 1; cookie.nodeid = new byte[32]; Array.Copy(data, 1, cookie.nodeid, 0, 32); // Target nodeid cookie.port = (ushort)IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(data, 33)); // Target port cookie.tls = ((data[35] & 0x01) != 0); // Use TLS cookie.oob = ((data[35] & 0x02) != 0); // Use OOB cookie.ticks = BitConverter.ToInt64(data, 36); // Time Ticks byte[] user = new byte[data[44]]; // Username length Array.Copy(data, 45, user, 0, user.Length); // Username cookie.username = UTF8Encoding.UTF8.GetString(user); byte[] host = new byte[data[45 + user.Length]]; // Hostname length Array.Copy(data, 46 + user.Length, host, 0, host.Length); // Hostname cookie.hostname = UTF8Encoding.UTF8.GetString(host); } else if (data[0] == 2) // IPv4 Direct routing cookie { cookie.version = 2; cookie.nodeid = new byte[32]; Array.Copy(data, 1, cookie.nodeid, 0, 32); // Relay nodeid byte[] addr = new byte[4]; Array.Copy(data, 33, addr, 0, 4); // Target address cookie.address = new IPAddress(addr); cookie.port = (ushort)IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(data, 37)); // Target port cookie.tls = ((data[39] & 0x01) != 0); // Use TLS cookie.oob = ((data[39] & 0x02) != 0); // Use OOB cookie.ticks = BitConverter.ToInt64(data, 40); // Time Ticks byte[] user = new byte[data[48]]; // Username length Array.Copy(data, 49, user, 0, user.Length); // Username cookie.username = UTF8Encoding.UTF8.GetString(user); byte[] host = new byte[data[49 + user.Length]]; // Hostname length Array.Copy(data, 50 + user.Length, host, 0, host.Length); // Hostname cookie.hostname = UTF8Encoding.UTF8.GetString(host); } // Check clock DateTime t1 = new DateTime(cookie.ticks); DateTime t2 = DateTime.UtcNow; if (t1 > t2.AddMinutes(3) || t1.AddMinutes(60) < t2) { return(null); } } catch (Exception) { return(null); } return(cookie); }
public static string EncodeHttpRoutingCookie(byte[] key, HttpRoutingCookie cookie) { if (key == null || key.Length != 50 || cookie.username == null || cookie.nodeid == null || cookie.nodeid.Length != 32 || cookie.hostname == null) { return(null); } byte[] user = UTF8Encoding.UTF8.GetBytes(cookie.username); byte[] host = UTF8Encoding.UTF8.GetBytes(cookie.hostname); if (user.Length > 250 || host.Length > 250) { return(null); } byte[] ticks = BitConverter.GetBytes(DateTime.UtcNow.Ticks); byte flags = 0; if (cookie.tls) { flags += 1; } if (cookie.oob) { flags += 2; } BinaryWriter bw = MeshUtils.GetBinaryWriter(); if (cookie.version == 1) // Automatic routing cookie { bw.Write((byte)1); // Cookie version bw.Write(cookie.nodeid, 0, 32); // Target nodeid bw.Write(IPAddress.HostToNetworkOrder((short)(cookie.port))); // Target port bw.Write(flags); // Flags (Use TLS/OOB) bw.Write(ticks, 0, 8); // Current time bw.Write((byte)user.Length); // Username length bw.Write(user, 0, user.Length); // Username bw.Write((byte)host.Length); // Hostname length bw.Write(host, 0, host.Length); // Hostname } else if (cookie.version == 2 && cookie.address != null && cookie.address.AddressFamily == AddressFamily.InterNetwork) // IPv4 Direct routing cookie { bw.Write((byte)2); // Cookie version bw.Write(cookie.nodeid, 0, 32); // Relay nodeid bw.Write(cookie.address.GetAddressBytes(), 0, 4); // Target IPv4 address bw.Write(IPAddress.HostToNetworkOrder((short)(cookie.port))); // Target port bw.Write(flags); // Flags (Use TLS/OOB) bw.Write(ticks, 0, 8); // Current time bw.Write((byte)user.Length); // Username length bw.Write(user, 0, user.Length); // Username bw.Write((byte)host.Length); // Hostname length bw.Write(host, 0, host.Length); // Hostname } string r = EncodeHttpRoutingCookieEx(key, ((MemoryStream)bw.BaseStream).ToArray()); MeshUtils.RecycleBinaryWriter(bw); return(r); }