Skip to content

Commit

Permalink
Merge pull request #55 from 0x41424142/fixes
Browse files Browse the repository at this point in the history
Bug fixes
  • Loading branch information
jake-lindsay-tfs authored Aug 5, 2024
2 parents 96f3a8e + 88ad903 commit 3bbfcf9
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 28 deletions.
23 changes: 12 additions & 11 deletions docs/vmdr.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# VMDR APIs

VMDR APIs return data on vulnerabilities in your environment as well as from the Qualys KB. It also returns data on assets, IPs/subnets, asset groups, and more.

After running:
Expand Down Expand Up @@ -27,7 +28,7 @@ You can use any of the VMDR endpoints currently supported:
|```cancel_scan```| Cancel a scan.|
|```delete_scan```| Delete a scan out of VMDR.|
|```launch_scan```| Create/launch a new VMDR scan.|
|```fetch_scan```| Pull the results of a VMDR scan as a tuple. ```tuple[0]``` is a ```pandas.DataFrame``` containing the results and ```tuple[1]``` is the ```scan_ref```.|
|```fetch_scan```| Pull the results of a VMDR scan as a ```pandas.DataFrame```.|
|```get_scanner_list```| Pull a list of VMDR scanner appliances.|
|```get_static_searchlists```| Pull a list of static search lists, according to the ```ids``` parameter.|
|```get_report_list```| Pull a list of reports.|
Expand Down Expand Up @@ -414,7 +415,7 @@ scheduled_scans = get_scan_list(auth, type='Scheduled', show_ags=True, show_op=T

### Pause Scan API

The ```pause_scan()``` API lets you pause a currently-running VM scan in VMDR. Results are returned as a tuple with two strings. tuple[0] is the response message from Qualys and tuple[1] is the scan reference. Acceptable params are:
The ```pause_scan()``` API lets you pause a currently-running VM scan in VMDR. Results are returned as a string, which is the response message from Qualys. Acceptable params are:

|Parameter| Possible Values |Description|Required|
|--|--|--|--|
Expand All @@ -428,11 +429,11 @@ from qualyspy.vmdr import pause_scan
auth = BasicAuth(<username>, <password>, platform='qg1')

result = pause_scan(auth, scan_ref='scan/123456789')
>>>("Pausing scan", "scan/123456789")
>>>Pausing scan
```

### Resume Scan API
The ```resume_scan()``` API lets you resume a paused VM scan in VMDR. Results are returned as a tuple with two strings. tuple[0] is the response message from Qualys and tuple[1] is the scan reference. Acceptable params are:
The ```resume_scan()``` API lets you resume a paused VM scan in VMDR. Results are returned as a string, which is the response message from Qualys. Acceptable params are:

|Parameter| Possible Values |Description|Required|
|--|--|--|--|
Expand All @@ -446,11 +447,11 @@ from qualyspy.vmdr import resume_scan
auth = BasicAuth(<username>, <password>, platform='qg1')

result = resume_scan(auth, scan_ref='scan/123456789')
>>>("Resuming scan", "scan/123456789")
>>>Resuming scan
```

### Cancel Scan API
The ```cancel_scan()``` API lets you cancel a VM scan in VMDR. Results are returned as a tuple with two strings. tuple[0] is the response message from Qualys and tuple[1] is the scan reference. Acceptable params are:
The ```cancel_scan()``` API lets you cancel a VM scan in VMDR. Results are returned as string, which is the response message from Qualys. Acceptable params are:

|Parameter| Possible Values |Description|Required|
|--|--|--|--|
Expand All @@ -464,11 +465,11 @@ from qualyspy.vmdr import cancel_scan
auth = BasicAuth(<username>, <password>, platform='qg1')

result = cancel_scan(auth, scan_ref='scan/123456789')
>>>("Cancelling scan", "scan/123456789")
>>>Cancelling scan
```

### Delete Scan API
The ```delete_scan()``` API lets you delete a VM scan in VMDR. Results are returned as a tuple with two strings. tuple[0] is the response message from Qualys and tuple[1] is the scan reference. Acceptable params are:
The ```delete_scan()``` API lets you delete a VM scan in VMDR. Results are returned as a string, which is the response message from Qualys. Acceptable params are:

|Parameter| Possible Values |Description|Required|
|--|--|--|--|
Expand All @@ -482,11 +483,11 @@ from qualyspy.vmdr import delete_scan
auth = BasicAuth(<username>, <password>, platform='qg1')

result = delete_scan(auth, scan_ref='scan/123456789')
>>>("Deleted scan", "scan/123456789")
>>>Deleted scan
```

### Fetch Scan Results API
The ```fetch_scan()``` API lets you download the results of a VM scan. Results are returned as a tuple. tuple[0] is the data as a pandas dataframe and tuple[1] is the scan reference. Acceptable params are:
The ```fetch_scan()``` API lets you download the results of a VM scan. Results are returned as a ```pandas.DataFrame```. Acceptable params are:

|Parameter| Possible Values |Description|Required|
|--|--|--|--|
Expand All @@ -504,7 +505,7 @@ from qualyspy.vmdr import fetch_scan
auth = BasicAuth(<username>, <password>, platform='qg1')

result = fetch_scan(auth, scan_ref='scan/123456789')
>>> (pandas.DataFrame, "scan/123456789")
>>> pandas.DataFrame
```

### Launch Scan API
Expand Down
2 changes: 2 additions & 0 deletions qualyspy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

from .vmdr import query_kb, get_host_list, get_hld

from .base.sql import make_engine, sql_upload


# surprise!
__surprise__ = b"\xe2\x9c\xa8\xe2\x9c\xa8\xe2\x9c\xa8 Have a great day!".decode("utf-8")
1 change: 1 addition & 0 deletions qualyspy/base/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
from .call_api import call_api
from .call_schema import CALL_SCHEMA
from .xml_parser import xml_parser
from .sql import make_engine, sql_upload
7 changes: 5 additions & 2 deletions qualyspy/vmdr/data_classes/vmscan.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,11 @@ def parse_duration(duration: str) -> timedelta:
days = 0
time = duration

hours, minutes, seconds = map(int, time.split(":"))
return timedelta(days=days, hours=hours, minutes=minutes, seconds=seconds)
try:
hours, minutes, seconds = map(int, time.split(":"))
return timedelta(days=days, hours=hours, minutes=minutes, seconds=seconds)
except ValueError:
return timedelta(days=days)


@dataclass(order=True)
Expand Down
32 changes: 17 additions & 15 deletions qualyspy/vmdr/vmscans.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@
"""

from datetime import datetime
from typing import Tuple, Literal
from typing import Union, Literal
from io import StringIO

from pandas import read_json, DataFrame
from numpy import nan

from qualyspy.base import call_api, xml_parser
from .data_classes.lists.base_list import BaseList
Expand Down Expand Up @@ -212,7 +213,7 @@ def manage_scan(
scan_ref: str,
action: Literal["pause", "cancel", "resume", "fetch", "delete"],
**kwargs,
) -> Tuple[str, str]:
) -> Union[str, DataFrame]:
"""
Perform an action on a VMDR scan.
Expand All @@ -230,7 +231,7 @@ def manage_scan(
client_name (str): The client name. Defaults to None. Only available for consultant subscriptions.
Returns:
Tuple[Union[str, pd.DataFrame], str]: A tuple containing either the text response or a pandas DF and the scan reference ID.
Union[str, pd.DataFrame]: Either a text response or a pandas DF.
"""

# Check for valid action:
Expand Down Expand Up @@ -283,7 +284,7 @@ def manage_scan(
if "CODE" in data.keys():
raise QualysAPIError(data["TEXT"])

return data["TEXT"], scan_ref
return data["TEXT"]

else:
# Make sure that the response is JSON:
Expand All @@ -298,14 +299,15 @@ def manage_scan(

# Parse the JSON response:
result = read_json(StringIO(response.text))

if result.empty:
print("No scan found.")
return None

return result, scan_ref
return result


def pause_scan(auth: BasicAuth, scan_ref: str) -> Tuple[str, str]:
def pause_scan(auth: BasicAuth, scan_ref: str) -> str:
"""
Pause a VMDR scan.
Expand All @@ -314,14 +316,14 @@ def pause_scan(auth: BasicAuth, scan_ref: str) -> Tuple[str, str]:
scan_ref (str): The scan reference ID. Formatted like scan/1234567890123456.
Returns:
Tuple[str, str]: A tuple containing the text response and the scan reference ID.
str: The text response from Qualys
"""

# Call manage_scan with the action set to "pause":
return manage_scan(auth=auth, scan_ref=scan_ref, action="pause")


def resume_scan(auth: BasicAuth, scan_ref: str) -> Tuple[str, str]:
def resume_scan(auth: BasicAuth, scan_ref: str) -> str:
"""
Resume a VMDR scan.
Expand All @@ -330,14 +332,14 @@ def resume_scan(auth: BasicAuth, scan_ref: str) -> Tuple[str, str]:
scan_ref (str): The scan reference ID. Formatted like scan/1234567890123456.
Returns:
Tuple[str, str]: A tuple containing the text response and the scan reference ID.
str: The text response from Qualys
"""

# Call manage_scan with the action set to "resume":
return manage_scan(auth=auth, scan_ref=scan_ref, action="resume")


def cancel_scan(auth: BasicAuth, scan_ref: str) -> Tuple[str, str]:
def cancel_scan(auth: BasicAuth, scan_ref: str) -> str:
"""
Cancel a VMDR scan.
Expand All @@ -346,14 +348,14 @@ def cancel_scan(auth: BasicAuth, scan_ref: str) -> Tuple[str, str]:
scan_ref (str): The scan reference ID. Formatted like scan/1234567890123456.
Returns:
Tuple[str, str]: A tuple containing the text response and the scan reference ID.
str: The text response from Qualys
"""

# Call manage_scan with the action set to "cancel":
return manage_scan(auth=auth, scan_ref=scan_ref, action="cancel")


def delete_scan(auth: BasicAuth, scan_ref: str) -> Tuple[str, str]:
def delete_scan(auth: BasicAuth, scan_ref: str) -> str:
"""
Delete a VMDR scan.
Expand All @@ -362,14 +364,14 @@ def delete_scan(auth: BasicAuth, scan_ref: str) -> Tuple[str, str]:
scan_ref (str): The scan reference ID. Formatted like scan/1234567890123456.
Returns:
Tuple[str, str]: A tuple containing the text response and the scan reference ID.
str: The text response from Qualys
"""

# Call manage_scan with the action set to "delete":
return manage_scan(auth=auth, scan_ref=scan_ref, action="delete")


def fetch_scan(auth: BasicAuth, scan_ref: str, **kwargs) -> Tuple[DataFrame, str]:
def fetch_scan(auth: BasicAuth, scan_ref: str, **kwargs) -> DataFrame:
"""
Fetch VMDR scan results.
Expand All @@ -384,7 +386,7 @@ def fetch_scan(auth: BasicAuth, scan_ref: str, **kwargs) -> Tuple[DataFrame, str
client_name (str): The client name. Defaults to None. Only available for consultant subscriptions.
Returns:
Tuple[pandas.DataFrame, str]: A tuple containing a pandas DF of the response and the scan reference ID.
pd.DataFrame: The scan results in a pandas DataFrame.
"""

# Call manage_scan with the action set to "fetch":
Expand Down

0 comments on commit 3bbfcf9

Please sign in to comment.