Esempio n. 1
0
        /**
         * This is either a request or response.  Look up the handler
         * for it, and pass the packet to the handler
         */
        public void HandleData(MemBlock p, ISender from, object state)
        {
            //Is it a request or reply?
            ReqrepType rt    = (ReqrepType)((byte)p[0]);
            int        idnum = NumberSerializer.ReadInt(p, 1);
            MemBlock   rest  = p.Slice(5); //Skip the type and the id

            if (rt == ReqrepType.Request || rt == ReqrepType.LossyRequest)
            {
                HandleRequest(rt, idnum, rest, from);
            }
            else if (rt == ReqrepType.Reply)
            {
                HandleReply(rt, idnum, rest, from);
            }
            else if (rt == ReqrepType.ReplyAck)
            {
                HandleReplyAck(rt, idnum, rest, from);
            }
            else if (rt == ReqrepType.RequestAck)
            {
                HandleRequestAck(rt, idnum, rest, from);
            }
            else if (rt == ReqrepType.Error)
            {
                HandleError(rt, idnum, rest, from);
            }
        }
        /// <summary>Parse a revocation message.</summary>
        public UserRevocationMessage(Certificate cacert, MemBlock data)
        {
            _data = data;

            int pos    = 0;
            int length = 0;

            Username = AdrConverter.Deserialize(data, pos, out length) as string;
            pos     += length;
            // Random number to reduce likelihood of malicious duplication of messages
            NumberSerializer.ReadInt(data, pos);
            pos += 4;
            // Verify that there is a date contained therein, perhaps we should verify the time
            new DateTime(NumberSerializer.ReadLong(data, pos));
            pos      += 8;
            Signature = new byte[data.Length - pos];
            data.Slice(pos).CopyTo(Signature, 0);

            // hash the data
            SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider();

            Hash = sha1.ComputeHash(data, 0, data.Length - Signature.Length);

            if (!cacert.PublicKey.VerifyHash(Hash,
                                             CryptoConfig.MapNameToOID("SHA1"), Signature))
            {
                throw new Exception("Invalid UserRevocationMessage signature");
            }
        }
Esempio n. 3
0
        public void HandleData(MemBlock b, ISender return_path, object state)
        {
            //Read the header:
            uint     crc32    = (uint)NumberSerializer.ReadInt(b, 0);
            int      id       = NumberSerializer.ReadInt(b, 4);
            ushort   block    = (ushort)NumberSerializer.ReadShort(b, 8);
            MemBlock data     = b.Slice(10);
            var      cachekey = new Triple <uint, int, ushort>(crc32, id, block);
            MemBlock packet   = null;

            lock (_sync) {
                if (false == _fragments.Contains(cachekey))
                {
                    //This is a new block:
                    _fragments.Add(cachekey, data);
                    var       fc_key = new Pair <uint, int>(crc32, id);
                    Fragments this_fc;
                    if (false == _frag_count.TryGetValue(fc_key, out this_fc))
                    {
                        this_fc = new Fragments();
                        _frag_count.Add(fc_key, this_fc);
                    }
                    if (this_fc.AddBlock(block))
                    {
                        //We have all of them, decode and clean up:
                        packet = DecodeAndClear(crc32, id, (ushort)this_fc.Total);
                    }
                }
            }
            if (null != packet)
            {
                Handle(packet, new FragmentingSender(DEFAULT_SIZE, return_path));
            }
        }
Esempio n. 4
0
 /**
  * Return a random AHAddress initialized from the given rng
  */
 public AHAddress(RandomNumberGenerator rng)
 {
     byte[] buffer = new byte[MemSize];
     rng.GetBytes(buffer);
     SetClass(buffer, this.Class);
     _buffer = MemBlock.Reference(buffer, 0, MemSize);
     _prefix = (uint)NumberSerializer.ReadInt(_buffer, 0);
 }
