Example #1
0
        public static short ProtocolVersionToMagicNumber(WaveProtocolVersion protocolVer)
        {
            switch (protocolVer)
            {
            case WaveProtocolVersion.Version2:
                return(WaveMessage.MagicNumberV2);

            case WaveProtocolVersion.Version3:
                return(WaveMessage.MagicNumberV3);

            case WaveProtocolVersion.Version4:
                return(WaveMessage.MagicNumberV4);

            default:
                return(0);
            }
        }
Example #2
0
        public static string ProtocolVersionToInfoString(WaveProtocolVersion protocolVer)
        {
            switch (protocolVer)
            {
            case WaveProtocolVersion.Version2:
                return("v2");

            case WaveProtocolVersion.Version3:
                return("v3");

            case WaveProtocolVersion.Version4:
                return("v4");

            case WaveProtocolVersion.Unknown:
            default:
                return("unknown");
            }
        }
Example #3
0
        private void InitialiseFromStream(Stream str)
        {
            protocolVersion = MagicNumberToProtocolVersion((short)str.ReadByte());

            if (protocolVersion == WaveProtocolVersion.Version4)
            {
                messageSize = str.ReadInteger24();
            }
            else
            {
                messageSize = str.ReadShort();
            }

            applicationID = (byte)str.ReadByte();
            messageID     = (short)str.ReadByte();

            short numberOfFields       = str.ReadShort();
            byte  extras               = 0;
            int   extendedHeaderLength = 0;
            bool  isCompressed         = false;

            if (protocolVersion == WaveProtocolVersion.Version4)
            {
                extras = (byte)str.ReadByte();
            }

            isCompressed         = ((extras & CompressedDataFlag) == CompressedDataFlag);
            extendedHeaderLength = extras >> 4;

            if (extendedHeaderLength > 0)
            {
                str.Seek(extendedHeaderLength, SeekOrigin.Current);
            }

            if (isCompressed)
            {
                // get size of data when uncompressed
                int uncompressedSize = str.ReadInteger24();

                // calculate size of compressed data
                int compressedSize = messageSize;

                if (protocolVersion == WaveProtocolVersion.Version4)
                {
                    compressedSize -= HeaderSizeV4;
                }
                else
                {
                    compressedSize -= HeaderSizeV3;
                }

                compressedSize -= extendedHeaderLength;
                compressedSize -= 3; // size of uncompressedSize

                // uncompress
                byte[] compressedData = str.ReadBytes(compressedSize);

                if (compressedData != null)
                {
                    byte[] uncompressedMessage = CompressionHelper.DeflateBuffer(compressedData);

                    using (MemoryStream mem = new MemoryStream(uncompressedMessage))
                        rootList = new FieldList(mem, numberOfFields);
                }
            }
            else
            {
                rootList = new FieldList(str, numberOfFields);
            }
        }
