public void UntrustContact(int contactId) { ThrowExceptionIfNotConnected(); lock (mutex) { if (contactId == this.UserId) { throw new Exception("You really don't want untrust yourself."); } Log("Sending UNTRUST_CONTACT command."); BinaryEncoder.SendCommand(stream, ConnectionCommand.UNTRUST_CONTACT); BinaryEncoder.SendInt(stream, contactId); using (Context context = new Context(config)) { var contact = new UContact(context.Contacts .Where(u => u.PublicId == contactId) .SingleOrDefault()) { Trusted = false }; PushOperations.SendJsonCapsula(context, contact.GetSelfUpdate(), UserId, UserId); context.SaveChanges(); } } Push(); }
public void Disconnect() { lock (mutex) { Log("Sending END_CONNECTION command."); isConnected = false; BinaryEncoder.SendCommand(stream, ConnectionCommand.END_CONNECTION); stream.Close(); client.Close(); } }
public SearchCServerCapsula SearchContact(SearchCClientCapsula searchCClientCapsula) { lock (mutex) { ThrowExceptionIfNotConnected(); BinaryEncoder.SendCommand(stream, ConnectionCommand.SEARCH_CONTACT); TextEncoder.SendJson(stream, searchCClientCapsula); return(TextEncoder.ReadJson <SearchCServerCapsula>(stream)); } }
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(); }
public int Pull() { int changes = 0; ThrowExceptionIfNotConnected(); lock (mutex) { Log("Sending PULL command."); BinaryEncoder.SendCommand(stream, ConnectionCommand.PULL); #if (DEBUG) Log("Sending ClientPullCapsula."); #endif ClientPullCapsula clientCapsula; using (Context context = new Context(config)) { clientCapsula = new ClientPullCapsula() { AesKeysUserIds = context.Contacts .Where(u => u.ReceiveAesKey == null) .Select(u => u.PublicId) .ToArray() }; } TextEncoder.SendJson(stream, clientCapsula); ServerPullCapsula capsula = TextEncoder.ReadJson <ServerPullCapsula>(stream); #if (DEBUG) Log("Received ServerPullCapsula."); #endif changes += capsula.AesKeysUserIds.Count; changes += capsula.Messages.Count; using (Context context = new Context(config)) { #if (DEBUG) Log("Receiving and saving AES keys."); #endif foreach (var id in capsula.AesKeysUserIds) { var user = new UContact(context.Contacts.Where(con => con.PublicId == id).SingleOrDefault()); try { user.ReceiveAesKey = RSAEncoder.DecryptAndVerify(BinaryEncoder.ReceiveBytes(stream), MyCertificate, X509Certificate2Utils.ImportFromPem(user.PublicCertificate)); } catch (Exception ex) { Log($"Loading of Receive AESKey from {user.PublicId} has failed."); logger.LogException(this, ex); } PushOperations.Update(context, user, UserId, UserId); } context.SaveChanges(); #if (DEBUG) Log("Receiving and saving messages."); #endif foreach (PullMessage metaMessage in capsula.Messages) { BlobMessages metaBlob = new BlobMessages() { PublicId = metaMessage.PublicId, SenderId = metaMessage.SenderId, Failed = 0, DoDelete = 0 }; context.BlobMessages.Add(metaBlob); context.SaveChanges(); try { PullMessageParser.ParseEncryptedMessage(context, BinaryEncoder.ReceiveBytes(stream), metaBlob.SenderId, metaBlob.Id, UserId); } catch (Exception ex) { Log($"Loading of message {metaMessage.PublicId} has failed."); metaBlob.Failed = 1; logger.LogException(this, ex); } context.SaveChanges(); } } Log("Pull have been done."); } return(changes); }
public void Push() { ThrowExceptionIfNotConnected(); lock (mutex) { Log("Sending PUSH command."); BinaryEncoder.SendCommand(stream, ConnectionCommand.PUSH); using (Context context = new Context(config)) { List <long> selfMessages = new List <long>(); var toSend = context.ToSendMessages.ToList(); PushCapsula capsula = new PushCapsula(); foreach (var message in toSend) { if (message.RecepientId == UserId) { selfMessages.Add((long)message.BlobMessagesId); } capsula.PushMessages.Add(new PushMessage() { RecepientId = (int)message.RecepientId, Priority = (int)message.Priority }); } capsula.MessageToDeleteIds = context.BlobMessages .Where(u => u.DoDelete == 1) .Select(u => (long)u.PublicId).ToList(); #if (DEBUG) Log($"Sending capsula with {toSend.Count} messages. {capsula.MessageToDeleteIds.Count} will be deleted."); #endif TextEncoder.SendJson(stream, capsula); #if (DEBUG) Log($"Sending message blobs."); #endif foreach (var message in toSend) { BinaryEncoder.SendBytes(stream, message.Blob); } #if (DEBUG) Log($"Receiving PushResponse"); #endif PushResponse response = TextEncoder.ReadJson <PushResponse>(stream); var selfMessagesZip = selfMessages.Zip(response.MessageIds, (u, v) => new { PrivateId = u, PublicId = v }); foreach (var message in selfMessagesZip) { context.BlobMessages.Where(u => u.Id == message.PrivateId) .SingleOrDefault().PublicId = message.PublicId; } #if (DEBUG) Log("Saving new public ids."); #endif context.SaveChanges(); #if (DEBUG) Log("Cleaning queue."); #endif context.Database.ExecuteSqlCommand("delete from TO_SEND_MESSAGES;"); context.Database.ExecuteSqlCommand("delete from BLOB_MESSAGES where DO_DELETE=1 and PUBLIC_ID<>null;;"); context.SaveChanges(); } Log("Push have been done."); } }