Esempio n. 5
0
        /// <summary>Parses web data and updates the revoked users hashtable if
        /// successful</summary>
        protected void UpdateRl(byte[] data)
        {
            // message is length (4) + date (8) + data (variable) + hash (~20)
            int length = data.Length;

            if (length < 12)
            {
                throw new Exception("No data?  Didn't get enough data...");
            }

            length = NumberSerializer.ReadInt(data, 0);
            DateTime date = new DateTime(NumberSerializer.ReadLong(data, 4));

            // warn the user that this is an old revocation list, maybe there is an attack
            if (date < DateTime.UtcNow.AddHours(-24))
            {
                ProtocolLog.WriteIf(IpopLog.GroupVPN, "Revocation list is over 24 hours old");
            }

            // Weird, data length is longer than the data we got
            if (length > data.Length - 12)
            {
                throw new Exception("Missing data?  Didn't get enough data...");
            }

            // hash the data and verify the signature
            SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider();

            byte[] hash      = sha1.ComputeHash(data, 4, length);
            byte[] signature = new byte[data.Length - 4 - length];
            Array.Copy(data, 4 + length, signature, 0, signature.Length);

            if (!_ca_cert.PublicKey.VerifyHash(hash, CryptoConfig.MapNameToOID("SHA1"), signature))
            {
                throw new Exception("Invalid signature!");
            }

            // convert the data to an array list as it was sent to us
            MemBlock mem = MemBlock.Reference(data, 12, length - 8);

            ArrayList rl = AdrConverter.Deserialize(mem) as ArrayList;

            if (rl == null)
            {
                throw new Exception("Data wasn't a list...");
            }

            // convert it into a hashtable for O(1) look ups
            Hashtable ht = new Hashtable();

            foreach (string username in rl)
            {
                ht[username] = true;
            }

            Interlocked.Exchange(ref _revoked_users, ht);
        }
Esempio n. 6
0
 public AHAddress(BigInteger big_int) : base(big_int)
 {
     if (ClassOf(_buffer) != this.Class)
     {
         throw new System.
               ArgumentException("Class of address is not my class:  ",
                                 this.ToString());
     }
     _prefix = (uint)NumberSerializer.ReadInt(_buffer, 0);
 }
Esempio n. 7
0
 public void HandleData(MemBlock p, ISender edge, object state)
 {
     try {
         int num = NumberSerializer.ReadInt(p, 0);
         Console.WriteLine("Got packet number: {0}", num);
         edge.Send(p);
     }
     catch (Exception x) {
         Console.WriteLine("Server got exception on send: {0}", x);
     }
 }
        ///<summary>Decrypts the packet given a SymmetricEncryption returning true
        ///if it was able to decrypt it.</summary>
        public bool Decrypt(SymmetricEncryption se)
        {
            byte[] decrypted = se.DecryptData(_encrypted_data);
            int    pos       = 0;
            int    data_len  = NumberSerializer.ReadInt(decrypted, pos);

            pos       += 4;
            _data      = MemBlock.Reference(decrypted, pos, data_len);
            pos       += data_len;
            _signature = MemBlock.Reference(decrypted, pos, decrypted.Length - pos);
            return(true);
        }
Esempio n. 9
0
 public DirectionalAddress(MemBlock mb)
 {
     if (ClassOf(mb) != this.Class)
     {
         throw new System.
               ArgumentException
                   ("This is not an AHAddress (Class 124) :  ",
                   this.ToString());
     }
     _buffer = mb;
     _dir    = (Direction)NumberSerializer.ReadInt(mb, 0);
 }
Esempio n. 10
0
        /// Simulator != thread-safe!
        protected static Address SimulatorCache(Address a)
        {
            int     idx = NumberSerializer.ReadInt(a.ToMemBlock(), 0);
            Address tmp = _cache.GetValue(idx);

            if (a.Equals(tmp))
            {
                return(tmp);
            }
            _cache.Replace(idx, a);
            return(a);
        }
Esempio n. 11
0
        /// <summary>Return the IDs and the payload given a packet.</summary>
        public bool Parse(MemBlock packet, out MemBlock payload, out int local_id,
                          out int remote_id)
        {
            if (packet.Length < 8)
            {
                throw new Exception("Data is not a complete datagram, less than 8 bytes: " + packet.Length);
            }

            remote_id = NumberSerializer.ReadInt(packet, IdentifierPair.SOURCE_OFFSET);
            local_id  = NumberSerializer.ReadInt(packet, IdentifierPair.DESTINATION_OFFSET);
            payload   = packet.Slice(8);
            return(true);
        }
