def main():
    #  TODO build true seed daemon for release
    while True:

        try:
            # verify openvas is configured
            openvas_user = session.query(OpenvasAdmin).first()

        except OperationalError as e:  # if it's not working
            print("\nIt appears that something went wrong, did you setup the database.yml correctly?")
            print("\n%s" % e)
            quit()

        if openvas_user is None:
            # TODO figure out how to bypass needing root for this function `setup_openvas()`
            setup_openvas()  # configured it
            openvas_user = session.query(OpenvasAdmin).first()

        # make sure service accounts are created in OpenVAS
        smb_users = session.query(SmbUser).all()
        linux_users = session.query(LinuxUser).all()

        for smb_u in smb_users:
            if smb_u.openvas_lsc_id is None:
                smb_passwd = decrypt_string(
                    str.encode(smb_u.encrypted_password), str.encode(smb_u.encrypted_password_salt)
                ).decode("utf-8")

                create_lsc_credential_response_smb = create_lsc_credential(
                    smb_u.description, smb_u.username, smb_passwd, openvas_user.username, openvas_user.password
                )
                if create_lsc_credential_response_smb != create_lsc_credential_error:
                    session.query(SmbUser).update({SmbUser.openvas_lsc_id: create_lsc_credential_response_smb})
                    session.commit()
                else:
                    print("User exists already")
                    lsc_smb_list = get_lsc_crdentials(openvas_user.username, openvas_user.password)
                    for lsc_smb in lsc_smb_list:
                        if smb_u.description in lsc_smb:
                            print("lsc id is %s" % lsc_smb[1])

        for linux_u in linux_users:
            if linux_u.openvas_lsc_id is None:
                linux_passwd = decrypt_string(
                    str.encode(linux_u.encrypted_password), str.encode(linux_u.encrypted_password_salt)
                ).decode("utf-8")

                create_lsc_credential_response_linux = create_lsc_credential(
                    linux_u.description, linux_u.username, linux_passwd, openvas_user.username, openvas_user.password
                )
                if create_lsc_credential_response_linux != create_lsc_credential_error:
                    session.query(LinuxUser).update({LinuxUser.openvas_lsc_id: create_lsc_credential_response_linux})
                    session.commit()
                else:
                    print("User exists already")
                    lsc_linux_list = get_lsc_crdentials(openvas_user.username, openvas_user.password)
                    for lsc_linux in lsc_linux_list:
                        if linux_u.description in lsc_linux:
                            print("lsc id is %s" % lsc_linux[1])

        # TODO check if we are using the core router for targets

        # if so get targets
        try:

            # get info from core, save in /tmp/perception/
            get_network_info(
                tmp_dir,  # ssh to Cisco IOS core switch
                ios_show_hosts_file,
                ios_show_local_conn_file,
                ios_show_cdp_detail_file,
                ios_show_fqdn_file,
            )

            # parse the local hosts file from /tmp/perception
            local_hosts(ios_show_hosts_file)  # this function also removes stale hosts from inventory

            # parse the local connections file from /tmp/perception
            local_connections(ios_show_local_conn_file)

            # parse the ios fqdn file from /tmp/perception
            ios_fqdn = ios_fqdn_detail(ios_show_fqdn_file)

            # parse the cdp detail file from /tmp/perception
            cdp_neighbors_detail(ios_show_cdp_detail_file, ios_fqdn)

            try:
                rmtree(tmp_dir)
            except FileNotFoundError as e:
                print(e)

        except ProgrammingError:
            print("database not ready")

        print("sleeping")
        sleep(300)
def get_network_info(tmp_dir,
                     show_hosts_file,
                     show_local_conn_file,
                     show_cdp_detail_file,
                     ios_show_fqdn_file):

  # get core router user service account info
  core_router = session.query(CoreRouter).first()
  if core_router:

    ip_addr = core_router.ip_addr

    username = core_router.linux_users.username

    password = decrypt_string(str.encode(core_router.linux_users.encrypted_password),
                              str.encode(core_router.linux_users.encrypted_password_salt))

    enable_password = decrypt_string(str.encode(core_router.linux_users.encrypted_enable_password),
                                     str.encode(core_router.linux_users.encrypted_enable_password_salt))

    try:
      mkdir(tmp_dir)
    except FileExistsError:
      """moving on.."""

    ssh_child1 = cisco_enable_mode(username,
                                   ip_addr,
                                   password.decode("utf-8"),
                                   enable_password.decode("utf-8"))

    ssh_child2 = cisco_enable_mode(username,
                                   ip_addr,
                                   password.decode("utf-8"),
                                   enable_password.decode("utf-8"))

    ssh_child3 = cisco_enable_mode(username,
                                   ip_addr,
                                   password.decode("utf-8"),
                                   enable_password.decode("utf-8"))

    ssh_child4 = cisco_enable_mode(username,
                                   ip_addr,
                                   password.decode("utf-8"),
                                   enable_password.decode("utf-8"))

    if ssh_child1:
      sys.stdout = open(show_hosts_file, 'w+')
      send_command(ssh_child1, IOSTERMLEN0)
      send_command(ssh_child1, IOS_SHOWARP)
      ssh_child1.logfile_read = sys.stdout
      ssh_child1.close()
      sys.stdout = sys.__stdout__

    if ssh_child2:
      sys.stdout = open(show_local_conn_file, 'w+')
      send_command(ssh_child2, IOSTERMLEN0)
      send_command(ssh_child2, SHOW_LOCAL_CONNECTIONS)
      ssh_child2.logfile_read = sys.stdout
      ssh_child2.close()
      sys.stdout = sys.__stdout__

    if ssh_child3:
      sys.stdout = open(show_cdp_detail_file, 'w+')
      send_command(ssh_child3, IOSTERMLEN0)
      send_command(ssh_child3, SHOW_CDP_DETAIL)
      ssh_child3.logfile_read = sys.stdout
      ssh_child3.close()
      sys.stdout = sys.__stdout__

    if ssh_child4:
      sys.stdout = open(ios_show_fqdn_file, 'w+')
      send_command(ssh_child4, IOSTERMLEN0)
      send_command(ssh_child4, IOS_SHOWHOSTNAME)
      send_command(ssh_child4, IOS_SHOWIPDOMAIN)
      ssh_child4.logfile_read = sys.stdout
      ssh_child4.close()
      sys.stdout = sys.__stdout__

    else:
      print('can\'t get child')
      exit()
