Пример #1
0
 def send_status_ping_and_verify_scanning_if_active():
     in_standby_mode = GlobalVars.standby_mode or GlobalVars.no_se_activity_scan
     if not in_standby_mode:
         # This is the active instance, so should be scanning. If it's not scanning, then report or go to standby.
         if GlobalVars.PostScanStat.get_stat(
         ) == Metasmoke.scan_stat_snapshot:
             # There's been no actvity since the last ping.
             Metasmoke.status_pings_since_scan_activity += 1
             if Metasmoke.status_pings_since_scan_activity >= NO_ACTIVITY_PINGS_TO_STANDBY:
                 # Assume something is very wrong. Report to debug rooms and go into standby mode.
                 error_message = "There's been no scan activity for {} status pings. Going into standby." \
                                 .format(Metasmoke.status_pings_since_scan_activity)
                 log('error', error_message)
                 chatcommunicate.tell_rooms_with("debug", error_message)
                 GlobalVars.standby_mode = True
                 # Let MS know immediately, to lessen potential wait time (e.g. if we fail to reboot).
                 Metasmoke.send_status_ping()
                 time.sleep(8)
                 exit_mode("standby")
             elif Metasmoke.status_pings_since_scan_activity >= NO_ACTIVITY_PINGS_TO_REPORT:
                 # Something might be wrong. Let people in debug rooms know.
                 status_message = "There's been no scan activity for {} status pings. There may be a problem." \
                                  .format(Metasmoke.status_pings_since_scan_activity)
                 log('warning', status_message)
                 chatcommunicate.tell_rooms_with("debug", status_message)
         else:
             Metasmoke.status_pings_since_scan_activity = 0
             Metasmoke.scan_stat_snapshot = GlobalVars.PostScanStat.get_stat(
             )
     Metasmoke.send_status_ping()
Пример #2
0
def restart_automatically():
    Metasmoke.send_statistics()
    chatcommunicate.tell_rooms_with(
        "debug", "{}: Executing automatic scheduled reboot.".format(
            GlobalVars.location))
    time.sleep(6)
    exit_mode("reboot")
Пример #3
0
def uncaught_exception(exctype, value, tb):
    delta = datetime.utcnow() - GlobalVars.startup_utc_date
    log_exception(exctype, value, tb)
    if delta.total_seconds() < 180 and exctype not in \
            {KeyboardInterrupt, SystemExit, requests.ConnectionError, WebSocketConnectionClosedException}:
        exit_mode("early_exception")
    else:
        exit_mode("restart")
Пример #4
0
def uncaught_exception(exctype, value, tb):
    delta = datetime.utcnow() - GlobalVars.startup_utc_date
    log_exception(exctype, value, tb)
    if delta.total_seconds() < 180 and exctype not in \
            {KeyboardInterrupt, SystemExit, requests.ConnectionError, WebSocketConnectionClosedException}:
        exit_mode("early_exception")
    else:
        exit_mode("restart")
Пример #5
0
def check_socket_connections():
    socket_failure = False
    with chatcommunicate._clients_lock:
        for client in chatcommunicate._clients.values():
            if client.last_activity and (
                    datetime.utcnow() -
                    client.last_activity).total_seconds() >= 60:
                socket_failure = True
    if socket_failure:
        exit_mode("socket_failure")
Пример #6
0
 def reboot_or_standby(action):
     error_message = "There's been no scan activity for {} status pings. Going to {}." \
                     .format(Metasmoke.status_pings_since_scan_activity, action)
     log('error', error_message)
     chatcommunicate.tell_rooms_with("debug", error_message)
     if action == "standby":
         GlobalVars.standby_mode = True
     # Let MS know immediately, to lessen potential wait time (e.g. if we fail to reboot).
     Metasmoke.send_status_ping()
     time.sleep(8)
     exit_mode(action)
Пример #7
0
def init_se_websocket_or_reboot(max_tries, tell_debug_room_on_error=False):
    for tries in range(1, 1 + max_tries, 1):
        ws = setup_websocket(tries, max_tries)
        if ws:
            break
    else:
        error_message = 'SE WebSocket: Max retries exceeded. Exiting, maybe a restart will kick things.'
        log('error', error_message)
        if tell_debug_room_on_error:
            chatcommunicate.tell_rooms_with("debug", error_message)
            time.sleep(
                6
            )  # Make it more likely the message is actually sent to the rooms prior to rebooting.
        exit_mode("reboot")

    return ws
