Exemple #1
0
        private void DispatchToChannel(Packet packet, uint channelId)
        {
            // Look up the channel and dispatch
            if (channels.ContainsKey(channelId))
            {
                try
                {
                    channels[channelId].HandlePacket((dynamic)packet);
                }
                catch (RuntimeBinderException)
                {
                    logger.LogWarning("Unhandled channel packet type: {Type}.", packet.PacketType);

                    Unimplemented unimplemented = new Unimplemented()
                    {
                        RejectedPacketNumber = packet.PacketSequence
                    };

                    Send(unimplemented);
                }
            }
            else
            {
                // TODO - what to do for a channel that does not exist?
            }
        }
Exemple #2
0
        private void HandlePacket(Packet packet)
        {
            try
            {
                HandleSpecificPacket((dynamic)packet);
            }
            catch (RuntimeBinderException)
            {
                m_Logger.LogWarning($"Unhandled packet type: {packet.PacketType}");

                Unimplemented unimplemented = new Unimplemented()
                {
                    RejectedPacketNumber = packet.PacketSequence
                };
                Send(unimplemented);
            }
        }
        public override IProgramPart VisitFunctionCall(FSQLParser.FunctionCallContext context)
        {
            var isInternal = context.fnInt != null && context.fnUsr == null;
            var name       = isInternal ? context.fnInt.GetText() : context.IDENT().GetText();
            var args       = Visit(context.args) as IEnumerable <IExpression>;

            if (isInternal)
            {
                IProgramPart results;
                var          token = context.fnInt.GetChild(0).Payload as IToken;
                var          type  = token?.Type ?? -1;
                switch (type)
                {
                case FSQLLexer.WRITELINE:
                    results = new WriteLine(args);
                    break;

                case FSQLLexer.WRITE:
                    results = new Write(args);
                    break;

                case FSQLLexer.COREDUMP:
                    results = new SystemFn("CoreDump", (ctx, prms) => ctx.Dump(Priority.Verbose));
                    break;

                case FSQLLexer.READLINE:
                    results = new SystemFn("ReadLine", (ctx, prms) => Console.ReadLine());
                    break;

                case FSQLLexer.READ:
                    results = new SystemFn("Read", (ctx, prms) => Console.Read());
                    break;

                //case FSQLLexer.EXISTS:
                //    results = new Exists(args);
                //    break;
                default:
                    results = new Unimplemented(name);
                    break;
                }
                return(results);
            }
            return(new FunctionCall(name, args));
        }
        public IStatement Parse(string source)
        {
            var inputStream       = new AntlrInputStream(source);
            var lexer             = new FSQLLexer(inputStream);
            var commonTokenStream = new CommonTokenStream(lexer);
            var parser            = new FSQLParser(commonTokenStream);

            IStatement results = new Unimplemented(source);

            var stmtContext = parser.statement();


            //IProgramPart parseResults;
            try {
                results = Visit(stmtContext) as IStatement;
                if (results == null)
                {
                    throw new SyntaxErrorException($"Could not parse '{source}'.");
                }
            } catch (Exception) {
                if (!source.StartsWith("@_ ="))
                {
                    source = "@_ = " + source;
                    if (!source.EndsWith(";"))
                    {
                        source = source + ";";
                    }
                    results = Parse(source);
                }
                else
                {
                    throw;
                }
            }

            return(results);
        }