def match_creds_to_hosts(host_list):

  # build vars
  smb_hosts = list()
  ssh_hosts = list()

  # auth ports
  smb_port = 135
  ssh_port = 22

  # validate ports are open and add hosts to proper list
  for host in host_list:

    smb_check = tcp_scan(host, smb_port)
    ssh_check = tcp_scan(host, ssh_port)

    if smb_check:
      smb_hosts.append(host)

    if ssh_check:
      ssh_hosts.append(host)

  # validate smb login credentials
  if smb_hosts:

    # query database for smb credentials
    smb_svc_accounts = session.query(SmbUser).all()
    smb_accounts = list()

    if smb_svc_accounts:

      # build a dictionary of smb accounts
      for u in smb_svc_accounts:

        smb_dict = {'id': u.id,
                    'username': u.username,
                    'password': decrypt_string(str.encode(u.encrypted_password),
                                               str.encode(u.encrypted_password_salt)),
                    'domain_name': u.domain_name}

        smb_accounts.append(smb_dict)

      # validate credentials using WMI
      for h in smb_hosts:

        for u in smb_accounts:
              cs_query = wmic_query(u['domain_name'], u['username'], u['password'], h, win32_computersystem)

              failed_login = {'[librpc/rpc/dcerpc_connect.c:828:dcerpc_pipe_connect_b_recv()]'
                              ' failed NT status (c0000022) in dcerpc_pipe_connect_b_recv':
                              '[wmi/wmic.c:196:main()] ERROR: Loin to remote object.'}

              error_login = {'[librpc/rpc/dcerpc_connect.c:828:dcerpc_pipe_connect_b_recv()] '
                             'failed NT status (c0000017) in dcerpc_pipe_connect_b_recv':
                             '[wmi/wmic.c:196:main()] ERROR: Login to remote object.'}

              connection_refused = {'[librpc/rpc/dcerpc_connect.c:828:dcerpc_pipe_connect_b_recv()]'
                                    ' failed NT status (c0000236) in dcerpc_pipe_connect_b_recv':
                                    '[wmi/wmic.c:196:main()] ERROR: Login to remote object.'}

              if cs_query[0] == connection_refused:
                print('connection refused from %s' % h)

              if cs_query[0] == error_login:
                print('error logging into %s' % h)

              if cs_query[0] == failed_login:
                print('failed login for %s' % h)

              elif cs_query[0] != connection_refused and cs_query[0] != error_login and cs_query[0] != failed_login:
                add_inventory_host = InventoryHost(ipv4_addr=h,
                                                   smb_user_id=u['id'])
                session.add(add_inventory_host)
                session.commit()

  # validate ssh login credentials
  if ssh_hosts:

    # query database for ssh credentials
    linux_svc_accounts = session.query(LinuxUser).all()
    linux_accounts = list()

    if linux_svc_accounts:

      # build a dictionary of ssh accounts
      for u in linux_svc_accounts:

        linux_dict = {'id': u.id,
                      'username': u.username,
                      'password': decrypt_string(str.encode(u.encrypted_password),
                                                 str.encode(u.encrypted_password_salt)),
                      'enable_password': decrypt_string(str.encode(u.encrypted_enable_password),
                                                        str.encode(u.encrypted_enable_password_salt))}
        linux_accounts.append(linux_dict)

      for h in ssh_hosts:

        # validate credentials using ssh
        for u in linux_accounts:

          ssh_to_host = check_creds(h, u['username'], u['password'].decode("utf-8"))

          if ssh_to_host == 1:

            add_inventory_host = InventoryHost(ipv4_addr=h,
                                               linux_user_id=u['id'])
            session.add(add_inventory_host)
            session.commit()

          if ssh_to_host == 99:
            print('linux user not added to %s, bad ssh key' % h)
            add_inventory_host = InventoryHost(ipv4_addr=h,
                                               bad_ssh_key=True)
            session.add(add_inventory_host)
            session.commit()