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))
Esempio n. 2
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
Esempio n. 3
0
 def start_subsystem(self, name, transport, channel):
     Logger.debug(
         8,
         f'NETCONFsubsys: start_subsystem name={name} transport={transport} channel={channel}'
     )
     self.sock = channel
     Logger.debug(9,
                  'Started NETCONF server on channel {!r}'.format(channel))
     try:
         self.handle_session()
     except Exception as e:
         Logger.error(f'NETCONFsubsys: callback exception {e}')
         ##raise
     Logger.debug(8,
                  'Stopped NETCONF server on channel {!r}'.format(channel))
  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