Exemple #5
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="avctx"></param>
        /// <param name="outdata"></param>
        /// <param name="outdata_size"></param>
        /// <param name="avpkt"></param>
        /// <returns></returns>
        public override int decode(AVCodecContext avctx, ref object outputData, AVPacket avpkt)
        {
            Pointer <byte> buf = avpkt.data;
            int            buf_size = avpkt.size;
            BMPContext     s = (BMPContext)avctx.priv_data;
            AVFrame        p = s.picture;
            uint           fsize, hsize;
            int            width, height;
            int            depth;
            BiCompression  comp;
            uint           ihsize;
            int            i, n, linesize;
            var            rgb   = new uint[3];
            uint           alpha = 0;
            Pointer <byte> ptr;
            int            dsize;
            Pointer <byte> buf0 = buf;

            if (buf_size < 14)
            {
                log.av_log(avctx, log.AV_LOG_ERROR, "buf size too small (%d)\n", buf_size);
                return(-1);
            }

            if (bytestream.get_byte(ref buf) != 'B' || bytestream.get_byte(ref buf) != 'M')
            {
                log.av_log(avctx, log.AV_LOG_ERROR, "bad magic number\n");
                return(-1);
            }

            fsize = bytestream.get_le32(ref buf);

            if (buf_size < fsize)
            {
                log.av_log(avctx, log.AV_LOG_ERROR, "not enough data (%d < %d), trying to decode anyway\n", buf_size, fsize);
                fsize = (uint)buf_size;
            }

            buf += 2;                              /* reserved1 */
            buf += 2;                              /* reserved2 */

            hsize  = bytestream.get_le32(ref buf); /* header size */
            ihsize = bytestream.get_le32(ref buf); /* more header size */

            if (ihsize + 14 > hsize)
            {
                log.av_log(avctx, log.AV_LOG_ERROR, "invalid header size %d\n", hsize);
                return(-1);
            }

            /* sometimes file size is set to some headers size, set a real size in that case */
            if (fsize == 14 || fsize == ihsize + 14)
            {
                fsize = (uint)(buf_size - 2);
            }

            if (fsize <= hsize)
            {
                log.av_log(avctx, log.AV_LOG_ERROR, "declared file size is less than header size (%d < %d)\n", fsize, hsize);
                return(-1);
            }

            switch (ihsize)
            {
            case  40:                     // windib
            case  56:                     // windib v3
            case  64:                     // OS/2 v2
            case 108:                     // windib v4
            case 124:                     // windib v5
                width  = (int)bytestream.get_le32(ref buf);
                height = (int)bytestream.get_le32(ref buf);
                break;

            case  12:                     // OS/2 v1
                width  = (int)bytestream.get_le16(ref buf);
                height = (int)bytestream.get_le16(ref buf);
                break;

            default:
                log.av_log(avctx, log.AV_LOG_ERROR, "unsupported BMP file, patch welcome\n");
                return(-1);
            }

            if (bytestream.get_le16(ref buf) != 1)             /* planes */
            {
                log.av_log(avctx, log.AV_LOG_ERROR, "invalid BMP header\n");
                return(-1);
            }

            depth = bytestream.get_le16(ref buf);

            if (ihsize == 40 || ihsize == 64 || ihsize == 56)
            {
                comp = (BiCompression)bytestream.get_le32(ref buf);
            }
            else
            {
                comp = BiCompression.BMP_RGB;
            }

            if (comp != BiCompression.BMP_RGB && comp != BiCompression.BMP_BITFIELDS && comp != BiCompression.BMP_RLE4 && comp != BiCompression.BMP_RLE8)
            {
                log.av_log(avctx, log.AV_LOG_ERROR, "BMP coding %d not supported\n", comp);
                return(-1);
            }

            if (comp == BiCompression.BMP_BITFIELDS)
            {
                buf   += 20;
                rgb[0] = bytestream.get_le32(ref buf);
                rgb[1] = bytestream.get_le32(ref buf);
                rgb[2] = bytestream.get_le32(ref buf);
                if (ihsize >= 108)
                {
                    alpha = bytestream.get_le32(ref buf);
                }
            }


            avctx.width  = width;
            avctx.height = height > 0 ? height : -height;

            avctx.pix_fmt = PixelFormat.PIX_FMT_NONE;

            switch (depth)
            {
            case 32:
                if (comp == BiCompression.BMP_BITFIELDS)
                {
                    if (rgb[0] == 0xFF000000 && rgb[1] == 0x00FF0000 && rgb[2] == 0x0000FF00)
                    {
                        avctx.pix_fmt = (alpha != 0) ? PixelFormat.PIX_FMT_ABGR : PixelFormat.PIX_FMT_0BGR;
                    }
                    else if (rgb[0] == 0x00FF0000 && rgb[1] == 0x0000FF00 && rgb[2] == 0x000000FF)
                    {
                        avctx.pix_fmt = (alpha != 0) ? PixelFormat.PIX_FMT_BGRA : PixelFormat.PIX_FMT_BGR0;
                    }
                    else if (rgb[0] == 0x0000FF00 && rgb[1] == 0x00FF0000 && rgb[2] == 0xFF000000)
                    {
                        avctx.pix_fmt = (alpha != 0) ? PixelFormat.PIX_FMT_ARGB : PixelFormat.PIX_FMT_0RGB;
                    }
                    else if (rgb[0] == 0x000000FF && rgb[1] == 0x0000FF00 && rgb[2] == 0x00FF0000)
                    {
                        avctx.pix_fmt = (alpha != 0) ? PixelFormat.PIX_FMT_RGBA : PixelFormat.PIX_FMT_RGB0;
                    }
                    else
                    {
                        log.av_log(avctx, log.AV_LOG_ERROR, "Unknown bitfields %0X %0X %0X\n", rgb[0], rgb[1], rgb[2]);
                        return(error.AVERROR(error.EINVAL));
                    }
                }
                else
                {
                    avctx.pix_fmt = PixelFormat.PIX_FMT_BGRA;
                }
                break;

            case 24:
                avctx.pix_fmt = PixelFormat.PIX_FMT_BGR24;
                break;

            case 16:
                if (comp == BiCompression.BMP_RGB)
                {
                    avctx.pix_fmt = PixelFormat.PIX_FMT_RGB555;
                }
                else if (comp == BiCompression.BMP_BITFIELDS)
                {
                    if (rgb[0] == 0xF800 && rgb[1] == 0x07E0 && rgb[2] == 0x001F)
                    {
                        avctx.pix_fmt = PixelFormat.PIX_FMT_RGB565;
                    }
                    else if (rgb[0] == 0x7C00 && rgb[1] == 0x03E0 && rgb[2] == 0x001F)
                    {
                        avctx.pix_fmt = PixelFormat.PIX_FMT_RGB555;
                    }
                    else if (rgb[0] == 0x0F00 && rgb[1] == 0x00F0 && rgb[2] == 0x000F)
                    {
                        avctx.pix_fmt = PixelFormat.PIX_FMT_RGB444;
                    }
                    else
                    {
                        log.av_log(avctx, log.AV_LOG_ERROR, "Unknown bitfields %0X %0X %0X\n", rgb[0], rgb[1], rgb[2]);
                        return(error.AVERROR(error.EINVAL));
                    }
                }
                break;

            case 8:
                if (hsize - ihsize - 14 > 0)
                {
                    avctx.pix_fmt = PixelFormat.PIX_FMT_PAL8;
                }
                else
                {
                    avctx.pix_fmt = PixelFormat.PIX_FMT_GRAY8;
                }
                break;

            case 1:
            case 4:
                if (hsize - ihsize - 14 > 0)
                {
                    avctx.pix_fmt = PixelFormat.PIX_FMT_PAL8;
                }
                else
                {
                    log.av_log(avctx, log.AV_LOG_ERROR, "Unknown palette for %d-colour BMP\n", 1 << depth);
                    return(-1);
                }
                break;

            default:
                log.av_log(avctx, log.AV_LOG_ERROR, "depth %d not supported\n", depth);
                return(-1);
            }

            if (avctx.pix_fmt == PixelFormat.PIX_FMT_NONE)
            {
                log.av_log(avctx, log.AV_LOG_ERROR, "unsupported pixel format\n");
                return(-1);
            }

            if (!p.data[0].IsNull)
            {
                avctx.release_buffer(avctx, p);
            }

            p.reference = 0;
            if (avctx.get_buffer(avctx, p) < 0)
            {
                log.av_log(avctx, log.AV_LOG_ERROR, "get_buffer() failed\n");
                return(-1);
            }

            p.pict_type = AVPictureType.AV_PICTURE_TYPE_I;

            p.key_frame = 1;

            buf   = buf0 + hsize;
            dsize = (int)(buf_size - hsize);

            /* Line size in file multiple of 4 */
            n = (int)(((avctx.width * depth + 31) / 8) & ~3);

            if (n * avctx.height > dsize && comp != BiCompression.BMP_RLE4 && comp != BiCompression.BMP_RLE8)
            {
                log.av_log(avctx, log.AV_LOG_ERROR, "not enough data (%d < %d)\n", dsize, n * avctx.height);
                return(-1);
            }

            // RLE may skip decoding some picture areas, so blank picture before decoding
            if (comp == BiCompression.BMP_RLE4 || comp == BiCompression.BMP_RLE8)
            {
                CLib.memset(p.data[0], 0, avctx.height * p.linesize[0]);
            }

            if (depth == 4 || depth == 8)
            {
                CLib.memset(p.data[1], 0, 1024);
            }

            if (height > 0)
            {
                ptr      = p.data[0] + (avctx.height - 1) * p.linesize[0];
                linesize = -p.linesize[0];
            }
            else
            {
                ptr      = p.data[0];
                linesize = p.linesize[0];
            }

            if (avctx.pix_fmt == PixelFormat.PIX_FMT_PAL8)
            {
                int colors = (1 << depth);
                if (ihsize >= 36)
                {
                    int t;
                    buf = buf0 + 46;
                    t   = (int)bytestream.get_le32(ref buf);
                    if (t < 0 || t > (int)(1 << depth))
                    {
                        log.av_log(avctx, log.AV_LOG_ERROR, "Incorrect number of colors - %X for bitdepth %d\n", t, depth);
                    }
                    else if (t != 0)
                    {
                        colors = t;
                    }
                }
                buf = buf0 + 14 + ihsize;                  //palette location
                if ((hsize - ihsize - 14) < (colors << 2)) // OS/2 bitmap, 3 bytes per palette entry
                {
                    for (i = 0; i < colors; i++)
                    {
                        var a = p.data[1].CastPointer <uint>();
                        a[i] = (uint)((0xff << 24) | bytestream.get_le24(ref buf));
                    }
                }
                else
                {
                    for (i = 0; i < colors; i++)
                    {
                        var a = p.data[1].CastPointer <uint>();
                        a[i] = (uint)((0xFFU << 24) | bytestream.get_le32(ref buf));
                    }
                }
                buf = buf0 + hsize;
            }

            if (comp == BiCompression.BMP_RLE4 || comp == BiCompression.BMP_RLE8)
            {
                if (height < 0)
                {
                    p.data[0]    += p.linesize[0] * (avctx.height - 1);
                    p.linesize[0] = -p.linesize[0];
                }

                //ff_msrle_decode(avctx, (AVPicture)p, depth, buf, dsize);
                Unimplemented.Mark();

                if (height < 0)
                {
                    p.data[0]    += p.linesize[0] * (avctx.height - 1);
                    p.linesize[0] = -p.linesize[0];
                }
            }
            else
            {
                switch (depth)
                {
                case 1:
                    for (i = 0; i < avctx.height; i++)
                    {
                        for (int j = 0; j < n; j++)
                        {
                            ptr[j * 8 + 0] = (byte)((buf[j] >> 7));
                            ptr[j * 8 + 1] = (byte)((buf[j] >> 6) & 1);
                            ptr[j * 8 + 2] = (byte)((buf[j] >> 5) & 1);
                            ptr[j * 8 + 3] = (byte)((buf[j] >> 4) & 1);
                            ptr[j * 8 + 4] = (byte)((buf[j] >> 3) & 1);
                            ptr[j * 8 + 5] = (byte)((buf[j] >> 2) & 1);
                            ptr[j * 8 + 6] = (byte)((buf[j] >> 1) & 1);
                            ptr[j * 8 + 7] = (byte)((buf[j] >> 0) & 1);
                        }
                        buf += n;
                        ptr += linesize;
                    }
                    break;

                case 8:
                case 24:
                case 32:
                    for (i = 0; i < avctx.height; i++)
                    {
                        //Console.WriteLine("i={0}, BytesPerRow={1}, linesize={2}", i, n, linesize);
                        CLib.memcpy(ptr, buf, n);
                        buf += n;
                        ptr += linesize;
                    }
                    break;

                case 4:
                    for (i = 0; i < avctx.height; i++)
                    {
                        for (int j = 0; j < n; j++)
                        {
                            ptr[j * 2 + 0] = (byte)((buf[j] >> 4) & 0xF);
                            ptr[j * 2 + 1] = (byte)(buf[j] & 0xF);
                        }
                        buf += n;
                        ptr += linesize;
                    }
                    break;

                case 16:
                    for (i = 0; i < avctx.height; i++)
                    {
                        Pointer <ushort> src = buf.CastPointer <ushort>();
                        Pointer <ushort> dst = ptr.CastPointer <ushort>();

                        for (int j = 0; j < avctx.width; j++)
                        {
                            dst[0] = av_bswap.av_le2ne16(src[0]);
                            src++;
                            dst++;
                        }

                        buf += n;
                        ptr += linesize;
                    }
                    break;

                default:
                    log.av_log(avctx, log.AV_LOG_ERROR, "BMP decoder is broken\n");
                    return(-1);
                }
            }

            outputData = s.picture;

            return(buf_size);
        } // decode
