# Copyright 2026 SigmaSRC, Inc. All Rights Reserved.

"""Gather ~user/.rhosts contents.

Table columns:

- localuser -- the local user where the .rhosts file is found
- host      -- the hostname column from the .rhosts file; includes + markup
- ipaddr    -- lookup of host (after stripping + or -); may be empty
- user      -- the username column from the .rhosts file; may be empty

Example:

Suppose ~guido/.rhosts contains the following:

    # never mind that this is insane :-)

    +
    + +
    foo
    +foo -bar         # this is a comment
    -foo

and assuming the IP address of host 'foo' is 1.2.3.4.  Then we
generate the following records:

    'guido', '+', '', ''
    'guido', '+', '', '+'
    'guido', 'foo', '1.2.3.4', ''
    'guido', '+foo', '1.2.3.4', '-bar'
    'guido', '-foo', '1.2.3.4', ''
"""

import os
import sys
import socket

if __name__ == "__main__":
    try:
        import sigma
    except ImportError:
        sys.path.append(os.path.join(os.pardir, os.pardir))

from sigma.runtime import rtlib

def Gather(collector):
    # The fourth column used to be "user", but that's an Oracle
    # reserved word, so now it's "remoteuser".
    # The server takes advantage of the fact that this table has the
    # same trust consequences as the table from gather_hosts_equiv, if
    # you ignore the "localuser" column.
    t = collector.table("rhosts",
                        ["localuser", "host", "ipaddr", "remoteuser"])
    h = rtlib.Host("localhost")
    for acct in h.list_local_accounts():
        rhosts = os.path.join(acct.home, ".rhosts")
        try:
            f = open(rhosts)
        except IOError:
            continue
        try:
            for line in f:
                words = line.split()
                if not words or words[0].startswith("#"):
                    continue
                host = words[0]
                if len(words) >= 2 and not words[1].startswith("#"):
                    user = words[1]
                else:
                    user = ""
                ipaddr = ""
                realhost = host
                if realhost[0] in ("+", "-"):
                    realhost = realhost[1:]
                    if realhost.startswith("@"):
                        realhost = ""
                if realhost:
                    try:
                        ipaddr = socket.gethostbyname(realhost)
                    except socket.error:
                        pass
                t.add([acct.username, host, ipaddr, user])
        finally:
            f.close()

def _test():
    from sigma.gather import gathering
    gathering.test(Gather)

if __name__ == "__main__":
    _test()
