Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Socket Authentication Server?

I am currently playing with java to create an authentication server for a desktop app and so far I have been able to make both the client and server communicate like a chat server/client for a start.

I do realise I only got a small portion of it working and there are many things to come and to learn but right now at this stage I am wondering how the authentication is done.

For example, this is the server code:

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class LoginServer
{
    public static void main(String[] args) throws Exception {
        int port = 7000;
        int id = 1;

        ServerSocket loginserver = null;
        try
        {
            loginserver = new ServerSocket(port);
            System.out.println("LoginServer started...");
        }
        catch (IOException e) {
            System.out.println("Could not listen on port: " + port);
            System.exit(-1);
        }

        while (true)
        {
            Socket clientSocket = loginserver.accept();
            ClientServiceThread cliThread = new ClientServiceThread(clientSocket, id++);
            cliThread.start();
        }
    }
}

class ClientServiceThread extends Thread
{
    Socket clientSocket;
    int clientID = -1;
    boolean running = true;

    ClientServiceThread(Socket s, int i)
    {
        clientSocket = s;
        clientID = i;
    }

    public void run()
    {
        System.out.println("Accepted Client : ID - " + clientID + " : Address - " + clientSocket.getInetAddress().getHostName());
        try
        {
            BufferedReader   in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
            PrintWriter   out = new PrintWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
            while (running)
            {
                String clientCommand = in.readLine();
                System.out.println("Client Says :" + clientCommand);
                if (clientCommand.equalsIgnoreCase("quit"))
                {
                    running = false;
                    System.out.print("Stopping client thread for client : " + clientID);
                }
                else
                {
                    out.println(clientCommand);
                    out.flush();
                }
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}

As you can see, I do read what the client sends and output it to the console as well as checking if the client has sent a quit or not command.

  • What I am wondering is how would I do so that the client can only connect to it if the user and password was sent ?

  • Or should I always receive the initial connection and from there receive the authentication information and if the client has not sent it in let's say 3 seconds disconnect them ?

  • What is the correct way of receiving the new connections and authenticate the users with it ?

like image 728
Guapo Avatar asked Mar 16 '11 04:03

Guapo


People also ask

What is the socket server?

Sockets are commonly used for client and server interaction. Typical system configuration places the server on one machine, with the clients on other machines. The clients connect to the server, exchange information, and then disconnect. A socket has a typical flow of events.

How do you authenticate a server?

In authentication, the user or computer has to prove its identity to the server or client. Usually, authentication by a server entails the use of a user name and password. Other ways to authenticate can be through cards, retina scans, voice recognition, and fingerprints.

How do servers authenticate clients?

The server authenticates the client by receiving the client's certificate during the SSL handshake and verifying the certificate is valid. Validation is done by the server the same way the client validates the server's certificate. The client sends a signed certificate to the server.


1 Answers

You've got the right idea, but you need to think of it more as a state machine.

A client connects, then it would need to go into the Login state, where you expect it to send authentication information. If incorrect or timeout, disconnect.

If correct, move on to the Command Processing state. If you receive a quit command, either move to a Cleanup state, or simply disconnect.

Here's a general outline:

String line;
while ((line = in.readLine()) != null) {
    switch (state) {
        case login:
            processLogin(line);
            break;
        case command:
            processCommand(line);
            break;
    }
}

Your processLogin function could look like this:

void processLogin(String line) {
    if (user == null) {
        user = line;
    }
    else if (password == null) {
        password = line;
    }
    else {
        if (validUser(user, password)) {
            state = command;
        }
        else {
            socket.close();
        }
    }
}

And your processCommand function:

void processCommand(String line) {
    if (line.equals(...)) {
        // Process each command like this
    }
    else if (line.equals("quit")) {
        socket.close();
    }
    else {
        System.err.println("Unrecognized command: " + line);
    }
}

The state instance variable would likely be an enum. You can see that using this model will give you some pretty simple extensibility. For example, a command could drop you into a different state to process specific sub-commands.

like image 111
Jonathan Avatar answered Oct 05 '22 10:10

Jonathan