Exemple #6
0
        public Packet ReadPacket()
        {
            if (m_Socket == null)
            {
                return(null);
            }

            uint blockSize = m_ActiveExchangeContext.CipherClientToServer.BlockSize;

            // We must have at least 1 block to read
            if (m_Socket.Available < blockSize)
            {
                return(null);  // Packet not here
            }
            byte[] firstBlock = new byte[blockSize];
            int    bytesRead  = m_Socket.Receive(firstBlock);

            if (bytesRead != blockSize)
            {
                throw new SSHServerException(DisconnectReason.SSH_DISCONNECT_CONNECTION_LOST, "Failed to read from socket.");
            }

            firstBlock = m_ActiveExchangeContext.CipherClientToServer.Decrypt(firstBlock);

            uint packetLength  = 0;
            byte paddingLength = 0;

            using (ByteReader reader = new ByteReader(firstBlock))
            {
                // uint32    packet_length
                // packet_length
                //     The length of the packet in bytes, not including 'mac' or the
                //     'packet_length' field itself.
                packetLength = reader.GetUInt32();
                if (packetLength > Packet.MaxPacketSize)
                {
                    throw new SSHServerException(DisconnectReason.SSH_DISCONNECT_PROTOCOL_ERROR, $"Client tried to send a packet bigger than MaxPacketSize ({Packet.MaxPacketSize} bytes): {packetLength} bytes");
                }

                // byte      padding_length
                // padding_length
                //    Length of 'random padding' (bytes).
                paddingLength = reader.GetByte();
            }

            // byte[n1]  payload; n1 = packet_length - padding_length - 1
            // payload
            //    The useful contents of the packet.  If compression has been
            //    negotiated, this field is compressed.  Initially, compression
            //    MUST be "none".
            uint bytesToRead = packetLength - blockSize + 4;

            byte[] restOfPacket = new byte[bytesToRead];
            bytesRead = m_Socket.Receive(restOfPacket);
            if (bytesRead != bytesToRead)
            {
                throw new SSHServerException(DisconnectReason.SSH_DISCONNECT_CONNECTION_LOST, "Failed to read from socket.");
            }

            restOfPacket = m_ActiveExchangeContext.CipherClientToServer.Decrypt(restOfPacket);

            uint payloadLength = packetLength - paddingLength - 1;

            byte[] fullPacket = firstBlock.Concat(restOfPacket).ToArray();

            // Track total bytes read
            m_TotalBytesTransferred += fullPacket.Length;

            byte[] payload = fullPacket.Skip(Packet.PacketHeaderSize).Take((int)(packetLength - paddingLength - 1)).ToArray();

            // byte[n2]  random padding; n2 = padding_length
            // random padding
            //    Arbitrary-length padding, such that the total length of
            //    (packet_length || padding_length || payload || random padding)
            //    is a multiple of the cipher block size or 8, whichever is
            //    larger.  There MUST be at least four bytes of padding.  The
            //    padding SHOULD consist of random bytes.  The maximum amount of
            //    padding is 255 bytes.

            // byte[m]   mac (Message Authentication Code - MAC); m = mac_length
            // mac
            //    Message Authentication Code.  If message authentication has
            //    been negotiated, this field contains the MAC bytes.  Initially,
            //    the MAC algorithm MUST be "none".

            uint packetNumber = GetReceivedPacketNumber();

            if (m_ActiveExchangeContext.MACAlgorithmClientToServer != null)
            {
                byte[] clientMac = new byte[m_ActiveExchangeContext.MACAlgorithmClientToServer.DigestLength];
                bytesRead = m_Socket.Receive(clientMac);
                if (bytesRead != m_ActiveExchangeContext.MACAlgorithmClientToServer.DigestLength)
                {
                    throw new SSHServerException(DisconnectReason.SSH_DISCONNECT_CONNECTION_LOST, "Failed to read from socket.");
                }

                var mac = m_ActiveExchangeContext.MACAlgorithmClientToServer.ComputeHash(packetNumber, fullPacket);
                if (!clientMac.SequenceEqual(mac))
                {
                    throw new SSHServerException(DisconnectReason.SSH_DISCONNECT_MAC_ERROR, "MAC from client is invalid");
                }
            }

            payload = m_ActiveExchangeContext.CompressionClientToServer.Decompress(payload);

            using (ByteReader packetReader = new ByteReader(payload))
            {
                PacketType type = (PacketType)packetReader.GetByte();

                if (Packet.PacketTypes.ContainsKey(type))
                {
                    Packet packet = Activator.CreateInstance(Packet.PacketTypes[type]) as Packet;
                    packet.Load(packetReader);
                    packet.PacketSequence = packetNumber;
                    return(packet);
                }

                m_Logger.LogWarning($"Unimplemented packet type: {type}");

                Unimplemented unimplemented = new Unimplemented()
                {
                    RejectedPacketNumber = packetNumber
                };
                Send(unimplemented);
            }

            return(null);
        }
