Package authorization_server

Source Code of authorization_server.AuthorizationServer

package authorization_server;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStreamWriter;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.Date;
import java.util.Hashtable;
import java.util.StringTokenizer;
import java.util.Timer;
import java.util.logging.Logger;

import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.TrustManagerFactory;

import common.DESEncrypter;
import common.DepartmentPriorities;
import common.FileTransport;

/**
* The Authorization Server
* Accepts connections from the server
* Bans, reject / allow downloads
*
* @author Claudiu Ghioc claudiu.ghioc@gmail.com
*
*/
public class AuthorizationServer implements Runnable {
  public static final int SERVER_PORT          = 7778;
  private static final int BAN_TIME          = 30000; // mili seconds
  private static final String SECRET_KEY        = "config/auth/AuthSecretKey.ser";
  static final String BANNED_ENCRYPTED        = "config/auth/banned";
  static final String BANNED_DECRYPTED        = "config/auth/banned.tmp";

  static Logger logger = Logger.getLogger(AuthorizationServer.class.getName());

  private Hashtable<String, Integer> priorities;
  private KeyStore serverKeyStore = null;
  private KeyManagerFactory keyManagerFactory = null;
  private TrustManagerFactory trustManagerFactory = null;
  private SSLContext sslContext = null;
  private SSLServerSocket serverSocket = null;
  private Certificate CACertificate = null;
  private String authKeystore;
  private String authKeystorePass;
  // key used for encrypting / decrypting the file containing information about the banned clients
  DESEncrypter crypt = null;


  public AuthorizationServer () {
    this.authKeystore     = System.getProperty("KeyStore");
    this.authKeystorePass = System.getProperty("KeyStorePass");
   
    // Load the departments' priorities
    this.priorities = DepartmentPriorities.initPriorities();
  }