Esempio n. 12
0
        protected void ListenThread()
        {
            Thread.CurrentThread.Name = "udp_listen_thread";
            BufferAllocator ba        = new BufferAllocator(8 + Int16.MaxValue);
            EndPoint        end       = new IPEndPoint(IPAddress.Any, 0);
            int             rec_bytes = 0;

            MonitorLogSwitch();
            ProtocolLog.Monitor.SwitchedSetting += MonitorLogSwitch;

            while (1 == _running)
            {
                int max = ba.Capacity;
                try {
                    rec_bytes = _s.ReceiveFrom(ba.Buffer, ba.Offset, max,
                                               SocketFlags.None, ref end);
                } catch (SocketException x) {
                    if ((1 == _running) && ProtocolLog.UdpEdge.Enabled)
                    {
                        ProtocolLog.Write(ProtocolLog.UdpEdge, x.ToString());
                    }
                }

                if (rec_bytes < 8)
                {
                    continue;
                }

                int remoteid = NumberSerializer.ReadInt(ba.Buffer, ba.Offset);
                int localid  = NumberSerializer.ReadInt(ba.Buffer, ba.Offset + 4);

                MemBlock packet_buffer = MemBlock.Reference(ba.Buffer, ba.Offset + 8, rec_bytes - 8);
                ba.AdvanceBuffer(rec_bytes);

                if (localid < 0)
                {
                    // Negative ids are control messages
                    HandleControlPacket(remoteid, localid, packet_buffer, end);
                }
                else
                {
                    HandleDataPacket(remoteid, localid, packet_buffer, end, null);
                }
            }
            ProtocolLog.Monitor.SwitchedSetting -= MonitorLogSwitch;
            //Let everyone know we are out of the loop
            _listen_finished_event.Set();
            _s.Close();
            //Allow garbage collection
            _s = null;
        }
 public SecurityDataMessage(MemBlock data) : base(data)
 {
     try {
         int pos = 0;
         _spi            = NumberSerializer.ReadInt(data, pos);
         pos            += 4;
         _epoch          = NumberSerializer.ReadInt(data, pos);
         pos            += 4;
         _seqid          = NumberSerializer.ReadInt(data, pos);
         pos            += 4;
         _encrypted_data = data.Slice(pos);
     } catch {
         throw new Exception("Invalid SecurityDataMessage");
     }
     _update_icpacket = false;
 }
Esempio n. 14
0
        /// <summary>Creates a new BroadcastSender based upon a packet sent from
        /// one.  This makes the recursion step easier.</summary>
        public static BroadcastSender Parse(StructuredNode node, MemBlock packet,
                                            out MemBlock data)
        {
            int       pos    = 0;
            AHAddress source = new AHAddress(packet.Slice(pos, Address.MemSize));

            pos += Address.MemSize;
            AHAddress from = new AHAddress(packet.Slice(pos, Address.MemSize));

            pos += Address.MemSize;
            AHAddress to = new AHAddress(packet.Slice(pos, Address.MemSize));

            pos += Address.MemSize;
            int forwarders = NumberSerializer.ReadInt(packet, pos);

            pos += 4;
            int hops = NumberSerializer.ReadInt(packet, pos) + 1;

            pos += 4;
            data = packet.Slice(pos);
            return(new BroadcastSender(node, source, from, to, forwarders, hops));
        }
Esempio n. 15
0
        /**
         * This is a System.Threading.ThreadStart delegate
         * We loop waiting for edges that need to send,
         * or data on the socket.
         *
         * This is the only thread that can touch the socket,
         * therefore, we do not need to lock the socket.
         */
        protected void ListenThread()
        {
            Thread.CurrentThread.Name = "udp_listen_thread";
            BufferAllocator ba  = new BufferAllocator(8 + Int16.MaxValue);
            EndPoint        end = new IPEndPoint(IPAddress.Any, 0);

            DateTime last_debug   = DateTime.UtcNow;
            int      debug_period = 5000;
            bool     logging      = ProtocolLog.Monitor.Enabled;
            int      rec_bytes    = 0;

            while (1 == _running)
            {
                if (logging)
                {
                    DateTime now = DateTime.UtcNow;
                    if (last_debug.AddMilliseconds(debug_period) < now)
                    {
                        last_debug = now;
                        ProtocolLog.Write(ProtocolLog.Monitor, String.Format("I am alive: {0}", now));
                    }
                }

                int max = ba.Capacity;
                try {
                    rec_bytes = _s.ReceiveFrom(ba.Buffer, ba.Offset, max,
                                               SocketFlags.None, ref end);
                } catch (SocketException x) {
                    if ((1 == _running) && ProtocolLog.UdpEdge.Enabled)
                    {
                        ProtocolLog.Write(ProtocolLog.UdpEdge, x.ToString());
                    }
                }

                if (rec_bytes < 8)
                {
                    continue;
                }

                int remoteid = NumberSerializer.ReadInt(ba.Buffer, ba.Offset);
                int localid  = NumberSerializer.ReadInt(ba.Buffer, ba.Offset + 4);

                MemBlock packet_buffer = MemBlock.Reference(ba.Buffer, ba.Offset + 8, rec_bytes - 8);
                ba.AdvanceBuffer(rec_bytes);

                if (localid < 0)
                {
                    // Negative ids are control messages
                    HandleControlPacket(remoteid, localid, packet_buffer, null);
                }
                else
                {
                    HandleDataPacket(remoteid, localid, packet_buffer, end, null);
                }
            }
            //Let everyone know we are out of the loop
            _listen_finished_event.Set();
            _s.Close();
            //Allow garbage collection
            _s = null;
        }
