External (internet) Pub Sub - c#

Lately I started to think about a solution to publish messages across the internet to subscribed clients I have. Our system is developed in C#.
We tried to use Redis, it works very good in terms of speed and accuracy, but very bad in terms of security, everyone can subscribe to everything, and the best I can do is:
1) Rename core-functions so they'll be unusable
2) Add authentication (but its per server, not per client)
I have 2 questions:
1) Can I do more in terms of Redis security? Can I set password per subscriber? per channel?
2) Are there any other solutions any of you is aware of?
Thanks!

Redis has no access control whatsoever almost (but just the generic AUTH), and even the planned ACL feature does not include explicit support for subscribing / posting to specific channels.
However... there is a surprising simple thing you could do, if you disable MONITOR and other commands that can be used in order to listen to other clients connections, which is, to use an HMAC in order to hash together the logical channel name with the password in order to obtain the real channel name, which is unguessable to clients that don't know the password.
This is the schema (but you should carefully consider if this is secure depending on your exact setup, connections encryption, set of enabled commands. I can just guarantee that it's crypto-hard to obtain the channel name, and that no channel name can be guessed at random).
For example the password for channel "foo" is "bar". To obtain the channel name you do:
HMAC-SHA256("bar","foo") -> 01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b
And you have your channel name.
IMPORTANT: Note that N clients with the same wrong (old) password will still be able to communicate. This should not be a problem in most setups since they can communicate anyway in this case just subscribing to the same channel name.
IMPORTANT2: If this is over the internet, you should tunnel all this over SSL or a VPN.
IMPORTANT3: On top of all that, make sure to also use AUTH as an additional authentication layer.

Related

Real time multi user interaction

The program I am making requires the use of real time cross computer interactions via the internet.
The issue I'm coming across is that while I wish for the clients to connect to a host client rather then going for a client server model there are a lot of problems in terms of getting the host client able to actually host (accept an incoming connection, etc.)
I'm trying to make the process of hosting a session as simple as possible, so that a user with no networking knowledge can accept incoming connections without having to configure their router or any other such thing. I was wondering how I could achieve this?
Sounds like you want to programatically update firewall rules, given the variation in network set ups, it's not possible to have a one size fits all approach. I think you have three choices, the last probably being the better:
1) http://en.wikipedia.org/wiki/Internet_Gateway_Device_Protocol
2) http://en.wikipedia.org/wiki/Tunneling_protocol
3) instructions for users to configure their routers (will be needed as a back-up for users who the first two fail for)

How to secure a service from being looped through to find out its api key

Let's say we have a WCF web service. and its link is as follows;
http://www.example.com/service/?api=62383581
62383581 is the API key here. How can we secure the service from being looped through to find out its API key?
i think the discussion should be "how to make it difficult" not preventing it, since if you are going to expose your service to Public you are prone to attacks.
The possibilities to make it difficult could be:
if you are providing access to your service to a close set of customers then you can apply IP restrictions on your Server to prevent calls from any other service, again this will prevent any calls from Client side scripts (e.g. JavaScript) and will be open to IP-Spoofing
You can place IP-restrictions in your Service too. in Message Inspector you can verify the IP and if it's not in your range throw an exception to prevent further access.
Use Alpha Numeric API key with inclusion of special characters to make it very complex and difficult to loop through (Brute force) (The best fit i can consider for your scenario)
you can give your client a public key (different for each client) ask them to append some identifier with key e.g. api&customerID and encrypt it with your key since on server side you have the Private key for that specific client and vice verse.. (this contains overhead of encryption decryption)
and if you have man in middle then this can compromise all above.
These are all to make things difficult and may require rethinking depending on your detailed scenario.
Use GUID instead of Int to make it much harder to bruteforce it.
I suppose checking the caller's IP address and preventing the same IP address to make more than n calls per hour would be pointless, since attackers would use spoofing to throw such efforts off.
The only way I can think of is to use either a strong configurable firewall that can detect such attacks, or an Intrusion Prevention System (IPS) such as Winsnort. See also http://www.winsnort.com/index.php?module=News&func=display&sid=41
Any API key contained in a program on an untrusted client can be leaked by definition.

