Пример #1
0
        private void initKey(string method, string password)
        {
            cipher = Cipher.CreateByName(method);
            if (cipher == null)
            {
                throw new ArgumentOutOfRangeException("Such encryption cipher methods are not supported");
            }

            byte[] passbuf = Encoding.Default.GetBytes(password);
            key = new byte[cipher.KeyLength];

            iv = new byte[cipher.IVLength];
            if (Native.EVP_BytesToKey(cipher.Handle, MessageDigest.MD5.Handle, null, passbuf, passbuf.Length, 1, key, iv) <= 0)
            {
                throw new ExternalException("Bytes to key calculations cannot be performed using cipher with md5(md) key password iv key etc");
            }

            int ivLen  = cipher.IVLength;
            int md5len = ivLen < sizeof(Guid) ? sizeof(Guid) : ivLen;

            iv = new byte[ivLen]; // RAND_bytes(iv.get(), ivLen); = new byte[ivLen]; // RAND_bytes(iv.get(), ivLen);

            // MD5->RC4
            Buffer.BlockCopy(HashAlgorithm <MD5> .
                             ComputeHash(
                                 merges(
                                     Encoding.Default.GetBytes($"SkylakeNAT@{method}."),
                                     key,
                                     Encoding.Default.GetBytes($".{password}"))), 0, iv, 0, sizeof(Guid));

            fixed(byte *piv = iv)
            fixed(byte *pkey = key)
            RC4.rc4_crypt(pkey, cipher.KeyLength, piv, ivLen, 0, 0);
        }
Пример #2
0
        private void ProcessReceiveFromUdp(IAsyncResult ar)
        {
            lock (this._syncobj)
            {
                try
                {
                    if (this._disposed)
                        return; }
                    if (ar == null)
                    {
                        EndPoint remoteEP = this._server.LocalEndPoint;
                        this._server.BeginReceiveFrom(_mssPacketBuffer, 0, _mssPacketBuffer.Length, 0, ref remoteEP, ProcessReceiveFromUdp, null);
                    }
                    else
                    {
                        EndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0);
                        int      bytes    = this._server.EndReceiveFrom(ar, ref remoteEP);
                        do
                        {
                            if (bytes < sizeof(pkg_hdr))
                                break;
                            fixed(byte *pinned = _mssPacketBuffer)
                            {
                                pkg_hdr *pkg = (pkg_hdr *)pinned;

                                if (pkg->fk != pkg_hdr.FK)
                                {
                                    break;
                                }
                                if ((pkg->len + sizeof(pkg_hdr)) != bytes)
                                {
                                    break;
                                }
                                if (pkg->id == 0)
                                {
                                    break;
                                }
                                Commands commands = unchecked ((Commands)pkg->cmd);

                                if (commands == Commands.NATCommands_kAuthentication)
                                {
                                    NATClientContext context = null;
                                    SkylakeNATClient client  = null;
                                    lock (this._sockets)
                                    {
                                        if (!_natClientTable.TryGetValue(pkg->id, out context) || context == null)
                                        {
                                            client = this.CreateClient(pkg->id, remoteEP);
                                            if (client != null)
                                            {
                                                client.LocalEndPoint = remoteEP;
                                                context = new NATClientContext()
                                                {
                                                    client = client
                                                };
                                                _natClientTable[pkg->id] = context;
                                                client.Abort            += this._onSocketAbort;
                                                client.Message          += this._onSocketMessage;
                                                client.Authentication   += this._onAuthentication;
                                            }
                                        }
                                        else
                                        {
                                            client = context.client;
                                        }
                                    }
                                    if (context != null && client != null)
                                    {
                                        lock (context)
                                        {
                                            context.agingsw.Restart();
                                        }
                                        client.LocalEndPoint = remoteEP;
                                        client.OnAuthentication(EventArgs.Empty);
                                    }
                                }
                                else
                                {
                                    SkylakeNATClient client = null;
                                    lock (this._sockets)
                                    {
                                        _natClientTable.TryGetValue(pkg->id, out NATClientContext context);
                                        if (context != null)
                                        {
                                            lock (context)
                                            {
                                                context.agingsw.Restart();
                                            }
                                            client = context.client;
                                        }
                                    }
                                    if (client != null)
                                    {
                                        BufferSegment payload = null;
                                        if (pkg->len > 0)
                                        {
                                            int ofs = sizeof(pkg_hdr);
#if _USE_RC4_SIMPLE_ENCIPHER
                                            fixed(byte *payloadPtr = &_mssPacketBuffer[ofs])
                                            RC4.rc4_crypt(this.Key, payloadPtr, pkg->len, this.Subtract, 0);
#endif
                                            payload = client._encryptor.Decrypt(new BufferSegment(_mssPacketBuffer, ofs, pkg->len));
                                        }
                                        else
                                        {
                                            payload = new BufferSegment(BufferSegment.Empty);
                                        }
                                        client.OnMessage(new SkylakeNATMessage(payload)
                                        {
                                            Commands = commands,
                                        });
                                    }
                                }
                            }
                        } while (false);
                        this.ProcessReceiveFromUdp(null);
                    }
                }
