Ejemplo n.º 1
0
        public void TrustContact(int contactId)
        {
            Pull();
            Log("Sending TRUST_CONTACT command.");
            TextEncoder.SendCommand(stream, ConnectionCommand.TRUST_CONTACT);

            TextEncoder.SendInt(stream, contactId);
            using (Context context = new Context(config))
            {
                var contact = context.Contacts
                              .Where(u => u.PublicId == contactId)
                              .SingleOrDefault();
                contact.Trusted = 1;
                context.SaveChanges();

                if (contact.SendAesKey == null)
                {
                    AESPassword password = AESPassword.GenerateAESPassword();
                    JAESKey     key      = new JAESKey(contactId, password);
                    PushOperations.SendIJType(context, key, UserId, UserId);

                    X509Certificate2 cert = X509Certificate2Utils.ImportFromPem(
                        context.Contacts
                        .Where(u => u.PublicId == contactId)
                        .Select(u => u.PublicCertificate)
                        .SingleOrDefault());
                    BinaryEncoder.SendBytes(stream, RSAEncoder.Encrypt(password.Password, cert));

                    context.SaveChanges();
                }
            }
            Push();
        }
Ejemplo n.º 2
0
        public void Connect(String password = null)
        {
            lock (mutex)
            {
                client = new TcpClient(serverAddress, ServerPort);
                logger.Log(this, "Client connected.");

                stream = new SslStream(client.GetStream(), false, verificator.AppCertificateValidation);
                X509CertificateCollection clientCertificates = new X509CertificateCollection();
                clientCertificates.Add(MyCertificate);

                stream.AuthenticateAsClient("Dummy", clientCertificates, SslProtocols.Tls12, false);
                logger.Log(this, "SSL authentication completed.");


                logger.Log(this, "Handshake started.");
                var handshake = Handshake.Login(logger, stream, MyCertificate, password, UserName, ClientId);
                logger.Log(this, "Handshake successeded.");

                UserName        = handshake.UserName;
                UserId          = handshake.UserId;
                ClientId        = handshake.ClientId;
                SelfAesPassword = handshake.SelfAesPassword;
                logger.Log(this, $"User {UserName} has id {UserId}. Client has id {ClientId}.");

                isConnected = true;
            }
        }
Ejemplo n.º 3
0
        public static IJType GetJsonDecoded(Context context, byte[] message, long senderId)
        {
            byte[] aesBinKey = context.Contacts
                               .Where(u => u.PublicId == senderId)
                               .Select(u => u.ReceiveAesKey)
                               .SingleOrDefault();

            AESPassword key = new AESPassword(aesBinKey);

            byte[]    decrypted = key.Decrypt(message);
            JsonTypes type      = (JsonTypes)decrypted[0];
            string    jsonText  = Encoding.UTF8.GetString(decrypted, 1, decrypted.Length - 1);

            switch (type)
            {
            case JsonTypes.ALARM:
                return(JsonConvert.DeserializeObject <JAlarm>(jsonText));

            case JsonTypes.CONTACT_DETAIL:
                return(JsonConvert.DeserializeObject <JContactDetail>(jsonText));

            case JsonTypes.MESSAGES:
                return(JsonConvert.DeserializeObject <JMessage>(jsonText));

            case JsonTypes.MESSAGES_THREAD:
                return(JsonConvert.DeserializeObject <JMessageThread>(jsonText));

            case JsonTypes.AES_KEY:
                return(JsonConvert.DeserializeObject <JAESKey>(jsonText));

            default:
                throw new Exception("Unknown JsonType.");
            }
        }