Is it possible to enforce web service calls from known client only?

Scenario:
A publically available Web Service that I have full control over.
But I only want this specific desktop application (my published application) to have access to the Web Service.
I could store a secret password in the desktop client, but that would be easy to crack.
Is there any known implementation that enforces this?
PKI, assymmetric keys?
If the public will have access to copies of this Desktop App, any good reverser will be able to crack it and "imitate" its transactions with the server. It doens't matter how secure is your cryptography, everything you app needs to encrypt/decrypt data is included in the binaries, so the cracker only needs to dig it out of it.
The objective of cryptography is to protect data while it is being transfered, from "middle-man" hackers, but if you have access to anyone of the peers, you can easily crack it.
Your server must never trust what comes from the client side.
[edit resuming]
Despite you cannot 100% guarantee a supposed client to your server is or isn't your App or some "emulator" made by thirdies, you can complicate things to them. Its a common practice in game anti-cheats to sometimes, randomly, make the client App a trick question like "whats the hash of your main.exe from offset A to offset B?" or "from now on packet type 0x07 swaps with packet type 0x5f". Once a fake is detected, server enter in a "silly mode", act malfunctional, and blacklist their IP/account to this mode for several hours so they cannot have sure of what their program is doing wrong.
If you detect someone is building an emulator, make them start all over again: jumble the packet type tables, cryptography tables, change some packet formats and force your clients to update. You won't see crackers bothering you for a while... LOL
WS-Security provides for X509 encryption.
Part of that implementation includes the possibility of only giving specific clients the generated public key. That way, only your selected clients can connect to the service.
The easiest way is message security using client and server certificates. The best way is to import the client certs in your server machines and hard code the client cert thumbprint in the app.config file. The other way is negotiation of certs which I haven't tried before.
If you are using IIS to host the service then client certificates using SSL is another option.
MSDN link on WCF Security.

Track messages though Windows Live Messenger

I would like to track messages sent and received though Windows Live Messenger. I would then like to collate these messages into a database (not in the scope of this question).
The question is how and where should I track these messages. The simplest way it to force all clients to keep history files and read those, but it is not really the solution that I am looking for. Is there a way to track them from a server running in the same domain, I have read a little into Windows Communicator, I have also seen a lot of people chat about http://dev.live.com/messenger/ but I was hoping that someone may have addressed this problem already :)
I would like to do this using C# .NET 3.5
Check out MSNPSharp. Its a .NET msn library. Its very powerful and allows you to sign in from multiple locations. So you can sign in and listen to other conversations happening on a given account.
Its very straight forward to use. Download the full source code, there's a sample application that demonstrates its use in full detail.
http://code.google.com/p/msnp-sharp/
Here is two idea that might work.
The first one is the easiest but can be easily avoided by the user if he doesn't want to be logged. It would be to use MSN Plus over the MSN. With MSN Plus you have an API that let you get all messages from any Chat Windows... and a lot more. Of course, if the user is not you, the user can simply uninstall Msn Plus and your program will not log any data.
The second idea is better if you have a network that you require to check all Msn Conversation. If you use WireShark you can see that conversation are not crypted (well the last time I did it) and you can check the port and protocol to simply get the data from the network.
Hope it gives you a way to what you need.
Just two ideas
1. First the standard MSN protocol is plain text (from what I understand) so you could intercept the messages on the firewall and then put them in the DB and do the correlation there.
2. If this is in an organisation you could use Office Communicator which is the "corporate" version of MSN and has that functionality built in already. You can then just go in via their SDK and get the correlated data.
I managed to find two ways of doing this, though both are not really programmatic solutions, so may not appeal to this audience.
Make use of a Jabber gateway to set up forwards between your jabber client and the other IM networks. Traffic flows between your jabber enabled client and the jabber server via the jabber server. The Jabber server then translates this to the destination networks protocol and forwards the message. Likewise messages from the external IM networks are routed and translated by the Jabber server. An example of this is PSI <-> IceWarp Merak <-> MSN
Make use of Symantec IM Manager to intercept messages from the messaging clients on your network. You will need to either use host files or local DNS rules to convince the your local PCs that Messenger.hotmail.com is actually located at 192.168.0.59 and not at Microsoft.
Hope it helps other people that may want to do the same.

