text: # -*- coding: utf-8 -*-
  """
  openssl s_client command module.
  """
  
  import re
  
  from moler.cmd.unix.genericunix import GenericUnixCommand
  from moler.exceptions import ParsingDone
  
  __author__ = 'Marcin Szlapa'
  __copyright__ = 'Copyright (C) 2020, Nokia'
  __email__ = 'marcin.szlapa@nokia.com'
  
  
  class OpensslSClient(GenericUnixCommand):
      """openssl command s_client"""
  
      def __init__(self, connection, options, prompt=None, newline_chars=None, runner=None):
          """
          s_client command.
  
          :param connection: moler connection to device, terminal when command is executed.
          :param options: parameters with which the command will be executed
          :param prompt: expected prompt sending by device after command execution
          :param newline_chars: Characters to split lines
          :param runner: Runner to run command
          """
          super(OpensslSClient, self).__init__(connection, prompt=prompt, newline_chars=newline_chars, runner=runner)
          self.options = options
          self.current_ret = dict()
  
      def build_command_string(self):
          """
          Build command string from parameters passed to object.
  
          :return: String representation of command to send over connection to device.
          """
          cmd = "openssl s_client"
          cmd = "{} {}".format(cmd, self.options)
          return cmd
  
      def on_new_line(self, line, is_full_line):
          """
          Parse command output.
  
          :param line: Line to process, can be only part of line. New line chars are removed from line.
          :param is_full_line: True if line had new line chars, False otherwise
          :return: None
          """
          if is_full_line:
              try:
                  self._parse_issuer(line)
                  self._parse_properties(line)
              except ParsingDone:
                  pass
          return super(OpensslSClient, self).on_new_line(line, is_full_line)
  
      #     Protocol  : TLSv1.1
      _re_properties = re.compile(r"^\s+(?P<KEY>.+)(?<!\s)\s*:\s*(?P<VALUE>.+)?(?<!\s)\s*$")
  
      def _parse_properties(self, line):
          if self._regex_helper.search_compiled(OpensslSClient._re_properties, line):
              self.current_ret[self._regex_helper.group('KEY')] = self._regex_helper.group('VALUE')
              raise ParsingDone
  
      # issuer=XX = abc, XX = net, XY = Root
      _re_issuer = re.compile(r"^issuer=(?P<ISSUER>.*)")
  
      def _parse_issuer(self, line):
          if self._regex_helper.search_compiled(OpensslSClient._re_issuer, line):
              self.current_ret["issuer"] = self._regex_helper.group('ISSUER')
              raise ParsingDone
  
  
  COMMAND_OUTPUT = """openssl s_client -tls1_1 -connect 10.10.10.10:443
  CONNECTED(00000003)
  write:errno=0
  ---
  no peer certificate available
  ---
  No client certificate CA names sent
  ---
  SSL handshake has read 0 bytes and written 10 bytes
  Verification: OK
  ---
  issuer=XX = abc, XX = net, XY = Root
  ---
  New, (NONE), Cipher is (NONE)
  Secure Renegotiation IS NOT supported
  Compression: NONE
  Expansion: NONE
  No ALPN negotiated
  SSL-Session:
      Protocol  : TLSv1.1
      Cipher    : 0000
      Session-ID:
      Session-ID-ctx:
      Master-Key:
      PSK identity: None
      PSK identity hint: None
      SRP username: None
      Start Time: 1623194332
      Timeout   : 7200 (sec)
      Verify return code: 0 (ok)
      Extended master secret: no
  ---
  user@host:~$"""
  
  COMMAND_KWARGS = {
      "options": "s_client -tls1_1 -connect 10.10.10.10:443",
  }
  
  COMMAND_RESULT = {
      "issuer": "XX = abc, XX = net, XY = Root",
      "Protocol": "TLSv1.1",
      "Cipher": "0000",
      "Session-ID": None,
      "Session-ID-ctx": None,
      "Master-Key": None,
      "PSK identity": "None",
      "PSK identity hint": "None",
      "SRP username": "None",
      "Start Time": "1623194332",
      "Timeout": "7200 (sec)",
      "Verify return code": "0 (ok)",
      "Extended master secret": "no",
  }
  