Example #4
0
        public void OnMessageReceived(WaveServerComponent dest, Enum msgID, WaveMessage data)
        {
            if (msgID is UserManagerMessageID)
            {
                if (data != null)
                {
                    switch ((UserManagerMessageID)msgID)
                    {
                    case UserManagerMessageID.Challenge:
                    {
                        bool createAccount = false;

                        // check if there is login already (otherwise set defaults)
                        if (!Core.Application.HasLogin)
                        {
                            createAccount = true;
                            Core.Application.UpdateCredentials(GenerateNewUsername(), StringHelper.GetBytes(DefaultPassword));
                        }

                        // get CSL version
                        WaveCSLVersion serverCSL = (WaveCSLVersion)(data[UserManagerFieldID.CSLVersion].AsShort() ?? (short)WaveCSLVersion.Unknown);

                        switch (serverCSL)
                        {
                        case WaveCSLVersion.Version5:
                        case WaveCSLVersion.Version4:
                            Core.CSLVersion = serverCSL;
                            break;

                        default:
                            Core.CSLVersion = WaveCSLVersion.Version3;
                            break;
                        }

                        // get maximum protocol version
                        WaveProtocolVersion serverProto = (WaveProtocolVersion)(data[UserManagerFieldID.MaxWeMessageVersion].AsByte() ?? (byte)WaveProtocolVersion.Unknown);

                        switch (serverProto)
                        {
                        case WaveProtocolVersion.Version4:
                            Core.ProtocolVersion = WaveProtocolVersion.Version4;
                            break;

                        default:
                            Core.ProtocolVersion = WaveProtocolVersion.Version3;
                            break;
                        }

                        // get challenge
                        BinaryField challenge = (BinaryField)data[UserManagerFieldID.Challenge];

                        // assemble login message
                        WaveMessage msgOut = new WaveMessage();

                        msgOut.AddInt16(UserManagerFieldID.CSLVersion, (short)Core.CSLVersion);
                        msgOut.AddBoolean(UserManagerFieldID.EncryptSession, Core.UseEncryption);
                        msgOut.AddInt16(UserManagerFieldID.PriorityMask, NetworkAgent.PrioritiesActiveMask);
                        msgOut.AddBinary(UserManagerFieldID.UserCredentials, ProcessChallenge(challenge.Data, Core.Application, createAccount));
                        msgOut.AddBoolean(UserManagerFieldID.CreateAccount, createAccount);

                        // cache hash
                        byte[] cacheHash = Core.Cache.CacheHash;
                        msgOut.AddBinary(CacheAgentFieldID.CacheHashCompressed, (cacheHash.Length > 0) ? CompressionHelper.GZipBuffer(cacheHash) : cacheHash);

                        // cache ID (if any)
                        if (Core.Cache.CacheID.HasValue)
                        {
                            msgOut.AddBinary(MessageOutFieldID.CacheItemID, Core.Cache.CacheID.Value.ToByteArray());
                        }

                        // compiling device settings
                        FieldList deviceSettingsList = FieldList.CreateField(UserManagerFieldID.DeviceSettings);
                        deviceSettingsList.AddString(UserManagerFieldID.DeviceBuildID, Core.BuildID);
                        deviceSettingsList.AddBoolean(NaviAgentFieldID.DeviceSupportsTouch, true);
                        deviceSettingsList.AddInt16(NaviAgentFieldID.DeviceScreenResolutionWidth, 480);
                        deviceSettingsList.AddInt16(NaviAgentFieldID.DeviceScreenResolutionHeight, 800);

                        DeviceGroup[] devs = Core.System.SupportedDeviceGroups;

                        foreach (DeviceGroup dev in devs)
                        {
                            deviceSettingsList.AddInt16(NaviAgentFieldID.DeviceProfileGroup, (short)dev);
                        }

                        deviceSettingsList.AddString(UserManagerFieldID.LanguageID, CultureInfo.CurrentCulture.Name);
                        deviceSettingsList.AddString(UserManagerFieldID.Timezone, Core.Settings.TimeZone);
                        deviceSettingsList.AddBoolean(UserManagerFieldID.AlphaSupport, true);
                        deviceSettingsList.AddBoolean(UserManagerFieldID.CompressionSupport, true);
                        msgOut.AddFieldList(deviceSettingsList);

                        // compiling application request list
                        FieldList appRequestList = FieldList.CreateField(UserManagerFieldID.ApplicationRequest);
                        appRequestList.AddString(NaviAgentFieldID.ApplicationURN, Core.Application.URI);
                        appRequestList.AddInt16(NaviAgentFieldID.ApplicationRequestAction, (short)AppRequestAction.GetAppEntryPage);
                        msgOut.AddFieldList(appRequestList);

                        msgOut.Send(WaveServerComponent.UserManager, UserManagerMessageID.Login);

                        Core.UI.SignalViewNavigationStart(Core.UI.RootViewID);
                        break;
                    }

                    case UserManagerMessageID.EncryptionKeys:
                    {
                        // setting encryption (if allowed by build configuration)
                        if (Core.UseEncryption && (sessionHandshakeFish != null))
                        {
                            BinaryField sessionKeyField = (BinaryField)data[UserManagerFieldID.SessionKey];

                            byte[] sessionKey = (byte[])sessionKeyField.Data;
                            sessionHandshakeFish.Decrypt(sessionKey, sessionKey.Length);

                            BinaryField globalServerKeyField = (BinaryField)data[UserManagerFieldID.GlobalServerKey];

                            byte[] globalServerKey = (byte[])globalServerKeyField.Data;
                            sessionHandshakeFish.Decrypt(globalServerKey, globalServerKey.Length);

                            Core.NotifyEncryptionKeysChanged(this, sessionKey, globalServerKey);
                        }
                        else
                        {
                            Core.NotifyEncryptionKeysChanged(this, null, null);
                        }

                        // setting login data
                        StringField userName = (StringField)data[UserManagerFieldID.CreatedAccountUserName];

                        if (userName != null)
                        {
                            BinaryField userPass = (BinaryField)data[UserManagerFieldID.CreatedAccountPasswordHash];

                            if ((userPass != null) && (sessionHandshakeFish != null))
                            {
                                byte[] passBuffer = (byte[])userPass.Data.Clone();
                                sessionHandshakeFish.Decrypt(passBuffer, passBuffer.Length);

                                Core.Application.UpdateCredentials(userName.Data, passBuffer);

                                // no longer needed
                                sessionHandshakeFish = null;
                            }
                        }

                        break;
                    }

                    case UserManagerMessageID.LoginResponse:
                    {
                        if (!authenticated)
                        {
                            Int16Field loginStatus = (Int16Field)data[UserManagerFieldID.LoginStatus];

                            switch ((UserLoginStatus)loginStatus.Data)
                            {
                            case UserLoginStatus.Success:
                            {
                                // signal authentication success
                                Core.NotifyAuthentication(this, data[UserManagerFieldID.SessionInfo].AsByteArray());

                                // preparing login data message
                                FieldList appContext = (FieldList)data[UserManagerFieldID.ApplicationContext];

                                if (appContext != null)
                                {
                                    int    appID                = appContext[MessageOutFieldID.ApplicationID].AsInteger() ?? 0;
                                    string unqualifiedAppURI    = appContext[UserManagerFieldID.ApplicationUnqualifiedURI].AsText();
                                    string fullyQualifiedAppURI = appContext[UserManagerFieldID.ApplicationFullyQualifiedURI].AsText();

                                    Core.NotifySuccessfulLogin(this, appID, unqualifiedAppURI, fullyQualifiedAppURI);
                                }

                                authenticated     = true;
                                authenticatedEver = true;
                                break;
                            }

                            case UserLoginStatus.FailedInvalidCredentials:
                                Core.NotifyTerminateSession(this, SessionTerminationReasonCode.InvalidCredentials);
                                break;

                            case UserLoginStatus.FailedNoUser:
                                Core.NotifyTerminateSession(this, SessionTerminationReasonCode.NoSuchUser);
                                break;
                            }
                        }

                        break;
                    }
                    }
                }
            }
        }
