Exemplo n.º 1
0
 def handle_session(self):
   Logger.debug(7, 'Session loop running')
   self.incoming_message('<?xml version="1.0" encoding="UTF-8"?><hello xmlns="parrot"/>')
   while True:
     try:
       Logger.debug(5,'NETCONF server ready, waiting for next message')
       msg = self.read_msg()
     except EOFError:
       Logger.debug(5,'EOF -- end of session')
       return
     except Exception as e:
       verdict = self.handle_read_exception(e)
       if verdict == "kill-session":
         return
       if verdict == "kill-server":
         Logger.info('Server terminating')
         sys.exit(1)
       # Else keep going
     try:
       if("" == msg):
         Logger.debug(5,'EOF ++ end of session')
         return
       if self.incoming_message(msg) == True:
         return
     except Exception as e:
       Logger.error('Exception in server processing: ' + str(e))
Exemplo n.º 2
0
    def run(self, host, port, parrot_file):
        Logger.info(f"Parroting {parrot_file}")
        try:
            parrot_path = pathlib.Path(parrot_file)
            env = Environment(loader=FileSystemLoader([parrot_path.parent],
                                                      followlinks=True),
                              autoescape=select_autoescape(['xml']))

            self.server.set_template(env.get_template(str(parrot_path.name)))
            self.server.set_host_port(host, port)
            self.server.serve()
        except Exception as e:
            traceback.print_exc()
            Logger.fatal(f"Top level exception: {str(e)}")
Exemplo n.º 3
0
    def build(self):
        if self.target_filename.exists():
            source_stat = self.source_filename.stat()
            target_stat = self.target_filename.stat()
            if source_stat.st_mtime <= target_stat.st_mtime:
                Logger.info(
                    f"Parrot Builder, {self.target_filename} up to date")
                return str(self.target_filename)

        with open(self.source_filename, "r") as source_file:
            with open(self.target_filename, "w") as target_file:
                self._make_messages(source_file)
                self._emit_messages(target_file)
        return str(self.target_filename)
Exemplo n.º 4
0
  def process_instructions(self, reply_msg):
    def split_processing_instructions(reply_msg):
      instructions = []
      pi_start_marker = '<?parrot '
      pi_end_marker = '?>'
      while True:
        pi_start = reply_msg.find(pi_start_marker)
        if pi_start < 0:
          break
        pi_end = reply_msg[pi_start:].find(pi_end_marker)
        if pi_end < 0:
          return ('bad-processing-instruction', reply_msg[pi_start:pi_start+20])
        pi = reply_msg[pi_start+len(pi_start_marker):pi_end]
        if pi_start:
          instructions += [('send', reply_msg[:pi_start])]
        reply_msg = reply_msg[pi_end+len(pi_end_marker):]
        cmd = pi.split(" ")[0]
        data = pi[len(cmd)+1:]
        instructions += [(cmd, data)]
      if reply_msg:
        instructions += [('send', reply_msg)]
      if not instructions:
        instructions = [('empty-response', None)]
      return instructions

    instructions = split_processing_instructions(reply_msg)
    end_session = False
    for (cmd, data) in instructions:
      if cmd == "send":
        Logger.debug(6, f'Sending {len(data)} bytes', payload=data)
        self.send_message(data)
      elif cmd == "ignore":
        Logger.debug(5, f'Not sending any response')
      elif cmd == "netconf11":
        Logger.debug(5, f'Switching to NETCONF 1.1')
        self.choose_netconf_ver([11])
      elif cmd == "netconf10":
        Logger.debug(5, f'Switching to NETCONF 1.0')
        self.choose_netconf_ver([10])
      elif cmd == "empty-response":
        Logger.warning(f'Template did not provide any response. Ending the session.')
        end_session = True
      elif cmd == "end-session":
        Logger.info(f'Ending session')
        end_session = True
      else:
        Logger.error(f'Unknown processing instruction "{cmd}" in template. Ending the session.')
        end_session = True
    return end_session
Exemplo n.º 5
0
 def send_msg(self, msg, netconf_ver=0):
   chunk_size = 10000
   if netconf_ver == 0:
     netconf_ver = self.netconf_ver
   msg_len = len(msg)
   while msg != "":
     chunk = msg[:chunk_size].encode('utf-8')
     chunk_len = len(chunk)
     if netconf_ver == 11:
       header = f"\n#{chunk_len}\n".encode('utf-8')
       Logger.debug(10, f'Sending NC11 header', payload=header)
       self.channel.send(header)
     Logger.debug(9, f'Sending {chunk_len} bytes chunk', payload=chunk)
     self.channel.send(chunk)
     msg = msg[chunk_size:]
   if netconf_ver == 11:
     Logger.debug(10, f'Sending NC11 delimiter', payload=self.delimiter11)
     self.channel.send(self.delimiter11)
   if netconf_ver == 10:
     Logger.debug(10, f'Sending NC10 delimiter', payload=self.delimiter10b)
     self.channel.send(self.delimiter10b)
   Logger.info(f"Sent {msg_len} bytes in NC{netconf_ver} message", payload=msg)
Exemplo n.º 6
0
  def handle_connection(self, host_key):
    try:
      DoGSSAPIKeyExchange = False
      t = Transport(self.sock, gss_kex=DoGSSAPIKeyExchange)
      t.set_subsystem_handler('netconf', self.subsys)
      t.set_gss_host(socket.getfqdn(""))
      try:
        t.load_server_moduli()
      except:
        Logger.warning('Failed to load moduli -- gex will be unsupported.')
      t.add_server_key(host_key)
      server = Server()
      t.start_server(server=server)

      # wait for auth
      self.channel = t.accept(20)
      if self.channel is None:
        Logger.error('No SSH channel')
        return

      Logger.info('Waiting for message')
      server.event.wait(10)
      Logger.info('Closing')
      ##self.channel.close()
      Logger.info('Client connection closed')
    except ConnectionResetError as e:
      Logger.debug(5,'Connection reset by peer')
    except SSHException:
      Logger.error('SSH negotiation failed, client connection dropped')
    except Exception as e:
      Logger.error('Caught exception: ' + str(e.__class__) + ': ' + str(e))
      traceback.print_exc()
      try:
        t.close()
      except:
        pass
Exemplo n.º 7
0
  def listen(self):
    NETCONF_Server.set_instance(self)
    try:
      sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
      sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
      #sock.bind(('', self.port))
      sock.bind((self.host, self.port))
    except Exception as e:
      Logger.fatal('Bind failed: ' + str(e))

    try:
      sock.listen(100)
    except Exception as e:
      Logger.fatal('Listen failed: ' + str(e))
    Logger.info(f'Listening for connections on port {self.port}...')

    host_key = None
    try:
      host_key = RSAKey(filename=self.host_key_filename)
    except:
      pass
    if not host_key:
      Logger.info(f'Generating new host key')
      host_key = RSAKey.generate(2048)
      if self.host_key_filename:
        host_key.write_private_key_file(self.host_key_filename, password=None)
        Logger.info(f"Wrote host key to file, '{self.host_key_filename}'")

    while True:
      try:
        Logger.info(f'Waiting for client to connect')
        client, addr = sock.accept()
      except Exception as e:
        Logger.fatal('Accept failed: ' + str(e))
      self.sock = client
      (ip, port) = addr
      Logger.info(f'Client {ip}:{port} connected')
      self.handle_connection(host_key)
      Logger.info(f'Client {ip}:{port} disconnected')