Пример #1
0
    def __init__(self, id, host, port, timeout, threads, fillserver, ssl, username = None,
                 password = None, optional=False, retention=0):
        self.id = id
        self.newid = None
        self.restart = False
        self.host = host
        self.port = port
        self.timeout = timeout
        self.threads = threads
        self.fillserver = fillserver
        self.ssl = ssl
        self.optional = optional
        self.retention = retention

        self.username = username
        self.password = password

        self.busy_threads = []
        self.idle_threads = []
        self.active = True
        self.bad_cons = 0
        self.errormsg = ''
        self.warning = ''
        self.info = None     # Will hold getaddrinfo() list
        self.request = False # True if a getaddrinfo() request is pending
        self.oddball = 'free.xsusenet.com' in host

        for i in range(threads):
            self.idle_threads.append(NewsWrapper(self, i+1))
Пример #2
0
    def __init__(self,
                 id,
                 displayname,
                 host,
                 port,
                 timeout,
                 threads,
                 priority,
                 ssl,
                 ssl_verify,
                 send_group,
                 username=None,
                 password=None,
                 optional=False,
                 retention=0,
                 categories=None):

        self.id = id
        self.newid = None
        self.restart = False
        self.displayname = displayname
        self.host = host
        self.port = port
        self.timeout = timeout
        self.threads = threads
        self.priority = priority
        self.ssl = ssl
        self.ssl_verify = ssl_verify
        self.optional = optional
        self.retention = retention
        self.send_group = send_group

        self.username = username
        self.password = password

        self.categories = categories

        # Temporary deprication warning
        if categories and (len(categories) > 1 or 'Default' not in categories):
            logging.warning(
                '[%s] Server specific categories option is scheduled to be removed in the next release of SABnzbd',
                self.host)

        self.busy_threads = []
        self.idle_threads = []
        self.active = True
        self.bad_cons = 0
        self.errormsg = ''
        self.warning = ''
        self.info = None  # Will hold getaddrinfo() list
        self.ssl_info = ''  # Will hold the type and cipher of SSL connection
        self.request = False  # True if a getaddrinfo() request is pending
        self.have_body = 'free.xsusenet.com' not in host
        self.have_stat = True  # Assume server has "STAT", until proven otherwise

        for i in range(threads):
            self.idle_threads.append(NewsWrapper(self, i + 1))
Пример #3
0
    def __reset_nw(
        self,
        nw: NewsWrapper,
        reset_msg: Optional[str] = None,
        warn: bool = False,
        wait: bool = True,
        count_article_try: bool = True,
        send_quit: bool = False,
    ):
        # Some warnings are errors, and not added as server.warning
        if warn and reset_msg:
            nw.server.warning = reset_msg
            logging.info("Thread %s@%s: %s", nw.thrdnum, nw.server.host, reset_msg)
        elif reset_msg:
            logging.debug("Thread %s@%s: %s", nw.thrdnum, nw.server.host, reset_msg)

        # Make sure this NewsWrapper is in the idle threads
        if nw in nw.server.busy_threads:
            nw.server.busy_threads.remove(nw)
        if nw not in nw.server.idle_threads:
            nw.server.idle_threads.append(nw)

        # Make sure it is not in the readable sockets
        self.remove_socket(nw)

        if nw.article:
            # Only some errors should count towards the total tries for each server
            if (
                count_article_try
                and nw.article.tries > cfg.max_art_tries()
                and (nw.article.fetcher.optional or not cfg.max_art_opt())
            ):
                # Too many tries on this server, consider article missing
                self.decode(nw.article, None)
            else:
                # Allow all servers to iterate over this nzo/nzf again
                sabnzbd.NzbQueue.reset_try_lists(nw.article)

        # Reset connection object
        nw.hard_reset(wait, send_quit=send_quit)

        # Empty SSL info, it might change on next connect
        nw.server.ssl_info = ""