Пример #8
0
    def send_status_ping():
        if GlobalVars.metasmoke_host is None:
            log('info', 'Attempted to send status ping but metasmoke_host is undefined. Not sent.')
            return
        elif GlobalVars.metasmoke_down:
            payload = {
                "location": GlobalVars.location,
                "timestamp": time.time()
            }
            SocketScience.send(payload)

        metasmoke_key = GlobalVars.metasmoke_key

        try:
            payload = {
                'location': GlobalVars.location,
                'key': metasmoke_key,
                'standby': GlobalVars.standby_mode
            }

            headers = {'content-type': 'application/json'}
            response = Metasmoke.post("/status-update.json",
                                      data=json.dumps(payload), headers=headers, ignore_down=True)

            try:
                response = response.json()
                GlobalVars.metasmoke_last_ping_time = datetime.now()  # Otherwise the ping watcher will exit(10)

                if response.get('pull_update', False):
                    log('info', "Received pull command from MS ping response")
                    exit_mode("pull_update")

                if 'failover' in response and GlobalVars.standby_mode:
                    if response['failover']:
                        GlobalVars.standby_mode = False

                        chatcommunicate.tell_rooms_with("debug", GlobalVars.location + " received failover signal.",
                                                        notify_site="/failover")

                if response.get('standby', False):
                    chatcommunicate.tell_rooms_with("debug",
                                                    GlobalVars.location + " entering metasmoke-forced standby.")
                    time.sleep(2)
                    exit_mode("standby")

                if response.get('shutdown', False):
                        exit_mode("shutdown")

            except Exception:  # TODO: What could happen here?
                pass

        except Exception as e:
            log('error', e)