Ejemplo n.º 4
0
        public static byte[] GetJsonEncoded(Context context, IJType message, long receiverId, byte[] attechment = null)
        {
            byte[] aesBinKey = context.Contacts
                               .Where(u => u.PublicId == receiverId)
                               .Select(u => u.SendAesKey)
                               .SingleOrDefault();

            AESPassword key = new AESPassword(aesBinKey);

            MemoryStream stream = new MemoryStream();

            BinaryEncoder.SendInt(stream, (int)message.GetJsonType());

            string json = JsonConvert.SerializeObject(message);

            TextEncoder.SendString(stream, json);

            if (attechment == null)
            {
                BinaryEncoder.SendInt(stream, 0);
            }
            else
            {
                BinaryEncoder.SendInt(stream, 1);
                BinaryEncoder.SendBytes(stream, attechment);
            }

            byte[] notEncrypted = stream.ToArray();
            return(key.Encrypt(notEncrypted));
        }
Ejemplo n.º 5
0
        public static JsonCapsula GetJsonDecoded(Context context, byte[] message, long senderId)
        {
            byte[] aesBinKey = context.Contacts
                               .Where(u => u.PublicId == senderId)
                               .Select(u => u.ReceiveAesKey)
                               .SingleOrDefault();

            AESPassword key = new AESPassword(aesBinKey);

            byte[] decrypted = key.Decrypt(message);

            MemoryStream stream   = new MemoryStream(decrypted);
            JsonTypes    type     = (JsonTypes)BinaryEncoder.ReadInt(stream);
            string       jsonText = TextEncoder.ReadString(stream);

            byte[] attechment   = null;
            int    isAttechment = BinaryEncoder.ReadInt(stream);

            if (isAttechment == 1)
            {
                attechment = BinaryEncoder.ReceiveBytes(stream);
            }

            IJType jmessage;

            switch (type)
            {
            case JsonTypes.ALARM:
                jmessage = JsonConvert.DeserializeObject <JAlarm>(jsonText);
                break;

            case JsonTypes.CONTACT:
                jmessage = JsonConvert.DeserializeObject <JContact>(jsonText);
                break;

            case JsonTypes.MESSAGES:
                jmessage = JsonConvert.DeserializeObject <JMessage>(jsonText);
                break;

            case JsonTypes.MESSAGES_THREAD:
                jmessage = JsonConvert.DeserializeObject <JMessageThread>(jsonText);
                break;

            default:
                throw new Exception("Unknown JsonType.");
            }

            return(new JsonCapsula()
            {
                Attechment = attechment,
                Message = jmessage
            });
        }
Ejemplo n.º 6
0
        static void AesTrial()
        {
            using (Context context = new Context(config))
            {
                byte[] aesBinKey = context.Contacts
                                   .Where(u => u.PublicId == connection.UserId)
                                   .Select(u => u.ReceiveAesKey)
                                   .SingleOrDefault();

                AESPassword key     = new AESPassword(aesBinKey);
                String      testStr = "Testy tisty teristy\n";
                for (int i = 0; i != 3; i++)
                {
                    testStr += testStr;
                }
                WriteLine($"Encrypting string: {testStr}");

                byte[] data      = Encoding.UTF8.GetBytes(testStr);
                byte[] encrypted = key.Encrypt(data);
                WriteLine(Encoding.UTF8.GetString(key.Decrypt(encrypted)));
            }
        }
Ejemplo n.º 7
0
        public static byte[] GetJsonEncoded(Context context, IJType message, long receiverId)
        {
            byte[] aesBinKey = context.Contacts
                               .Where(u => u.PublicId == receiverId)
                               .Select(u => u.SendAesKey)
                               .SingleOrDefault();

            AESPassword key = new AESPassword(aesBinKey);

            MemoryStream stream = new MemoryStream();

            stream.WriteByte((byte)message.GetJsonType());

            string       json   = JsonConvert.SerializeObject(message);
            StreamWriter writer = new StreamWriter(stream, Encoding.UTF8);

            writer.Write(json);
            writer.Close();

            byte[] notEncrypted = stream.ToArray();
            return(key.Encrypt(notEncrypted));
        }
