# Copyright 2015 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Utility library to add SSL support to the RPC server."""

import logging
import ssl
import subprocess
import tempfile

from legion.lib import common_lib
from legion.lib.rpc import jsonrpclib
from legion.lib.rpc import SimpleJSONRPCServer


class Error(Exception):
  pass


def CreateKeyFile():
  """Creates an SSL keyfile and returns the path."""
  keyfile = tempfile.mkstemp()[1]
  cmd = [
    'openssl',
    'genrsa',
    '-out', keyfile,
    '2048'
    ]
  _RunCommand(cmd)
  return keyfile


def CreateCsrFile(keyfile):
  """Creates an SSL CSR file and returns the path."""
  csrfile = tempfile.mkstemp()[1]
  cmd = [
      'openssl',
      'req',
      '-new',
      '-key', keyfile,
      '-out', csrfile,
      '-subj', '/C=NA/ST=NA/L=NA/O=Chromium/OU=Test/CN=chromium.org'
      ]
  _RunCommand(cmd)
  return csrfile


def CreateCrtFile(keyfile, csrfile):
  """Creates an SSL CRT file and returns the path."""
  crtfile = tempfile.mkstemp()[1]
  cmd = [
      'openssl',
      'x509',
      '-req',
      '-days', '1',
      '-in', csrfile,
      '-signkey', keyfile,
      '-out', crtfile
      ]
  _RunCommand(cmd)
  return crtfile


def CreatePemFile():
  """Creates an SSL PEM file and returns the path."""
  keyfile = CreateKeyFile()
  csrfile = CreateCsrFile(keyfile)
  crtfile = CreateCrtFile(keyfile, csrfile)
  pemfile = tempfile.mkstemp()[1]
  with open(keyfile) as k:
    with open(crtfile) as c:
      with open(pemfile, 'wb') as p:
        p.write('%s\n%s' % (k.read(), c.read()))
  return pemfile


def _RunCommand(cmd):
  try:
    p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  except OSError as e:
    raise Error('Failed to run %s: %s' % (' '.join(cmd), e))
  out, err = p.communicate()
  if p.returncode != 0:
    raise Error(err)
  return out


class SslRpcServer(SimpleJSONRPCServer.SimpleJSONRPCServer):
  """Class to add SSL support to the RPC server."""

  def __init__(self, *args, **kwargs):
    SimpleJSONRPCServer.SimpleJSONRPCServer.__init__(self, *args, **kwargs)
    self.socket = ssl.wrap_socket(self.socket, certfile=CreatePemFile(),
                                  server_side=True)

  @staticmethod
  def Connect(server, port=common_lib.SERVER_PORT):
    """Creates and returns a connection to an SSL RPC server."""
    addr = 'https://%s:%d' % (server, port)
    logging.debug('Connecting to RPC server at %s', addr)
    return jsonrpclib.ServerProxy(addr, allow_none=True)