Пример #9
0
    def handle_websocket_data(data):
        if "message" not in data:
            if "type" in data and data['type'] == "reject_subscription":
                log(
                    'error',
                    "MS WebSocket subscription was rejected. Check your MS key."
                )
                raise ConnectionError("MS WebSocket connection rejected")
            return
        message = data['message']
        if not isinstance(message, Iterable):
            return

        if "message" in message:
            chatcommunicate.tell_rooms_with("metasmoke", message['message'])
        elif "autoflag_fp" in message:
            event = message["autoflag_fp"]

            chatcommunicate.tell_rooms(event["message"],
                                       ("debug", "site-" + event["site"]),
                                       ("no-site-" + event["site"], ),
                                       notify_site="/autoflag_fp")
        elif "exit" in message:
            os._exit(message["exit"])
        elif "blacklist" in message:
            ids = (message['blacklist']['uid'], message['blacklist']['site'])

            datahandling.add_blacklisted_user(ids, "metasmoke",
                                              message['blacklist']['post'])
            datahandling.last_feedbacked = (ids, time.time() + 60)
        elif "unblacklist" in message:
            ids = (message['unblacklist']['uid'],
                   message['unblacklist']['site'])
            datahandling.remove_blacklisted_user(ids)
        elif "naa" in message:
            post_site_id = parsing.fetch_post_id_and_site_from_url(
                message["naa"]["post_link"])
            datahandling.add_ignored_post(post_site_id[0:2])
        elif "fp" in message:
            post_site_id = parsing.fetch_post_id_and_site_from_url(
                message["fp"]["post_link"])
            datahandling.add_false_positive(post_site_id[0:2])
        elif "report" in message:
            import chatcommands  # Do it here
            chatcommands.report_posts([message["report"]["post_link"]],
                                      message["report"]["user"], True,
                                      "the metasmoke API")
        elif "deploy_updated" in message:
            return  # Disabled
            sha = message["deploy_updated"]["head_commit"]["id"]
            if sha != os.popen('git log -1 --pretty="%H"').read():
                if "autopull" in message["deploy_updated"]["head_commit"][
                        "message"]:
                    if only_blacklists_changed(GitManager.get_remote_diff()):
                        commit_md = "[`{0}`](https://github.com/{1}/commit/{0})" \
                                    .format(sha[:7], GlobalVars.bot_repo_slug)
                        integrity = blacklist_integrity_check()
                        if len(integrity) == 0:  # No issues
                            GitManager.pull_remote()
                            findspam.reload_blacklists()
                            chatcommunicate.tell_rooms_with(
                                "debug",
                                "No code modified in {0}, only blacklists"
                                " reloaded.".format(commit_md))
                        else:
                            integrity.append("please fix before pulling.")
                            chatcommunicate.tell_rooms_with(
                                "debug", ", ".join(integrity))
        elif "commit_status" in message:
            c = message["commit_status"]
            sha = c["commit_sha"][:7]
            recent_commits = sp.check_output(
                ["git", "log", "-50",
                 "--pretty=%H"]).decode('utf-8').strip().split('\n')
            if c["commit_sha"] in recent_commits:
                return  # Same rev, or earlier rev (e.g. when watching things faster than CI completes), nothing to do

            if c["status"] == "success":
                if "autopull" in c["commit_message"] or c["commit_message"].startswith("!") or \
                        c["commit_message"].startswith("Auto "):
                    s = "[CI]({ci_link}) on [`{commit_sha}`](https://github.com/{repo}/" \
                        "commit/{commit_sha}) succeeded. Message contains 'autopull', pulling...".format(
                            ci_link=c["ci_url"], repo=GlobalVars.bot_repo_slug, commit_sha=sha)
                    remote_diff = GitManager.get_remote_diff()
                    if only_blacklists_changed(remote_diff):
                        GitManager.pull_remote()
                        if not GlobalVars.on_branch:
                            # Restart if HEAD detached
                            log('warning',
                                "Pulling remote with HEAD detached, checkout deploy",
                                f=True)
                            exit_mode("checkout_deploy")
                        GlobalVars.reload()
                        findspam.FindSpam.reload_blacklists()
                        chatcommunicate.tell_rooms_with(
                            'debug', GlobalVars.s_norestart_blacklists)
                    elif only_modules_changed(remote_diff):
                        GitManager.pull_remote()
                        if not GlobalVars.on_branch:
                            # Restart if HEAD detached
                            log('warning',
                                "Pulling remote with HEAD detached, checkout deploy",
                                f=True)
                            exit_mode("checkout_deploy")
                        GlobalVars.reload()
                        reload_modules()
                        chatcommunicate.tell_rooms_with(
                            'debug', GlobalVars.s_norestart_findspam)
                    else:
                        chatcommunicate.tell_rooms_with('debug',
                                                        s,
                                                        notify_site="/ci")
                        exit_mode("pull_update")
                else:
                    s = "[CI]({ci_link}) on [`{commit_sha}`](https://github.com/{repo}/commit/{commit_sha}) " \
                        "succeeded.".format(ci_link=c["ci_url"], repo=GlobalVars.bot_repo_slug, commit_sha=sha)

                    chatcommunicate.tell_rooms_with("debug",
                                                    s,
                                                    notify_site="/ci")
            elif c["status"] == "failure":
                s = "[CI]({ci_link}) on [`{commit_sha}`](https://github.com/{repo}/commit/{commit_sha}) " \
                    "failed.".format(ci_link=c["ci_url"], repo=GlobalVars.bot_repo_slug, commit_sha=sha)

                chatcommunicate.tell_rooms_with("debug", s, notify_site="/ci")
        elif "everything_is_broken" in message:
            if message["everything_is_broken"] is True:
                exit_mode("shutdown")
        elif "domain_whitelist" in message:
            if message["domain_whitelist"] == "refresh":
                metasmoke_cache.MetasmokeCache.delete('whitelisted-domains')
Пример #10
0
    def send_status_ping():
        if GlobalVars.metasmoke_host is None:
            log(
                'info',
                'Attempted to send status ping but metasmoke_host is undefined. Not sent.'
            )
            return
        elif GlobalVars.metasmoke_down:
            payload = {
                "location": GlobalVars.location,
                "timestamp": time.time()
            }
            SocketScience.send(payload)

        metasmoke_key = GlobalVars.metasmoke_key

        try:
            payload = {
                'location':
                GlobalVars.location,
                'key':
                metasmoke_key,
                'standby':
                GlobalVars.standby_mode or GlobalVars.no_se_activity_scan
            }

            headers = {'content-type': 'application/json'}
            response = Metasmoke.post("/status-update.json",
                                      data=json.dumps(payload),
                                      headers=headers,
                                      ignore_down=True)

            try:
                response = response.json()
                GlobalVars.metasmoke_last_ping_time = datetime.utcnow(
                )  # Otherwise the ping watcher will exit(10)

                if response.get('pull_update', False):
                    log('info', "Received pull command from MS ping response")
                    exit_mode("pull_update")

                if ('failover' in response and GlobalVars.standby_mode
                        and not GlobalVars.no_se_activity_scan):
                    # If we're not scanning, then we don't want to become officially active due to failover.
                    if response['failover']:
                        GlobalVars.standby_mode = False

                        chatcommunicate.tell_rooms_with(
                            "debug",
                            GlobalVars.location + " received failover signal.",
                            notify_site="/failover")

                if response.get('standby', False):
                    chatcommunicate.tell_rooms_with(
                        "debug", GlobalVars.location +
                        " entering metasmoke-forced standby.")
                    time.sleep(2)
                    exit_mode("standby")

                if response.get('shutdown', False):
                    exit_mode("shutdown")

            except Exception:  # TODO: What could happen here?
                pass

        except Exception as e:
            log('error', e)