  /**
   * Initializes the Authorization Server, opens SSL socket, creates decrypter
   * @return
   */
  private int initialize () {
    try {
      // get a reference to the authorization server's keystore
      this.serverKeyStore = KeyStore.getInstance("JKS");
      this.serverKeyStore.load(new FileInputStream(authKeystore), authKeystorePass.toCharArray());
    } catch (Exception e) {
      logger.severe("Failed to get a reference to the authorization server's keystore: keyStoreName = "
          + authKeystore + ", password = " + authKeystorePass);
      e.printStackTrace();
      return 1;
    }
    logger.info("Successfully obtained a reference to the authorization server's keystore");

    try {
      // get a key manager factory
      this.keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
    } catch (Exception e) {
      logger.severe("Failed to obtain a key manager factory");
      e.printStackTrace();
      return 1;
    }
    logger.info("Successfully obtained a key manager factory");

    try {
      // initialize the key manager factory with a source of key material
      this.keyManagerFactory.init(this.serverKeyStore, authKeystorePass.toCharArray());
    } catch (Exception e) {
      logger.severe("Failed to initialize the key manager factory with the key material coming from the server's keystore");
      e.printStackTrace();
      return 1;
    }
    logger.info("Successfully initialized the key manager factory");

    try {
      // get a trust manager factory
      this.trustManagerFactory = TrustManagerFactory.getInstance("SunX509");
    } catch (Exception e) {
      logger.severe("Failed to obtain a trust manager factory");
      e.printStackTrace();
      return 1;
    }
    logger.info("Successfully obtained a trust manager factory");

    try {
      // initialize the trust manager factory with a source of key material
      this.trustManagerFactory.init(this.serverKeyStore);
    } catch (Exception e) {
      logger.severe("Failed to initialize the trust manager factory with the key material coming from the server's keystore");
      e.printStackTrace();
      return 1;
    }
    logger.info("Successfully initialized the trust manager factory");

    try {
      // set the SSL context
      this.sslContext = SSLContext.getInstance("TLS");
      this.sslContext.init(this.keyManagerFactory.getKeyManagers(), this.trustManagerFactory.getTrustManagers(), null);
    } catch (Exception e) {
      logger.severe("Failed to initialize the SSl context");
      e.printStackTrace();
      return 1;
    }
    logger.info("Successfully initialized a SSL context");

    try {
      // get the certificate of this server's certification authority
      this.CACertificate = this.serverKeyStore.getCertificate("certification_authority");
    } catch (Exception e) {
      logger.severe("Failed to retrive the certificate of this server's certificate authority");
      e.printStackTrace();
      return 1;
    }

    // Try to open the Authorization server's secret key
    SecretKey key = null;
    try {
      ObjectInputStream in = new ObjectInputStream(new FileInputStream(AuthorizationServer.SECRET_KEY));
      key = (SecretKey)in.readObject();
      in.close();
    } catch (FileNotFoundException fnfe) {
      // generate a cryptographic key
      try {
        key = KeyGenerator.getInstance("DES").generateKey();
        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(AuthorizationServer.SECRET_KEY));
        out.writeObject(key);
        out.close();
      } catch (Exception e) {
        e.printStackTrace();
        return 1;
      }
    } catch (Exception e) {
      e.printStackTrace();
      return 1;
    }
    crypt = new DESEncrypter(key);
    return 0;
  }

  public void run () {
    if (initialize() != 0) {
      return;
    }
    try {
      this.serverSocket = (SSLServerSocket) sslContext.getServerSocketFactory().createServerSocket(AuthorizationServer.SERVER_PORT);
    } catch (Exception e) {
      logger.severe("Failed to create a SSL server socket");
      e.printStackTrace();
      return;
    }
    logger.info("Successfully created a SSL server socket");

    serverSocket.setNeedClientAuth(true);
    logger.info("Listening for incoming connections... ");

    while (true) {
      SSLSocket socket = null;
      try {
        socket = (SSLSocket) this.serverSocket.accept();
      } catch (Exception e) {
        logger.severe("Failed to accept an incoming connection");
        e.printStackTrace();
        return
      }
      logger.info("Just accepted a connection");
      try {
        socket.startHandshake();
      } catch (IOException e) {
        logger.severe("Failed to complete a handshake");
        e.printStackTrace();
        continue
      }
      logger.info("Successful handshake");
      X509Certificate[] peerCertificates = null;
      try {
        peerCertificates = (X509Certificate[])(socket.getSession()).getPeerCertificates();
        if (peerCertificates.length < 2) {
          logger.severe("'peerCertificates' should contain at least two certificates");
          continue;
        }
      } catch (Exception e) {
        logger.severe("Failed to get peer certificates");
        e.printStackTrace();
        continue;
      }

      if (CACertificate.equals(peerCertificates[1])) {
        logger.info("The peer's CA certificate matches the authorization server's CA certificate");
      }
      else {
        logger.severe("The peer's CA certificate doesn't match the authorization server's CA certificate");
        continue;
      }
      BufferedReader reader = null;
      BufferedWriter writer = null;
      try {
        reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()))
      } catch (Exception e) {
        logger.severe("Failed to properly handle the communication with a peer");
        e.printStackTrace();
        continue;
      }
      String request = null;
      try {
        request = reader.readLine()
      } catch (IOException e) {
        logger.severe("Failed to read a message from the socket");
        e.printStackTrace();
        try {
          socket.close();
        } catch (IOException ioe) {
          logger.severe("Failed to close the socket");
          ioe.printStackTrace()
        }
        continue;
      }
      if (request == null) {
        logger.severe("The end of the input stream has been reached");
        try {
          socket.close();
        } catch (IOException ioe) {
          logger.severe("Failed to close the socket");
          ioe.printStackTrace()
        }
        continue;
      }
      System.out.println("Received request: <" + request + ">");
      String response = processRequest(request);
      try {
        writer.write(response);
        writer.newLine();
        writer.flush()
      } catch (IOException e) {
        logger.severe("Failed to write a message to the socket");
        e.printStackTrace();
        try {
          socket.close();
        } catch (IOException ioe) {
          logger.severe("Failed to close the socket");
          ioe.printStackTrace()
        }
        continue;
      }
    }
  }

  /**
   * Processes a request from the server
   * @param request
   * @return
   */
  public String processRequest(String request) {
    StringTokenizer st = new StringTokenizer(request, " ");
   
    // Add a client to the banned list
    if (request.startsWith("BAN")) {
      st.nextToken();
      ban(st.nextToken());
      return FileTransport.OK;
    }

    // Check if a client is banned
    if (request.startsWith("REQ_BAN")) {
      st.nextToken();
      return isBanned(st.nextToken());
    }

    // Check if a client has the right to download a file from the server
    st.nextToken();
    String newDept = st.nextToken();
    String oldDept = st.nextToken();
    System.out.println("Comparing " + newDept + " with " + oldDept);
    int newPriority = this.priorities.get(newDept);
    int oldPriority = this.priorities.get(oldDept);
    if (newPriority <= oldPriority)
      return FileTransport.OK;
    return FileTransport.DENIED;
  }

  /**
   * Adds a client to the banned list
   * @param clientName
   */
  private void ban(String clientName) {
    System.out.println("Banning " + clientName);
    try {
      if (!crypt.decrypt(new FileInputStream(BANNED_ENCRYPTED), new FileOutputStream(BANNED_DECRYPTED))) {
        return
      }
      // add this client to the list of those banned
      FileOutputStream out = new FileOutputStream(BANNED_DECRYPTED, true);
      String line = clientName + " " + System.currentTimeMillis() + "\n";
      out.write(line.getBytes());
      out.close();
     
      // delete the old encryption
      File file = new File(BANNED_ENCRYPTED);
      file.delete();
     
      // encrypt the new information
      File newEncryption = new File(BANNED_ENCRYPTED);
      if (newEncryption.createNewFile() == false) {
        logger.severe("Failed to re-create the 'banned_encrypted' file when banning the client '" + clientName + "'");
        return
      }
      if (!crypt.encrypt(new FileInputStream(BANNED_DECRYPTED), new FileOutputStream(BANNED_ENCRYPTED))) {
        logger.severe("Failed to ban the client '" + clientName + "'");
        return;
      }
     
      // set the timer so that the client is allowed back after the timeout
      Date timeToRun = new Date(System.currentTimeMillis() + BAN_TIME);
      Timer timer = new Timer();
      timer.schedule(new BannedTimerTask(this, clientName), timeToRun);

    } catch (Exception e) {
      logger.severe("Failed to ban the client '" + clientName + "'");
      e.printStackTrace();
      return;
    }
   
    // delete the decryption
    File temp = new File(BANNED_DECRYPTED);
    temp.delete();
    return;
  }
 
  /**
   * Check if a client is on the banned list
   * @param clientName
   * @return
   */
  public String isBanned(String clientName) {
    System.out.println("Checking ban state for " + clientName);
    String response = FileTransport.OK;
    byte[] buffer = new byte[1024];
    try {
      if (!crypt.decrypt(new FileInputStream(AuthorizationServer.BANNED_ENCRYPTED), new FileOutputStream(AuthorizationServer.BANNED_DECRYPTED))) {
        return FileTransport.OK; 
      }
      FileInputStream in = new FileInputStream(AuthorizationServer.BANNED_DECRYPTED);
      in.read(buffer);
      in.close();
      String info = new String(buffer);
      if (info.indexOf(clientName) == -1)
        response = FileTransport.NO;
      else
        response = FileTransport.OK; 
    } catch (Exception e) {
      logger.severe("Failed to find out if client '" + clientName + "' is banned or not");
      e.printStackTrace();
      return FileTransport.OK; 
    }
    // delete the decryption
    File temp = new File(AuthorizationServer.BANNED_DECRYPTED);
    temp.delete();
    return response;
  }

  public static void main (String args[]) {
    (new Thread(new AuthorizationServer())).start();
  }
}
TOP

Related Classes of authorization_server.AuthorizationServer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.