Esempio n. 16
0
        /**
         * This handles lightweight control messages that may be sent
         * by UDP
         */
        protected void HandleControlPacket(int remoteid, int n_localid,
                                           MemBlock buffer, object state)
        {
            int     local_id = ~n_localid;
            UdpEdge e        = _id_ht[local_id] as UdpEdge;

            if (e == null)
            {
                return;
            }

            if (e.RemoteID == 0)
            {
                try {
                    e.RemoteID = remoteid;
                } catch {
                    return;
                }
            }

            if (e.RemoteID != remoteid)
            {
                return;
            }

            try {
                ControlCode code = (ControlCode)NumberSerializer.ReadInt(buffer, 0);
                if (ProtocolLog.UdpEdge.Enabled)
                {
                    ProtocolLog.Write(ProtocolLog.UdpEdge, String.Format(
                                          "Got control {1} from: {0}", e, code));
                }
                if (code == ControlCode.EdgeClosed)
                {
                    //The edge has been closed on the other side
                    RequestClose(e);
                    CloseHandler(e, null);
                }
                else if (code == ControlCode.EdgeDataAnnounce)
                {
                    //our NAT mapping may have changed:
                    IDictionary info =
                        (IDictionary)AdrConverter.Deserialize(buffer.Slice(4));
                    string our_local_ta = (string)info["RemoteTA"]; //his remote is our local
                    if (our_local_ta != null)
                    {
                        //Update our list:
                        TransportAddress new_ta = TransportAddressFactory.CreateInstance(our_local_ta);
                        TransportAddress old_ta = e.PeerViewOfLocalTA;
                        if (!new_ta.Equals(old_ta))
                        {
                            if (ProtocolLog.UdpEdge.Enabled)
                            {
                                ProtocolLog.Write(ProtocolLog.UdpEdge, String.Format(
                                                      "Local NAT Mapping changed on Edge: {0}\n{1} => {2}",
                                                      e, old_ta, new_ta));
                            }
                            //Looks like matters have changed:
                            this.UpdateLocalTAs(e, new_ta);

                            /**
                             * @todo, maybe we should ping the other edges sharing this
                             * EndPoint, but we need to be careful not to do some O(E^2)
                             * operation, which could easily happen if each EdgeDataAnnounce
                             * triggered E packets to be sent
                             */
                        }
                    }
                }
                else if (code == ControlCode.Null)
                {
                    //Do nothing in this case
                }
            }
            catch (Exception x) {
                //This could happen if this is some control message we don't understand
                if (ProtocolLog.Exceptions.Enabled)
                {
                    ProtocolLog.Write(ProtocolLog.Exceptions, x.ToString());
                }
            }
        }
