Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions agent/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ def _missing_(cls, value):
return None


TERMINAL_STATUSES = [Status.COMPLETE, Status.FAILED, Status.EXCEPTION]

AGENT_BROWSER_EXT_PATH = ""
AGENT_BROWSER_LOCK = Lock()
ANALYZER_FOLDER = ""
Expand Down Expand Up @@ -494,6 +496,11 @@ def put_status():
except ValueError:
return json_error(400, "No valid status has been provided")

# If the new status is terminal, unset the async subprocess so /status reports
# the final analysis state rather than the child process state.
if status in TERMINAL_STATUSES:
state["async_subprocess"] = None

state["status"] = status
state["description"] = request.form.get("description")
return json_success("Analysis status updated")
Expand Down
28 changes: 28 additions & 0 deletions agent/test_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,34 @@ def test_async_failure(self):
js = self.confirm_status(str(agent.Status.FAILED))
assert "process_id" not in js

def test_async_manual_status_override(self):
"""Test that a manual status update overrides an in-progress async process."""
# Upload a Python file that sleeps for a short period, to ensure the
# async subprocess is running while we override the status.
file_contents = (
"import time",
"time.sleep(10)",
)

filepath = self.store_file(file_contents)
form = {"filepath": filepath, "async": 1}

execpy_resp = self.post_form("execpy", form)
assert execpy_resp.get("message") == "Successfully spawned command"

# While the subprocess is running, the status should initially be RUNNING.
self.confirm_status(str(agent.Status.RUNNING))

# Manually override the status to COMPLETE via POST /status.
override_form = {
"status": str(agent.Status.COMPLETE),
"description": "beep boop"
}
status_resp = self.post_form("status", override_form)
assert status_resp.get("message") == "Analysis status updated"

self.confirm_status(str(agent.Status.COMPLETE))

def test_execute(self):
"""Test executing the 'date' command."""
if sys.platform == "win32":
Expand Down
10 changes: 0 additions & 10 deletions docs/book/src/installation/host/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -53,16 +53,6 @@ want to pay more attention to are:
.. _`SQLAlchemy`: http://www.sqlalchemy.org/
.. _`Database Urls`: http://docs.sqlalchemy.org/en/latest/core/engines.html#database-urls

.. warning:: Check your interface for resultserver IP! Some virtualization software (for example Virtualbox)
doesn't bring up the virtual networking interfaces until a virtual machine is started.
CAPE needs to have the interface where you bind the resultserver up before the start, so please
check your network setup. If you are not sure about how to get the interface up, a good trick is to manually start
and stop an analysis virtual machine, this will bring virtual networking up.
If you are using NAT/PAT in your network, you can set up the resultserver IP
to 0.0.0.0 to listen on all interfaces, then use the specific options `resultserver_ip` and `resultserver_port`
in *<machinery>.conf* to specify the address and port as every machine sees them. Note that if you set
resultserver IP to 0.0.0.0 in cuckoo.conf you have to set `resultserver_ip` for all your virtual machines.

.. note:: Default freespace value is 50GB
It is worth mentioning that the default ``freespace`` value in ``cuckoo.conf`` is 50000 MB aka 50 GB.

Expand Down
2 changes: 1 addition & 1 deletion web/templates/analysis/admin/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
</tr>
{% if analysis.info.user_id %}
<tr>
<th>Task cretated by user id: <a href="{% url "admin:auth_user_change" analysis.info.user_id %}">{{analysis.info.user_id}}</a></th>
<th>Task created by user id: <a href="{% url "admin:auth_user_change" analysis.info.user_id %}">{{analysis.info.user_id}}</a></th>
<td>
<a href="{% url "ban_user" analysis.info.user_id %}" class="btn btn-danger btn-sm" data-bs-toggle="tooltip" title="Ban user"><i class="fas fa-user-lock"></i></a>
or
Expand Down