Пример #4
0
    def __init__(self,
                 id,
                 displayname,
                 host,
                 port,
                 timeout,
                 threads,
                 priority,
                 ssl,
                 ssl_type,
                 send_group,
                 username=None,
                 password=None,
                 optional=False,
                 retention=0,
                 categories=None):

        self.id = id
        self.newid = None
        self.restart = False
        self.displayname = displayname
        self.host = host
        self.port = port
        self.timeout = timeout
        self.threads = threads
        self.priority = priority
        self.ssl = ssl
        self.ssl_type = None
        self.optional = optional
        self.retention = retention
        self.send_group = send_group

        self.username = username
        self.password = password

        self.categories = categories

        self.busy_threads = []
        self.idle_threads = []
        self.active = True
        self.bad_cons = 0
        self.errormsg = ''
        self.warning = ''
        self.info = None  # Will hold getaddrinfo() list
        self.request = False  # True if a getaddrinfo() request is pending
        self.have_body = 'free.xsusenet.com' not in host
        self.have_stat = True  # Assume server has "STAT", until proven otherwise

        if ssl:
            # When the user has set a supported protocol, use it
            if ssl_type and ssl_type in ssl_protocols():
                self.ssl_type = ssl_type

        for i in range(threads):
            self.idle_threads.append(NewsWrapper(self, i + 1))
Пример #5
0
def test_nntp_server(host, port, server=None, username=None, password=None, ssl=None, ssl_type=None):
    """ Will connect (blocking) to the nttp server and report back any errors """
    timeout = 4.0
    if '*' in password and not password.strip('*'):
        # If the password is masked, try retrieving it from the config
        if not server:
            servers = get_servers()
            got_pass = False
            for server in servers:
                if host in server:
                    srv = servers[server]
                    password = srv.password()
                    got_pass = True
        else:
            srv = get_servers().get(server)
            if srv:
                password = srv.password()
                got_pass = True
        if not got_pass:
            return False, T('Password masked in ******, please re-enter')
    try:
        s = Server(-1, '', host, port, timeout, 0, 0, ssl, ssl_type, False, username, password)
    except:
        return False, T('Invalid server details')

    try:
        nw = NewsWrapper(s, -1, block=True)
        nw.init_connect(None)
        while not nw.connected:
            nw.lines = []
            nw.recv_chunk(block=True)
            #more ssl related: handle 1/n-1 splitting to prevent Rizzo/Duong-Beast
            read_sockets, _, _ = select.select([nw.nntp.sock], [], [], 0.1)
            if read_sockets:
                nw.recv_chunk(block=True)
            nw.finish_connect(nw.lines[0][:3])

    except socket.timeout, e:
        if port != 119 and not ssl:
            return False, T('Timed out: Try enabling SSL or connecting on a different port.')
        else:
            return False, T('Timed out')
Пример #6
0
def test_nntp_server(host,
                     port,
                     server=None,
                     username=None,
                     password=None,
                     ssl=None,
                     ssl_type='t1'):
    """ Will connect (blocking) to the nttp server and report back any errors """
    timeout = 4.0
    if '*' in password and not password.strip('*'):
        # If the password is masked, try retrieving it from the config
        if not server:
            servers = get_servers()
            got_pass = False
            for server in servers:
                if host in server:
                    srv = servers[server]
                    password = srv.password()
                    got_pass = True
        else:
            srv = get_servers().get(server)
            if srv:
                password = srv.password()
                got_pass = True
        if not got_pass:
            return False, T('Password masked in ******, please re-enter')
    try:
        s = Server(-1, '', host, port, timeout, 0, 0, ssl, ssl_type, False,
                   username, password)
    except:
        return False, T('Invalid server details')

    try:
        nw = NewsWrapper(s, -1, block=True)
        nw.init_connect(None)
        while not nw.connected:
            nw.lines = []
            nw.recv_chunk(block=True)
            nw.finish_connect(nw.lines[0][:3])

    except socket.timeout, e:
        if port != 119 and not ssl:
            return False, T(
                'Timed out: Try enabling SSL or connecting on a different port.'
            )
        else:
            return False, T('Timed out')