Пример #3
0
            public virtual bool Send(SkylakeNATMessage message, int sent = 1)
            {
                if (message == null)
                {
                    return(false);
                }
                Socket socket = null;

                lock (this._syncobj)
                {
                    socket = this._socket;
                    if (socket == null)
                    {
                        return(false);
                    }
                }
                BufferSegment payload_segment = message.Payload;

#if !_USE_RC4_SIMPLE_ENCIPHER || __USE_UDP_PAYLOAD_TAP_PACKET
                if (payload_segment.Length > 0)
                {
                    payload_segment = this._encryptor.Encrypt(payload_segment);
                }
#endif
                int    payload_size = payload_segment.Length;
                byte[] packet       = new byte[sizeof(pkg_hdr) + payload_size];
                fixed(byte *pinned = packet)
                {
                    pkg_hdr *pkg = (pkg_hdr *)pinned;

                    pkg->fk  = pkg_hdr.FK;
                    pkg->len = unchecked ((ushort)payload_size);
                    pkg->cmd = unchecked ((byte)message.Commands);
                    if (payload_size > 0)
                    {
                        byte *payload_data = sizeof(pkg_hdr) + pinned;
                        Marshal.Copy(payload_segment.Buffer, payload_segment.Offset, (IntPtr)payload_data, payload_size);
#if _USE_RC4_SIMPLE_ENCIPHER
                        RC4.rc4_crypt(this.Router.Key, payload_data, payload_size, this.Router.Subtract, 1);
#endif
                    }
                }

#if _USE_RC4_SIMPLE_ENCIPHER
                try
                {
                    if (sent <= 0)
                    {
                        sent = 1;
                    }
                    for (int i = 0; i < sent; i++)
                    {
                        socket.BeginSendTo(packet, 0, packet.Length, SocketFlags.None, this.LocalEndPoint, (ar) =>
                        {
                            try
                            {
                                socket.EndSendTo(ar);
                            }
                            catch (Exception) { }
                        }, null);
                    }
                    return(true);
                }
                catch (Exception)
                {
                    return(false);
                }
#else
                SocketError error = SocketError.SocketError;
                try
                {
                    socket.BeginSend(packet, 0, packet.Length, SocketFlags.None, out error, (ar) =>
                    {
                        error = SocketError.SocketError;
                        try
                        {
                            socket.EndSend(ar, out error);
                        }
                        catch (Exception)
                        {
                            error = SocketError.SocketError;
                        }
                        if (error != SocketError.Success)
                        {
                            this.CloseOrAbort();
                        }
                    }, null);
                }
                catch (Exception)
                {
                    error = SocketError.SocketError;
                }
                if (error != SocketError.Success && error != SocketError.IOPending)
                {
                    this.CloseOrAbort();
                    return(false);
                }
                return(true);
#endif
            }