Example #5
0
        public void Parse()
        {
            if (IsEmpty)
            {
                return;
            }

            if (!hasHeader)
            {
                // determine protocol version
                WaveProtocolVersion version = WaveMessage.MagicNumberToProtocolVersion(buffer[0]);

                if (version != WaveProtocolVersion.Unknown)
                {
                    // check if we have entire header yet
                    int headerSize = 0;

                    switch (version)
                    {
                    case WaveProtocolVersion.Version2:
                    case WaveProtocolVersion.Version3:
                        headerSize = 7;
                        break;

                    case WaveProtocolVersion.Version4:
                        headerSize = 9;
                        break;
                    }

                    if ((headerSize != 0) && (buffer.Length >= headerSize))
                    {
                        // we have entire header, so let's determine entire message size
                        if (version == WaveProtocolVersion.Version4)
                        {
                            // message size is a 24 bit integer
                            byte[] temp = new byte[3] {
                                buffer[1], buffer[2], buffer[3]
                            };

                            ExpectedSize = DataHelper.BytesToInt24(temp);

                            if (ExpectedSize == -1)
                            {
                                ExpectedSize = 0; // 0 is our "undefined" value
                            }
                        }
                        else
                        {
                            // message size is a 16 bit integer
                            byte[] temp = new byte[2] {
                                buffer[1], buffer[2]
                            };

                            ExpectedSize = BitConverter.ToInt16(temp, 0);
                        }

                        // do not repeat this again
                        hasHeader = true;
                    }
                }
            }
        }