Пример #11
0
    def handle_websocket_data(data):
        if "message" not in data:
            return
        message = data['message']
        if not isinstance(message, Iterable):
            return

        if "message" in message:
            chatcommunicate.tell_rooms_with("metasmoke", message['message'])
        elif "autoflag_fp" in message:
            event = message["autoflag_fp"]

            chatcommunicate.tell_rooms(event["message"], ("debug", "site-" + event["site"]),
                                       ("no-site-" + event["site"],), notify_site="/autoflag_fp")
        elif "exit" in message:
            os._exit(message["exit"])
        elif "blacklist" in message:
            ids = (message['blacklist']['uid'], message['blacklist']['site'])

            datahandling.add_blacklisted_user(ids, "metasmoke", message['blacklist']['post'])
            datahandling.last_feedbacked = (ids, time.time() + 60)
        elif "unblacklist" in message:
            ids = (message['unblacklist']['uid'], message['unblacklist']['site'])
            datahandling.remove_blacklisted_user(ids)
        elif "naa" in message:
            post_site_id = parsing.fetch_post_id_and_site_from_url(message["naa"]["post_link"])
            datahandling.add_ignored_post(post_site_id[0:2])
        elif "fp" in message:
            post_site_id = parsing.fetch_post_id_and_site_from_url(message["fp"]["post_link"])
            datahandling.add_false_positive(post_site_id[0:2])
        elif "report" in message:
            import chatcommands  # Do it here
            chatcommands.report_posts([message["report"]["post_link"]], message["report"]["user"],
                                      True, "the metasmoke API")
        elif "deploy_updated" in message:
            return  # Disabled
            sha = message["deploy_updated"]["head_commit"]["id"]
            if sha != os.popen('git log -1 --pretty="%H"').read():
                if "autopull" in message["deploy_updated"]["head_commit"]["message"]:
                    if only_blacklists_changed(GitManager.get_remote_diff()):
                        commit_md = "[`{0}`](https://github.com/{1}/commit/{0})" \
                                    .format(sha[:7], GlobalVars.bot_repo_slug)
                        integrity = blacklist_integrity_check()
                        if len(integrity) == 0:  # No issues
                            GitManager.pull_remote()
                            findspam.reload_blacklists()
                            chatcommunicate.tell_rooms_with("debug", "No code modified in {0}, only blacklists"
                                                            " reloaded.".format(commit_md))
                        else:
                            integrity.append("please fix before pulling.")
                            chatcommunicate.tell_rooms_with("debug", ", ".join(integrity))
        elif "commit_status" in message:
            c = message["commit_status"]
            sha = c["commit_sha"][:7]
            if c["commit_sha"] == sp.check_output(["git", "log", "-1", "--pretty=%H"]).decode('utf-8').strip():
                return  # Same rev, nothing to do

            if c["status"] == "success":
                if "autopull" in c["commit_message"] or c["commit_message"].startswith("!") or \
                        c["commit_message"].startswith("Auto "):
                    s = "[CI]({ci_link}) on [`{commit_sha}`](https://github.com/{repo}/" \
                        "commit/{commit_sha}) succeeded. Message contains 'autopull', pulling...".format(
                            ci_link=c["ci_url"], repo=GlobalVars.bot_repo_slug, commit_sha=sha)
                    remote_diff = GitManager.get_remote_diff()
                    if only_blacklists_changed(remote_diff):
                        GitManager.pull_remote()
                        if not GlobalVars.on_branch:
                            # Restart if HEAD detached
                            log('warning', "Pulling remote with HEAD detached, checkout deploy", f=True)
                            exit_mode("checkout_deploy")
                        GlobalVars.reload()
                        findspam.FindSpam.reload_blacklists()
                        chatcommunicate.tell_rooms_with('debug', GlobalVars.s_norestart)
                    elif only_modules_changed(remote_diff):
                        GitManager.pull_remote()
                        if not GlobalVars.on_branch:
                            # Restart if HEAD detached
                            log('warning', "Pulling remote with HEAD detached, checkout deploy", f=True)
                            exit_mode("checkout_deploy")
                        GlobalVars.reload()
                        reload_modules()
                        chatcommunicate.tell_rooms_with('debug', GlobalVars.s_norestart2)
                    else:
                        chatcommunicate.tell_rooms_with('debug', s, notify_site="/ci")
                        exit_mode("pull_update")
                else:
                    s = "[CI]({ci_link}) on [`{commit_sha}`](https://github.com/{repo}/commit/{commit_sha}) " \
                        "succeeded.".format(ci_link=c["ci_url"], repo=GlobalVars.bot_repo_slug, commit_sha=sha)

                    chatcommunicate.tell_rooms_with("debug", s, notify_site="/ci")
            elif c["status"] == "failure":
                s = "[CI]({ci_link}) on [`{commit_sha}`](https://github.com/{repo}/commit/{commit_sha}) " \
                    "failed.".format(ci_link=c["ci_url"], repo=GlobalVars.bot_repo_slug, commit_sha=sha)

                chatcommunicate.tell_rooms_with("debug", s, notify_site="/ci")
        elif "everything_is_broken" in message:
            if message["everything_is_broken"] is True:
                exit_mode("shutdown")