Exemple #7
0
        public static object Create(string eventName, object data)
        {
            object res;

            if (Ready.EventIsThis(eventName))
            {
                res = new Ready((JObject)data);
            }
            else if (Resumed.EventIsThis(eventName))
            {
                res = new Resumed((JObject)data);
            }
            else if (InvalidSession.EventIsThis(eventName))
            {
                res = (bool)((JValue)data).Value;
            }
            else if (Channel.EventIsThis(eventName))
            {
                res = new Channel((JObject)data);
            }
            else if (ChannelPinsUpdate.EventIsThis(eventName))
            {
                res = new ChannelPinsUpdate((JObject)data);
            }
            else if (EvtServer.EventIsThis(eventName))
            {
                res = new EvtServer((JObject)data);
            }
            else if (ServerDelete.EventIsThis(eventName))
            {
                res = ((JObject)data).ToObject <UaServerJson>().id;
            }
            else if (ServerUser.EventIsThis(eventName))
            {
                res = new ServerUser((JObject)data, eventName == ServerUser.MemberRemoveId);
            }
            else if (ServerUserSet.EventIsThis(eventName))
            {
                res = new ServerUserSet((JObject)data);
            }
            else if (ServerUserUpdate.EventIsThis(eventName))
            {
                res = new ServerUserUpdate((JObject)data);
            }
            else if (ServerEmojiUpdate.EventIsThis(eventName))
            {
                res = new ServerEmojiUpdate((JObject)data);
            }
            else if (RawServer.EventIsThis(eventName))
            {
                res = new RawServer((JObject)data);
            }
            else if (ServerRole.EventIsThis(eventName))
            {
                res = new ServerRole((JObject)data);
            }
            else if (ServerRoleDelete.EventIsThis(eventName))
            {
                res = new ServerRoleDelete((JObject)data);
            }
            else if (Message.EventIsThis(eventName))
            {
                res = new Message((JObject)data, eventName == Message.UpdateId);
            }
            else if (RawMessage.EventIsThis(eventName))
            {
                res = new RawMessage((JObject)data, eventName == RawMessage.BulkDeleteId);
            }
            else if (Reaction.EventIsThis(eventName))
            {
                res = new Reaction((JObject)data);
            }
            else if (ReactionRemoveAll.EventIsThis(eventName))
            {
                res = new ReactionRemoveAll((JObject)data);
            }
            else if (Webhook.EventIsThis(eventName))
            {
                res = new Webhook((JObject)data);
            }
            else if (EvtUser.EventIsThis(eventName))
            {
                res = new EvtUser((JObject)data);
            }
            else if (Unimplemented.EventIsThis(eventName))
            {
                res = Unimplemented.Instance;
            }
            else
            {
                throw new UnknownEventException("Gateway event \"" + eventName + "\" is unknown.");
            }
            DiscordDebug.WriteLine("Heard event: " + eventName + ", handling w/ object " + res.GetType().Name);
            return(res);
        }