Whats the best way to send an event to all workstations

I hope someone can guide me as I'm stuck... I need to write an emergency broadcast system that notifies workstations of an emergency and pops up a little message at the bottom of the user's screen. This seems simple enough but there are about 4000 workstations over multiple subnets. The system needs to be almost realtime, lightweight and easy to deploy as a windows service.
The problem started when I discovered that the routers do not forward UDP broadcast packets x.x.x.255. Later I made a simple test hook in VB6 to catch net send messages but even those didn't pass the routers. I also wrote a simple packet sniffer to filter packets only to find that the network packets never reached the intended destination.
Then I took a look and explored using MSMQ over HTTP, but this required IIS to be installed on the target workstation. Since there are so many workstations it would be a major security concern.
Right now I've finished a web service with asynchronous callback that sends an event to subscribers. It works perfectly on a small scale but once there are more than 15 subscribers performance degrades considerably. Polling a server isn't really an option because of the load it will generate on the server (plus I've tried it too)
I need your help to guide me as to what technology to use. has anyone used the comet way with so many clients or should I look at WCF?
I'm using Visual C# 2005. Please help me out of this predicament.
Thanks
Consider using WCF callbacks mechanism and events. There is good introduction by Juval Lowy.
Another pattern is to implement blocking web-service calls. This is how GMail chat works, for example. However, you will have to deal with sessions and timeouts here. It works when clients are behind NATs and Firewalls and not reachable directly. But it may be too complicated for simple alert within intranet.
This is exactly what Multicast was designed for.
A normal network broadcast (by definition) stays on the local subnet, and will not be forwarded through routers.
Multicast transmissions on the other hand can have various scopes, ranging from subnet local, through site local, even to global. All you need is for the various routers connecting your subnets together to be multicast aware.
This problem i think is best solved with socket.
Open a connection to the server, and keep it open.
Could you have a slave server in each subnet that was responsible for distributing the messages to all the clients in the subnet?
Then you could have just the slaves attached to the central server where the messages are initiated.
I think some of you are vastly overthinking this. There is already a service built into every version of Windows that provides this exact functionality! It is called the Messenger service. All you have to do is ensure that this service is enabled and running on all clients.
(Although you didn't specify in the question, I'm assuming from your choices of technology that the client population of this network is all Windows).
You can send messages using this facility from the command line using something like this:
NET SEND computername "This is a test message"
The NET SEND command also has options to send by Windows domain, or to specific users by name regardless of where they are logged in, or to every system that is connected to a particular Windows server. Those options should let you easily avoid the subnet issue, particularly if you use domain-based security on your network. (You may need the "Alerter" service enabled on certain servers if you are sending messages through the server and not directly to the clients).
The programmatic version of this is an API called NetMessageBufferSend() which is pretty straightforward. A quick scan of P/Invoke.net finds a page for this API that supplies not only the definitions you need to call out to the API, but also a C# sample program!
You shouldn't need to write any client-side code at all. Probably the most involved thing will be figuring out the best set of calls to this API that will get complete coverage of the network in your configuration.
ETA: I just noticed that the Messenger service and this API are completely gone in Windows Vista. Very odd of Microsoft to completely remove functionality like this. It appears that this vendor has a compatible replacement for Vista.

Categories