Пример #4
0
            private void StartReceive(IAsyncResult ar)
            {
                SkylakeNATMessage message = null;
                SocketError       error   = SocketError.SocketError;

                try
                {
                    do
                    {
                        Socket socket = null;
                        lock (this._syncobj)
                            socket = this._socket;
                        if (socket == null)
                        {
                            return;
                        }
                        if (ar == null)
                        {
                            if (!_fhdr)
                            {
                                socket.BeginReceive(_phdr, 0, _phdr.Length, SocketFlags.None, out error, StartReceive, null);
                            }
                            else
                            {
                                int suplus = _message.Length - _fseek;
                                if (suplus >= Layer3Netif.MSS)
                                {
                                    suplus = Layer3Netif.MSS;
                                }
                                socket.BeginReceive(_message, _fseek, suplus, SocketFlags.None, out error, StartReceive, null);
                            }
                            if (error == SocketError.IOPending)
                            {
                                error = SocketError.Success;
                            }
                        }
                        else
                        {
                            int len = -1;
                            try
                            {
                                len = socket.EndReceive(ar, out error);
                            }
                            catch (Exception)
                            {
                                len = -1;
                            }
                            if (len <= 0)
                            {
                                error = SocketError.SocketError;
                                break;
                            }
                            else
                            {
                                bool completion = false;
                                if (!_fhdr)
                                {
                                    fixed(byte *pinned = _phdr)
                                    {
                                        pkg_hdr *pkg = (pkg_hdr *)pinned;

                                        if (len != sizeof(pkg_hdr) || pkg->fk != pkg_hdr.FK)
                                        {
                                            error = SocketError.SocketError;
                                            break;
                                        }
                                        if (0 == pkg->len)
                                        {
                                            completion = true;
                                        }
                                        else
                                        {
                                            _fseek   = 0;
                                            _fhdr    = true;
                                            _message = new byte[pkg->len];
                                        }
                                        error = SocketError.Success;
                                    }
                                }
                                else
                                {
                                    _fseek += len;
                                    if (_fseek >= _message.Length)
                                    {
                                        completion = true;
                                    }
                                    error = SocketError.Success;
                                }
                                if (completion)
                                {
                                    fixed(byte *pinned = _phdr)
                                    {
                                        pkg_hdr *pkg = (pkg_hdr *)pinned;

                                        if (0 == pkg->len)
                                        {
                                            message = new SkylakeNATMessage(new BufferSegment(BufferSegment.Empty));
                                        }
                                        else
                                        {
                                            message = new SkylakeNATMessage(new BufferSegment(_message));
                                        }
                                        if (0 == this.Id)
                                        {
                                            this.Id = pkg->id;
                                        }
                                        message.Commands = unchecked ((Commands)pkg->cmd);
                                        _fseek           = 0;
                                        _fhdr            = false;
                                        _message         = null;
                                    }
                                    error = SocketError.Success;
                                }
                            }
                        }
                    } while (false);
                }
                catch (Exception)
                {
                    error = SocketError.SocketError;
                }
                if (error != SocketError.Success)
                {
                    this.CloseOrAbort();
                }
                else if (ar != null)
                {
                    if (message != null)
                    {
                        BufferSegment segment = message.Payload;
#if !_USE_RC4_SIMPLE_ENCIPHER
                        if (segment.Length > 0)
                        {
                            segment         = this._encryptor.Decrypt(segment);
                            message.Payload = segment;
                        }
#else
                        fixed(byte *pinned = segment.Buffer)
                        if (pinned != null)
                        {
                            RC4.rc4_crypt(this.Router.Key, pinned, segment.Length, this.Router.Subtract, 0);
                        }
#endif
                        if (message.Commands != Commands.NATCommands_kAuthentication)
                        {
                            this.OnMessage(message);
                        }
                        else
                        {
                            this.OnAuthentication(message);
                        }
                    }
                    this.StartReceive(null);
                }
            }