Exemple #8
0
        private Packet ReadPacket()
        {
            if (!IsConnected)
            {
                return(null);
            }

            uint blockSize = activeExchangeContext.CipherClientToServer.BlockSize;

            // We must have at least one block available to read
            if (socket.Available < blockSize)
            {
                return(null);
            }

            // We have a block, read it
            byte[] firstBlock = new byte[blockSize];
            int    bytesRead  = socket.Receive(firstBlock);

            if (bytesRead != blockSize)
            {
                throw new SwishServerException(DisconnectReason.SSH_DISCONNECT_CONNECTION_LOST, "Failed to read from socket.");
            }

            // Decrypt the block
            firstBlock = activeExchangeContext.CipherClientToServer.Decrypt(firstBlock);

            // Pick out the packet length and padding. See https://tools.ietf.org/html/rfc4253#section-6
            uint packetLength  = 0;     // The length of the packet in bytes, not including 'mac' or the 'packet_length' field itself.
            uint paddingLength = 0;     // Length of 'random padding' (bytes).

            using (var reader = new ByteReader(firstBlock))
            {
                packetLength = reader.GetUInt32();

                if (packetLength > Packet.MaxPacketSize)
                {
                    throw new SwishServerException(DisconnectReason.SSH_DISCONNECT_PROTOCOL_ERROR, $"Client tried to send a packet bigger than MaxPacketSize ({Packet.MaxPacketSize} bytes): {packetLength} bytes");
                }

                paddingLength = reader.GetByte();
            }

            // Now that we know the packet length, read the rest of the payload
            uint bytesToRead = packetLength - blockSize + 4;

            // TODO - possible bug? What if the client has only written a block's worth of data?

            var restOfPacket = new byte[bytesToRead];

            bytesRead = socket.Receive(restOfPacket);
            if (bytesRead != bytesToRead)
            {
                throw new SwishServerException(DisconnectReason.SSH_DISCONNECT_CONNECTION_LOST, "Failed to read from socket.");
            }

            restOfPacket = activeExchangeContext.CipherClientToServer.Decrypt(restOfPacket);

            uint payloadLength = packetLength - paddingLength - 1;

            byte[] fullPacket = firstBlock.Concat(restOfPacket).ToArray();

            // Keep track of the total bytes transferred
            totalBytesTransferred += fullPacket.Length;

            // Pick out the payload
            var payload = fullPacket.Skip(Packet.PacketHeaderSize).Take((int)payloadLength).ToArray();

            // Get the packet number, so we know the sequence
            uint packetNumber = GetReceivedPacketNumber();

            // Check the MAC, if we have one
            if (activeExchangeContext.MACAlgorithmClientToServer != null)
            {
                byte[] clientMac = new byte[activeExchangeContext.MACAlgorithmClientToServer.DigestLength];
                bytesRead = socket.Receive(clientMac);
                if (bytesRead != activeExchangeContext.MACAlgorithmClientToServer.DigestLength)
                {
                    throw new SwishServerException(DisconnectReason.SSH_DISCONNECT_CONNECTION_LOST, "Failed to read from socket.");
                }

                var mac = activeExchangeContext.MACAlgorithmClientToServer.ComputeHash(packetNumber, fullPacket);
                if (!clientMac.SequenceEqual(mac))
                {
                    throw new SwishServerException(DisconnectReason.SSH_DISCONNECT_MAC_ERROR, "MAC from client is invalid");
                }
            }

            // Decompress
            payload = activeExchangeContext.CompressionClientToServer.Decompress(payload);

            // Parse the packet
            using (var reader = new ByteReader(payload))
            {
                var type = (PacketType)reader.GetByte();

                if (Packet.PacketTypes.ContainsKey(type))
                {
                    Packet packet = Activator.CreateInstance(Packet.PacketTypes[type]) as Packet;
                    packet.Load(reader);
                    packet.PacketSequence = packetNumber;
                    return(packet);
                }

                logger.LogWarning("Unimplemented packet type: {Type}.", type);

                var unimplemented = new Unimplemented
                {
                    RejectedPacketNumber = packetNumber
                };

                Send(unimplemented);
            }

            return(null);
        }
Exemple #9
0
 /**
  * Set the fields of the given AVFrame to default values.
  *
  * @param pic The AVFrame of which the fields should be set to default values.
  */
 static public void avcodec_get_frame_defaults(AVFrame pic)
 {
     Unimplemented.MarkWarning("avcodec_get_frame_defaults");
     //throw(new NotImplementedException());
 }