Ejemplo n.º 8
0
        /// <summary>
        /// 这是一次彻底的重连,重新获取服务器地址的重连,以下情况下才会调用该方法:
        /// 1,进程启动后第一次连接时;
        /// 2,连不上服务器时;
        /// 3,收到服务器的WsMessage.ReGetServerAddress类型的消息时;
        /// </summary>
        /// <returns></returns>
        private void NewWebSocket(Action <WebSocket> callback)
        {
            RpcRoot.OfficialServer.WsServerNodeService.GetNodeAddressAsync(NTMinerRegistry.GetClientId(_appType), _outerUserId, (response, ex) => {
                LastTryOn = DateTime.Now;
                if (!response.IsSuccess())
                {
                    IncreaseFailCount();
                    UpdateNextTrySecondsDelay();
                    string description;
                    if (response == null || response.ReasonPhrase == null)
                    {
                        description = "网络错误";
                    }
                    else
                    {
                        description = response.ReadMessage(ex);
                    }
                    UpdateWsStateAsync(description, toOut: false);
                    callback?.Invoke(null);
                    // 退出
                    return;
                }
                string server = response.Data;
                if (string.IsNullOrEmpty(server))
                {
                    IncreaseFailCount();
                    UpdateNextTrySecondsDelay();
                    UpdateWsStateAsync("服务器不在线", toOut: false);
                    callback?.Invoke(null);
                    // 退出
                    return;
                }

                var ws     = new WebSocket($"ws://{server}/{_appType.GetName()}");
                ws.OnOpen += (sender, e) => {
                    ResetFailCount();
                    UpdateWsStateAsync("连接服务器成功", toOut: false);
                };
                ws.OnMessage += (sender, e) => {
                    if (_ws != ws)
                    {
                        return;
                    }
                    #region
                    if (e.IsPing)
                    {
                        return;
                    }
                    WsMessage message = null;
                    if (e.IsBinary)
                    {
                        message = VirtualRoot.BinarySerializer.Deserialize <WsMessage>(e.RawData);
                    }
                    else  // 此时一定IsText,因为取值只有IsBinary、IsPing、IsText这三种
                    {
                        if (string.IsNullOrEmpty(e.Data) || e.Data[0] != '{' || e.Data[e.Data.Length - 1] != '}')
                        {
                            return;
                        }
                        message = VirtualRoot.JsonSerializer.Deserialize <WsMessage>(e.Data);
                    }
                    if (message == null)
                    {
                        return;
                    }
                    switch (_appType)
                    {
                    case NTMinerAppType.MinerClient:
                        if (message.Type == WsMessage.UpdateAESPassword)
                        {
                            if (message.TryGetData(out AESPassword aesPassword))
                            {
                                aesPassword.Password = Cryptography.RSAUtil.DecryptString(aesPassword.Password, aesPassword.PublicKey);
                                _aesPassword         = aesPassword;
                            }
                            return;
                        }
                        if (_aesPassword == null)
                        {
                            return;
                        }
                        if (message.Sign != message.CalcSign(_aesPassword.Password))
                        {
                            UpdateWsStateAsync(description: "来自群控的消息签名错误", toOut: true);
                            return;
                        }
                        break;
Ejemplo n.º 9
0
        public void TrustContact(int contactId)
        {
            ThrowExceptionIfNotConnected();

            Pull();
            lock (mutex)
            {
                Log("Sending TRUST_CONTACT command.");
                BinaryEncoder.SendCommand(stream, ConnectionCommand.TRUST_CONTACT);

                BinaryEncoder.SendInt(stream, contactId);
                using (Context context = new Context(config))
                {
                    var contact = new UContact(context.Contacts
                                               .Where(u => u.PublicId == contactId)
                                               .SingleOrDefault())
                    {
                        Trusted = true
                    };


                    if (contact.SendAesKey == null)
                    {
                        Log("Sending new key.");
                        BinaryEncoder.SendInt(stream, 1);
                        AESPassword password = AESPassword.GenerateAESPassword();

                        contact.SendAesKey = password.Password;
                        X509Certificate2 recepientCert = X509Certificate2Utils.ImportFromPem(
                            context.Contacts
                            .Where(u => u.PublicId == contactId)
                            .Select(u => u.PublicCertificate)
                            .SingleOrDefault());

                        byte[] toSend = RSAEncoder.EncryptAndSign(password.Password, recepientCert, MyCertificate);
                        BinaryEncoder.SendBytes(stream, toSend);
                    }
                    else
                    {
                        Log("No new key will be sended.");
                        BinaryEncoder.SendInt(stream, 0);
                    }

                    if (contactId != this.UserId)
                    {
                        PushOperations.SendJsonCapsula(context, contact.GetSelfUpdate(), UserId, UserId);
                    }
                    else
                    {
                        var me = context.Contacts
                                 .Where(u => u.PublicId == UserId)
                                 .Single();
                        me.SendAesKey    = contact.SendAesKey;
                        me.ReceiveAesKey = contact.ReceiveAesKey;
                    }

                    context.SaveChanges();
                }
                Log("Trustification has been done.");
            }
            Push();
        }
Ejemplo n.º 10
0
        private void Ws_OnMessage(object sender, MessageEventArgs e)
        {
            WebSocket ws = (WebSocket)sender;

            if (_ws != ws)
            {
                return;
            }
            #region
            if (e.IsPing)
            {
                return;
            }
            WsMessage message = null;
            if (e.IsBinary)
            {
                message = VirtualRoot.BinarySerializer.Deserialize <WsMessage>(e.RawData);
            }
            else  // 此时一定IsText,因为取值只有IsBinary、IsPing、IsText这三种
            {
                if (string.IsNullOrEmpty(e.Data) || e.Data[0] != '{' || e.Data[e.Data.Length - 1] != '}')
                {
                    return;
                }
                message = VirtualRoot.JsonSerializer.Deserialize <WsMessage>(e.Data);
            }
            if (message == null)
            {
                return;
            }
            switch (_appType)
            {
            case NTMinerAppType.MinerClient:
                if (message.Type == WsMessage.UpdateAESPassword)
                {
                    if (message.TryGetData(out AESPassword aesPassword))
                    {
                        aesPassword.Password = Cryptography.RSAUtil.DecryptString(aesPassword.Password, aesPassword.PublicKey);
                        _aesPassword         = aesPassword;
                    }
                    return;
                }
                if (_aesPassword == null)
                {
                    return;
                }
                if (message.Sign != message.CalcSign(_aesPassword.Password))
                {
                    UpdateWsStateAsync(description: "来自群控的消息签名错误", toOut: true);
                    return;
                }
                break;

            case NTMinerAppType.MinerStudio:
                if (message.Type == WsMessage.ReLogin)
                {
                    UpdateWsStateAsync(description: "用户密码已变更,请重新登录", toOut: true);
                    return;
                }
                if (message.Sign != message.CalcSign(RpcRoot.RpcUser.Password))
                {
                    UpdateWsStateAsync(description: "来自群控的消息签名错误", toOut: true);
                    return;
                }
                break;

            default:
                break;
            }
            if (message.Type == WsMessage.ReGetServerAddress)
            {
                ws.CloseAsync(CloseStatusCode.Normal, WsMessage.ReGetServerAddress);
                return;
            }
            if (TryGetHandler(message.Type, out Action <Action <WsMessage>, WsMessage> handler))
            {
                handler.Invoke(SendAsync, message);
            }
            else
            {
                NTMinerConsole.DevWarn(() => $"OnMessage Received InvalidType {e.Data}");
            }
            #endregion
        }
Ejemplo n.º 11
0
 public JAESKey(long UserId, AESPassword password)
 {
     this.UserId = UserId;
     this.AESKey = password.Password;
 }