Esempio n. 1
0
        /// <summary>
        /// Authenticates a socket before accepting into
        /// a permanent connection (it's connection attempt
        /// may yet be rejected.)
        /// </summary>
        /// <param name="socketObj">The object to cast into a socket to query.</param>
        public void Authenticate(Object socketObj)
        {
            Socket s = (Socket)socketObj;

            int rconConId = this.NextRconID; //Don't bother sending CreateRootUser this ID. The socket
            if ( rconConId == -1 ) return; //doesn't exist for long enough for us to care. But it's important that it's there.

            if ( rconUsers == null ) {
                CreateRootUser( s );
                return;
            }

            StringBuilder sb = new StringBuilder();
            sb.AppendFormat( "<{0}.{1}@{2}>",
                System.Diagnostics.Process.GetCurrentProcess().Id,
                DateTime.Now.ToString( "ddmmyyhhmmss" ),
                System.Environment.UserDomainName );

            string authmsg = "authenticate " + sb.ToString();
            int offset = 0;
            SocketError errorCode;
            do {
                try {
                    offset += s.Send( IRCProtocol.Ascii.GetBytes( authmsg ),
                        offset, authmsg.Length - offset, SocketFlags.None, out errorCode );
                }
                catch ( SocketException ) {
                    s.Close();
                    return; //Give up. They can reconnect.
                }
            } while ( offset < authmsg.Length );

            if ( errorCode != SocketError.Success ) { s.Close(); return; }

            //Get Auth response.
            byte[] recvBuf = new byte[rconfig.SocketBufferSize];
            offset = s.Receive( recvBuf, 0, rconfig.SocketBufferSize, SocketFlags.None, out errorCode );
            if ( offset == 0 || errorCode != SocketError.Success ) { s.Close(); return; }
            string authReply = IRCProtocol.Ascii.GetString( recvBuf, 0, offset );

            //Parse into name/hash and verify both for correctness.
            string[] unameAndHash = authReply.Split( ' ' );
            if ( unameAndHash.Length != 2 ) { s.Close(); return; }

            //Verify username.
            string username = unameAndHash[0];
            Nullable<RconUserFile.RconUser> rc = rconUsers.GetUser(username);
            if ( rc == null ) { s.Close(); return; }

            //Verify their hash.
            string theirHash = unameAndHash[1];
            string pass = rc.Value.Password;

            HMACMD5 hmac = new HMACMD5( IRCProtocol.Ascii.GetBytes( pass ) );
            hmac.Initialize();
            hmac.TransformFinalBlock( IRCProtocol.Ascii.GetBytes( sb.ToString() ), 0, theirHash.Length );
            string ourHash = RconUserFile.GetHashFromDigest( hmac.Hash );

            if ( !ourHash.Equals( theirHash ) ) { s.Close(); return; }

            authmsg = "success";
            offset = 0;
            do {
                try {
                    offset += s.Send( IRCProtocol.Ascii.GetBytes( authmsg ),
                        offset, authmsg.Length - offset, SocketFlags.None, out errorCode );
                }
                catch ( SocketException ) {
                    s.Close();
                    return; //Give up. They can reconnect.
                }
            } while ( offset < authmsg.Length );

            if ( errorCode != SocketError.Success ) { s.Close(); return; }

            //DO IT MAD AMOUNTS OF ARRAY LOOKUPS FOR NO REASON. L2TEMP VARIABLE PLZ
            rconConnections[rconConId] = new SocketPipe( s, rconConId, 30000, 5000, 0 );
            rconConnections[rconConId].OnReceive += new SocketPipe.ReceiveData( OnReceive );
            rconConnections[rconConId].OnDisconnect += new SocketPipe.NoParams( OnDisconnect );

            Thread t = new Thread( new ThreadStart( rconConnections[rconConId].ConstantPump ) );
            t.Start(); //Start sending anything we can :D
            rconConnections[rconConId].ConstantSiphon(); //Consume current thread generated by ConstantAccept.
        }
Esempio n. 2
0
        /// <summary>
        /// Creates a server from a ServerConfig with a parameter
        /// to provide an interface for logging.
        /// </summary>
        /// <param name="config">The configuration to build the Server from.</param>
        /// <param name="logFunction">The function to call to log text for the application.</param>
        public Server(Configuration.ServerConfig config, Project2QService.WriteLogFunction logFunction)
        {
            //Instantiate and load databases
            uc = new UserCollection();
            cc = new ChannelCollection();
            uc.LoadRegisteredUsers( "userdb\\" + config.Name + ".udb" );

            //Rip up this little guy to help us out :D
            currentHost = new IRCHost();
            currentIP = null;

            this.authmode = !File.Exists( "userdb\\" + config.Name + ".udb" );

            this.writeLogFunction = logFunction;

            //Assign a Server ID
            this.serverId = Server.NextServerId;
            if ( this.serverId == -1 ) throw new OverflowException( "Too many servers created." );
            servers[serverId] = this;

            //Save the configuration.
            this.config = config;

            //Tie default static handlers together for this instance of IRCEvents.
            irce = new IRCEvents();

            //Initialize the socket pipe before the modules. Modules are scary.
            state = State.Disconnected;

            socketPipe = new SocketPipe(
                this.serverId, config.RetryTimeout, config.OperationTimeout, config.SendInhibit, config.SocketBufferSize ); //Default values for now, get them from config later plz.
            socketPipe.OnDisconnect += new SocketPipe.NoParams( this.OnDisconnect );
            socketPipe.OnReceive += new SocketPipe.ReceiveData( this.OnReceive );
        }