Esempio n. 17
0
        public SecurityControlMessage(MemBlock data)
        {
            try {
                int pos = 0;
                _version       = NumberSerializer.ReadInt(data, 0);
                pos           += 4;
                _spi           = NumberSerializer.ReadInt(data, pos);
                pos           += 4;
                _type          = (MessageType)NumberSerializer.ReadInt(data, pos);
                pos           += 4;
                _local_cookie  = data.Slice(pos, CookieLength);
                pos           += CookieLength;
                _remote_cookie = data.Slice(pos, CookieLength);
                pos           += CookieLength;

                bool read_cas  = false;
                bool read_dhe  = false;
                bool read_cert = false;
                bool read_hash = false;

                switch (_type)
                {
                case MessageType.CookieResponse:
                    read_cas = true;
                    break;

                case MessageType.DHEWithCertificate:
                    read_cert = true;
                    read_dhe  = true;
                    break;

                case MessageType.DHEWithCertificateAndCAs:
                    read_cas  = true;
                    read_dhe  = true;
                    read_cert = true;
                    break;

                case MessageType.Confirm:
                    read_hash = true;
                    break;
                }

                if (read_dhe)
                {
                    int dhe_length = NumberSerializer.ReadInt(data, pos);
                    pos += 4;
                    _dhe = data.Slice(pos, dhe_length);
                    pos += dhe_length;
                }

                if (read_cert)
                {
                    int cert_length = NumberSerializer.ReadInt(data, pos);
                    pos         += 4;
                    _certificate = data.Slice(pos, cert_length);
                    pos         += cert_length;
                }

                if (read_cas)
                {
                    int cas_length = NumberSerializer.ReadInt(data, pos);
                    pos += 4;
                    _cas = new List <MemBlock>();
                    int end = pos + cas_length;
                    while (pos < end)
                    {
                        _cas.Add(data.Slice(pos, CALength));
                        pos += CALength;
                    }
                }

                if (read_hash)
                {
                    int hash_length = NumberSerializer.ReadInt(data, pos);
                    pos  += 4;
                    _hash = data.Slice(pos, hash_length);
                    pos  += hash_length;
                }

                _signature = data.Slice(pos);
            } catch {
                throw new Exception("Invalid SecurityControlMessage");
            }
            _update_packet = false;
            _packet        = data;
        }
Esempio n. 18
0
 /**
  * @deprecated
  * This makes a copy of b and initializes the AHAddress with
  * that value
  */
 public AHAddress(byte[] b, int off) : this(MemBlock.Copy(b, off, MemSize))
 {
     _prefix = (uint)NumberSerializer.ReadInt(_buffer, 0);
 }
Esempio n. 19
0
        /// <summary>Where data packets prepended with a tunnel come.  Here we
        /// receive data as well as create new RelayEdges.</summary>
        public void HandleData(MemBlock data, ISender return_path, object state)
        {
            AHSender         ah_from = return_path as AHSender;
            ForwardingSender fs_from = return_path as ForwardingSender;
            AHAddress        target  = null;

            if (ah_from == null)
            {
                if (fs_from == null)
                {
                    return;
                }
                target = (AHAddress)fs_from.Destination;
            }
            else
            {
                target = (AHAddress)ah_from.Destination;
            }

            int remote_id = NumberSerializer.ReadInt(data, 0);
            int local_id  = NumberSerializer.ReadInt(data, 4);

            RelayEdge te = null;

            // No locally assigned ID, so we'll create a new RelayEdge and assign it one.
            // This could be hit many times by the same RemoteID, but it is safe since
            // we'll attempt Linkers on all of them and he'll only respond to the first
            // one he receives back.
            if (local_id == -1)
            {
                if (fs_from == null)
                {
                    throw new Exception("No LocalID assigned but not from a useful sender!");
                }

                ConnectionList cons  = _connections;
                int            index = cons.IndexOf(fs_from.Forwarder);
                if (index < 0)
                {
                    return;
                }

                List <Connection> overlap_addrs = new List <Connection>();
                overlap_addrs.Add(cons[index]);

                while (true)
                {
                    te = new RelayEdge(this, (RelayTransportAddress)_local_tas[0],
                                       new RelayTransportAddress(target, overlap_addrs),
                                       _iasf.GetForwarderSelector(), overlap_addrs, remote_id);
                    lock (_sync) {
                        if (!_id_to_tunnel.ContainsKey(te.LocalID))
                        {
                            _id_to_tunnel[te.LocalID] = te;
                            break;
                        }
                    }
                    // Arriving here, implies another RelayEdge will be created and this
                    // one needs to be closed
                    te.Close();
                }

                local_id = te.LocalID;

                te.CloseEvent += CloseHandler;
                SendEdgeEvent(te);
            }

            if (!_id_to_tunnel.TryGetValue(local_id, out te))
            {
                // Maybe we closed this edge
                // throw new Exception("No such edge");
                // Old behavior would ignore these packets...
                return;
            }
            else if (te.RemoteID == -1)
            {
                // We created this, but we haven't received a packet yet
                te.RemoteID = remote_id;
            }
            else if (te.RemoteID != remote_id)
            {
                // Either we closed this edge and it was reallocated or something is up!
                // throw new Exception("Receiving imposter packet...");
                // Old behavior would ignore these packets...
                return;
            }

            if (te.IsClosed)
            {
                throw new Exception("Edge is closed...");
            }

            // Chop off the Ids
            data = data.Slice(8);
            te.ReceivedPacketEvent(data);
        }