Пример #12
0
        # Ran into this error in testing on Windows, best to throw a warn if we get this...
        err_msg = "WARNING: Cannot verify SSL connection for TLD names update; skipping TLD names update."

    else:
        err_msg = strerror
    log_exception(type(ioerr), ioerr, err_msg, True, level="warning")

if "ChatExchangeU" in os.environ:
    log('debug', "ChatExchange username loaded from environment")
    username = os.environ["ChatExchangeU"]
elif GlobalVars.chatexchange_u:
    log('debug', "ChatExchange username loaded from config")
    username = GlobalVars.chatexchange_u
else:
    log('error', "No ChatExchange username provided. Set it in config or provide it via environment variable")
    exit_mode("shutdown")

if "ChatExchangeP" in os.environ:
    log('debug', "ChatExchange password loaded from environment")
    password = os.environ["ChatExchangeP"]
elif GlobalVars.chatexchange_p:
    log('debug', "ChatExchange password loaded from config")
    password = GlobalVars.chatexchange_p
else:
    log('error', "No ChatExchange password provided. Set it in config or provide it via environment variable")
    exit_mode("shutdown")

# We need an instance of bodyfetcher before load_files() is called
GlobalVars.bodyfetcher = BodyFetcher()
if GlobalVars.flovis_host:
    GlobalVars.flovis = Flovis(GlobalVars.flovis_host)
Пример #13
0
def restart_automatically():
    Metasmoke.send_statistics()
    exit_mode("reboot")
Пример #14
0
def restart_automatically():
    Metasmoke.send_statistics()
    exit_mode("reboot")
Пример #15
0
def check_socket_connections():
    for client in chatcommunicate._clients.values():
        if client.last_activity and (datetime.utcnow() - client.last_activity).total_seconds() >= 60:
            exit_mode("socket_failure")
Пример #16
0
            errlogs.write("WARNING: Cannot verify SSL connection for TLD names update; skipping TLD names update.")
            errlogs.close()
            pass

        else:
            raise ioerr

if "ChatExchangeU" in os.environ:
    log('debug', "ChatExchange username loaded from environment")
    username = os.environ["ChatExchangeU"]
elif GlobalVars.chatexchange_u:
    log('debug', "ChatExchange username loaded from config")
    username = GlobalVars.chatexchange_u
else:
    log('error', "No ChatExchange username provided. Set it in config or provide it via environment variable")
    exit_mode("shutdown")

if "ChatExchangeP" in os.environ:
    log('debug', "ChatExchange password loaded from environment")
    password = os.environ["ChatExchangeP"]
elif GlobalVars.chatexchange_p:
    log('debug', "ChatExchange password loaded from config")
    password = GlobalVars.chatexchange_p
else:
    log('error', "No ChatExchange password provided. Set it in config or provide it via environment variable")
    exit_mode("shutdown")

# We need an instance of bodyfetcher before load_files() is called
GlobalVars.bodyfetcher = BodyFetcher()
if GlobalVars.flovis_host:
    GlobalVars.flovis = Flovis(GlobalVars.flovis_host)