Пример #7
0
 def __request_article(self, nw: NewsWrapper):
     try:
         nzo = nw.article.nzf.nzo
         if nw.server.send_group and nzo.group != nw.group:
             group = nzo.group
             if sabnzbd.LOG_ALL:
                 logging.debug("Thread %s@%s: GROUP <%s>", nw.thrdnum, nw.server.host, group)
             nw.send_group(group)
         else:
             if sabnzbd.LOG_ALL:
                 logging.debug("Thread %s@%s: BODY %s", nw.thrdnum, nw.server.host, nw.article.article)
             nw.body()
         # Mark as ready to be read
         self.read_fds[nw.nntp.fileno] = nw
     except socket.error as err:
         logging.info("Looks like server closed connection: %s", err)
         self.__reset_nw(nw, "server broke off connection", warn=True, send_quit=False)
     except:
         logging.error(T("Suspect error in downloader"))
         logging.info("Traceback: ", exc_info=True)
         self.__reset_nw(nw, "server broke off connection", warn=True, send_quit=False)
Пример #8
0
    def __init__(
        self,
        server_id,
        displayname,
        host,
        port,
        timeout,
        threads,
        priority,
        ssl,
        ssl_verify,
        ssl_ciphers,
        send_group,
        username=None,
        password=None,
        optional=False,
        retention=0,
    ):

        self.id: str = server_id
        self.newid: Optional[str] = None
        self.restart: bool = False
        self.displayname: str = displayname
        self.host: str = host
        self.port: int = port
        self.timeout: int = timeout
        self.threads: int = threads
        self.priority: int = priority
        self.ssl: bool = ssl
        self.ssl_verify: int = ssl_verify
        self.ssl_ciphers: str = ssl_ciphers
        self.optional: bool = optional
        self.retention: int = retention
        self.send_group: bool = send_group

        self.username: Optional[str] = username
        self.password: Optional[str] = password

        self.busy_threads: List[NewsWrapper] = []
        self.idle_threads: List[NewsWrapper] = []
        self.next_article_search: float = 0
        self.active: bool = True
        self.bad_cons: int = 0
        self.errormsg: str = ""
        self.warning: str = ""
        self.info: Optional[List] = None  # Will hold getaddrinfo() list
        self.ssl_info: str = ""  # Will hold the type and cipher of SSL connection
        self.request: bool = False  # True if a getaddrinfo() request is pending
        self.have_body: bool = True  # Assume server has "BODY", until proven otherwise
        self.have_stat: bool = True  # Assume server has "STAT", until proven otherwise

        for i in range(threads):
            self.idle_threads.append(NewsWrapper(self, i + 1))
Пример #9
0
    def __init__(
        self,
        server_id,
        displayname,
        host,
        port,
        timeout,
        threads,
        priority,
        ssl,
        ssl_verify,
        ssl_ciphers,
        send_group,
        username=None,
        password=None,
        optional=False,
        retention=0,
    ):

        self.id = server_id
        self.newid = None
        self.restart = False
        self.displayname = displayname
        self.host = host
        self.port = port
        self.timeout = timeout
        self.threads = threads
        self.priority = priority
        self.ssl = ssl
        self.ssl_verify = ssl_verify
        self.ssl_ciphers = ssl_ciphers
        self.optional = optional
        self.retention = retention
        self.send_group = send_group

        self.username = username
        self.password = password

        self.busy_threads = []
        self.idle_threads = []
        self.active = True
        self.bad_cons = 0
        self.errormsg = ""
        self.warning = ""
        self.info = None  # Will hold getaddrinfo() list
        self.ssl_info = ""  # Will hold the type and cipher of SSL connection
        self.request = False  # True if a getaddrinfo() request is pending
        self.have_body = "free.xsusenet.com" not in host
        self.have_stat = True  # Assume server has "STAT", until proven otherwise

        for i in range(threads):
            self.idle_threads.append(NewsWrapper(self, i + 1))
