views:

178

answers:

1

Hello,

I'm writing a client-server application to be used in a computer lab and act as a service (without running as a service). I have a console application calling the native function "ShowWindow"/SW_HIDE using the console's HWND object -- this gives it what I am wanting here. The server/client is working, I've sent the message "Hello world!" from the client to the server many times and I'm pleased. (I'm using UDP for the socket protocol because the IT department wants a connectionless approach.)

My question lies in a 'protocol' for communication between client-server.

The goals behind the server include the following:

  • Give access, programmatically, to certain abilities that our IT-Department has blocked for security (e.g. "net.exe")
  • Give access to my program to monitor what students are viewing in the computer lab.

Some things I want to include are simple questions being sent back and forth:

  • A command of "REQUSER" would return the username and fullname (as allowed by "net user" previously)
  • A command of "REQPROCS" would return a list of processes currently being ran under current user's username.

I have no doubt I am able to do this. The thing I am leary of at the moment is data safety. We do have some "hackers" here at my college who may know how to packet sniff and be able to resend packets out to specific servers to either do malicious things or get information on an enemy or whatnot.

My thought was to provide an encryption scheme on all data sent and decode it on receive.

A friend who I talked to said I should use a bit packer and I started porting his BitPacker class from C++ to C# which I got confused with and came here to see what Stackoverflow thought.

namespace Atlantis.Net.Sockets
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Linq;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;
    using System.Windows.Forms;

    public class UdpServer : System.Net.Sockets.UdpClient
    {

        #region Constructor(s)

        public UdpServer(Int32 port)
            : base(port)
        {
        }

        public UdpServer(IPEndPoint endPoint)
            : base(endPoint)
        {
        }

        #endregion

        #region Properties

        private Int32 m_Backlog = 32;
        /// <summary>
        ///     Sets how many active connections the socket can support
        /// </summary>
        public Int32 Backlog
        {
            private get
            {
                return m_Backlog;
            }
            set
            {
                m_Backlog = value;
            }
        }

        private Boolean m_IsInitialized = false;
        /// <summary>
        ///     Gets a value indicating whether the server has been initialized
        /// </summary>
        public Boolean IsInitialized
        {
            get
            {
                return m_IsInitialized;
            }
            private set
            {
                m_IsInitialized = value;
            }
        }

        private Int32 m_Port = 1337;
        /// <summary>
        ///     Sets the port number for listening for incoming connections
        /// </summary>
        public Int32 Port
        {
            private get
            {
                return m_Port;
            }
            set
            {
                m_Port = value;
            }
        }

        private Encoding m_Encoding = Encoding.ASCII;
        /// <summary>
        ///     Gets or sets the text encoding for data being transferred to/from the server
        /// </summary>
        public Encoding Encoding
        {
            get
            {
                return m_Encoding;
            }
            set
            {
                m_Encoding = value;
            }
        }

        #endregion

        #region Events

        public event EventHandler<UdpReceiveEventArgs> DataReceive;

        #endregion

        #region Methods

        protected virtual void OnDataRecieve(String data, object state)
        {
            if (DataReceive != null)
            {
                DataReceive(this, new UdpReceiveEventArgs(data, ((UdpState)state)));
            }
        }

        private void DataReceiveCallback(IAsyncResult ar)
        {
            UdpClient u = (UdpClient)((UdpState)ar.AsyncState).host;
            IPEndPoint e = (IPEndPoint)((UdpState)ar.AsyncState).endPoint;

            Byte[] data = u.EndReceive(ar, ref e);

            OnDataRecieve(Encoding.GetString(data), ((UdpState)ar.AsyncState));

            UdpState state = new UdpState();
            state.endPoint = new IPEndPoint(IPAddress.Any, Port);
            state.host = u;
            u.BeginReceive(new AsyncCallback(DataReceiveCallback), ((UdpState)ar.AsyncState));
        }

        /// <summary>
        ///     .
        /// </summary>
        public void Initialize()
        {
            if (IsInitialized)
            {
                return;
            }
            //Debug.WriteLine(String.Format("Local address and port : {0}", Client.RemoteEndPoint.ToString()));

            UdpState state = new UdpState();
            state.endPoint = new IPEndPoint(IPAddress.Any, Port);
            state.host = this;
            BeginReceive(new AsyncCallback(DataReceiveCallback), state);

            IsInitialized = true;
        }

        #endregion

    }
}

P.S. I hope the question is clear? I've noticed most of my questions I write are unclear. :/

+1  A: 

SslStream Class from System.Net.Security might do what you need

(SslStream) Provides a stream used for client-server communication that uses the Secure Socket Layer (SSL) security protocol to authenticate the server and optionally the client.

...

SSL protocols help to provide confidentiality and integrity checking for messages transmitted using an SslStream. An SSL connection, such as that provided by SslStream, should be used when communicating sensitive information between a client and a server. Using an SslStream helps to prevent anyone from reading and tampering with information while it is in transit on the network

more details and examples here: SslStream Class

serge_gubenko
Thanks :) I'll take a look closely in a bit. But real quick, SSL can be used with UDP? (Sorry, never of heard of ssl/udp combos :o)
Zack
hmm.. I'm also not sure regarding UDP :) as SSL should be using public keys encryption to exchange a shared secret key which is used for rest if the conversation. I guess the solution here (once again that's just an idea, not sure if it gonna work :) could be establishing a TCP connection for the key exchange, and then use a key cipher to encrypt individual UDP packets.
serge_gubenko