Пример #10
0
def test_nntp_server(host,
                     port,
                     server=None,
                     username=None,
                     password=None,
                     ssl=None,
                     ssl_verify=1):
    """ Will connect (blocking) to the nttp server and report back any errors """
    timeout = 4.0
    if '*' in password and not password.strip('*'):
        # If the password is masked, try retrieving it from the config
        if not server:
            servers = get_servers()
            got_pass = False
            for server in servers:
                if host in servers[server].host():
                    srv = servers[server]
                    password = srv.password()
                    got_pass = True
        else:
            srv = get_servers().get(server)
            if srv:
                password = srv.password()
                got_pass = True
        if not got_pass:
            return False, T('Password masked in ******, please re-enter')
    try:
        s = Server(-1, '', host, port, timeout, 0, 0, ssl, ssl_verify, None,
                   False, username, password)
    except:
        return False, T('Invalid server details')

    try:
        nw = NewsWrapper(s, -1, block=True)
        nw.init_connect(None)
        while not nw.connected:
            nw.clear_data()
            nw.recv_chunk(block=True)
            #more ssl related: handle 1/n-1 splitting to prevent Rizzo/Duong-Beast
            read_sockets, _, _ = select.select([nw.nntp.sock], [], [], 0.1)
            if read_sockets:
                nw.recv_chunk(block=True)
            nw.finish_connect(nw.status_code)

    except socket.timeout, e:
        if port != 119 and not ssl:
            return False, T(
                'Timed out: Try enabling SSL or connecting on a different port.'
            )
        else:
            return False, T('Timed out')
Пример #11
0
def test_nntp_server(host,
                     port,
                     server=None,
                     username=None,
                     password=None,
                     ssl=None,
                     ssl_verify=1,
                     ssl_ciphers=None):
    """ Will connect (blocking) to the nttp server and report back any errors """
    timeout = 4.0
    if "*" in password and not password.strip("*"):
        # If the password is masked, try retrieving it from the config
        if not server:
            servers = get_servers()
            got_pass = False
            for server in servers:
                if host in servers[server].host():
                    srv = servers[server]
                    password = srv.password()
                    got_pass = True
        else:
            srv = get_servers().get(server)
            if srv:
                password = srv.password()
                got_pass = True
        if not got_pass:
            return False, T("Password masked in ******, please re-enter")
    try:
        s = Server(-1, "", host, port, timeout, 0, 0, ssl, ssl_verify,
                   ssl_ciphers, False, username, password)
    except:
        return False, T("Invalid server details")

    try:
        nw = NewsWrapper(s, -1, block=True)
        nw.init_connect(None)
        while not nw.connected:
            nw.clear_data()
            nw.recv_chunk(block=True)
            # Handle 1/n-1 splitting to prevent Rizzo/Duong-Beast
            read_sockets, _, _ = select.select([nw.nntp.sock], [], [], 0.1)
            if read_sockets:
                nw.recv_chunk(block=True)
            nw.finish_connect(nw.status_code)

    except socket.timeout:
        if port != 119 and not ssl:
            return False, T(
                "Timed out: Try enabling SSL or connecting on a different port."
            )
        else:
            return False, T("Timed out")

    except socket.error as e:
        # Trying SSL on non-SSL port?
        if "unknown protocol" in str(e).lower():
            return False, T(
                "Unknown SSL protocol: Try disabling SSL or connecting on a different port."
            )

        return False, str(e)

    except TypeError:
        return False, T("Invalid server address.")

    except IndexError:
        # No data was received in recv_chunk() call
        return False, T("Server quit during login sequence.")

    except:
        return False, str(sys.exc_info()[1])

    if not username or not password:
        nw.nntp.sock.sendall(b"ARTICLE <test@home>\r\n")
        try:
            nw.clear_data()
            nw.recv_chunk(block=True)
        except:
            # Some internal error, not always safe to close connection
            return False, str(sys.exc_info()[1])

    # Close the connection
    nw.terminate(quit=True)

    if nw.status_code == 480:
        return False, T("Server requires username and password.")

    elif nw.status_code == 100 or str(nw.status_code).startswith(("2", "4")):
        return True, T("Connection Successful!")

    elif nw.status_code == 502 or clues_login(nntp_to_msg(nw.data)):
        return False, T("Authentication failed, check username/password.")

    elif clues_too_many(nntp_to_msg(nw.data)):
        return False, T(
            "Too many connections, please pause downloading or try again later"
        )

    else:
        return False, T("Could not determine connection result (%s)"
                        ) % nntp_to_msg(nw.data)