paragbaxi / qualysapi Goto Github PK
View Code? Open in Web Editor NEWQualys API connector.
License: Apache License 2.0
Qualys API connector.
License: Apache License 2.0
Appreciate all the work and recent activity, but any chance we can have the changelog maintained as well? Suddenly piprot in my CI/CD workflow is telling me I have dependencies that are 1400+ days out of date! I then had to come here and start picking through merges to see what's been updated, only to find the initial pushes of code with Python 3 support caused some issues with Python 2, etc.
So some notes in the changelog about new features, compatibility changes, and bug fixes would be really helpful!
Storing creds in a file isn't very secure. Why not pull them from env variables or enable them to be passed in to the connect(). This way there is a better chance they don't get caught up in code commits or they could be stored in a vault and passed in a run time.
Hi Parag,
got one small issues with launching scan using V2 API. My code:
a = qualysapi.connect(remember_me=True)
call = '/api/2.0/fo/scan/'
scan_title = usr_account + ' ' + time.asctime(time.gmtime())
parameters = {'action':'launch','asset_groups': usr_account, 'scan_title': scan_title, 'iscanner_name': 'External'}
print 'Launching scan! This might take a while. Please wait..'
xml_output = a.request(call, parameters)
and I get the error:
File "/usr/local/Cellar/python/2.7.6/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/requests/models.py", line 773, in raise_for_status
raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 400 Client Error: Bad Request
Any idea what I am doing wrong?
Many thanks for great module!
Vladimir
I am new to Qualys, but this behavior is not what I expect. If this is an issue, I am happy to make a PR. If I am misunderstanding something, appoligizes in advance. ๐
Inconsistent behavior:
qualys.request("/EXAMPLE/", api_version="2")
...
DEBUG:qualysapi.connector:Base url =
https://qualysguard.qg2.apps.qualys.com/qps/rest/2.0/
...
qualys.request("/EXAMPLE/", api_version=2)
...
DEBUG:qualysapi.connector:Base url =
https://qualysguard.qg2.apps.qualys.com/
...
qualys.url_api_version("2")
...
Exception: Unknown QualysGuard API Version Number (2)
What I would expect:
qualys.request("/EXAMPLE/", api_version=2)
...
DEBUG:qualysapi.connector:Base url =
https://qualysguard.qg2.apps.qualys.com/api/2.0/
...
At some point it would be nice to have the certview API included as well.
I'm willing to work on this, but I can't right now. I figured I'd leave this here in case anybody else had the time.
Link to Qualys docs: https://www.qualys.com/docs/qualys-certview-api-user-guide.pdf
https://travis-ci.org/paragbaxi/qualysapi/jobs/353189768#L478
qualysapi code, maybe since 6.0 version, does not reuse the http_method identification between functions.
When I return http_method build into QDconnector.build_request function to calling functions, the correct http_method is used (POST by default, which is problematic with some API call).
3 lines to change:
line 281: return url, data, headers, http_method
ligne 288: url, data, headers, http_method = self.build_request(api_call, data, api_version, http_method)
line 359: url, data, headers, http_method = self.build_request(api_call, data, api_version, http_method)
Many thanks for your code.
When attempting to import this module in a test project I encountered a runtime import error regarding the urlparse module from urllib.parse (ImportError: No module named parse).
After some research I discovered that this module in urllib is Python 3 specific, and for Python 2 urlparse should be imported from the urlparse module. I've fixed this locally and it works under Python 2 and 3.
I'm unsure if issue is only affecting me on my system, or if it is a real issue and applies to everyone. I'd appreciate if a maintainer could review it.
I'm happy to submit a pull request if this issue is considered valid.
So I've been plunking around withing qualysapi for a few weeks to see if it will/can handle what I/we need (essentially enterprise-level massive network stuff [million+hosts].
The short answer is no, not as it is. The good ansewr is that it's light enoguh to be a decent base. As such I've started implementing some internal changes I think others may be interested in so I'm putting this in as an interest-level feeler. if interest is sufficiently high, I will either fork the project or contribute the code (whatever, doesn't matter much to me).
The changes I have implemented include the following:
Lemme know.
Whilst porting some basic scripts over to AWS, we are encountering an issue relating to the chardet detection which ultimately crashes the script. This does not affect the original script running on the windows box.
Error is as follows;
ubuntu@XXXXX:~$ time ./KB-AWS-test.py -d
Downloading KB...
Traceback (most recent call last):
File "./KB-AWS-test.py", line 41, in <module>
downloadKB()
File "./KB-AWS-test.py", line 26, in downloadKB
print a.request(call, parameters)
File "/home/ubuntu/.local/lib/python2.7/site-packages/qualysapi/connector.py", line 327, in request
response = request.text
File "/home/ubuntu/.local/lib/python2.7/site-packages/requests/models.py", line 857, in text
encoding = self.apparent_encoding
File "/home/ubuntu/.local/lib/python2.7/site-packages/requests/models.py", line 727, in apparent_encoding
return chardet.detect(self.content)['encoding']
File "/home/ubuntu/.local/lib/python2.7/site-packages/chardet/__init__.py", line 38, in detect
detector.feed(byte_str)
File "/home/ubuntu/.local/lib/python2.7/site-packages/chardet/universaldetector.py", line 211, in feed
if prober.feed(byte_str) == ProbingState.FOUND_IT:
File "/home/ubuntu/.local/lib/python2.7/site-packages/chardet/charsetgroupprober.py", line 71, in feed
state = prober.feed(byte_str)
File "/home/ubuntu/.local/lib/python2.7/site-packages/chardet/hebrewprober.py", line 227, in feed
byte_str = self.filter_high_byte_only(byte_str)
File "/home/ubuntu/.local/lib/python2.7/site-packages/chardet/charsetprober.py", line 63, in filter_high_byte_only
buf = re.sub(b'([\x00-\x7F])+', b' ', buf)
File "/usr/lib/python2.7/re.py", line 155, in sub
return _compile(pattern, flags).sub(repl, string, count)
MemoryError
real 22m2.627s
user 13m54.835s
sys 0m8.815s
The script responsible for the crash is as follows;
#!/usr/bin/env python
import qualysapi
from optparse import OptionParser
import sys
def downloadKB():
print 'Downloading KB...'
a = qualysapi.connect()
call = '/api/2.0/fo/knowledge_base/vuln/'
parameters = {'action': 'list'}
print a.request(call, parameters)
#write file at once - takes a while and no feedback, build out chunking/feedback procedure...TODO
#f = open('KB.xml', 'w')
#f.write(a.request(call, parameters))
#f.close()
return
#### MAIN ####
parser = OptionParser()
parser.add_option("-d", action="store_true", dest="downloadFlag")
(options, args) = parser.parse_args()
if options.downloadFlag:
downloadKB()
It is similar to experienced with chardet elsewhere ([(https://github.com/sentinelsat/sentinelsat/issues/150)]) and can be resolved by forcing encoding type on response?
qualysapi/qualysapi/connector.py
Line 320 in c6a0e22
In python 3, this should read either
response = request.content
that will return bytes
or if you absolutely want unicode repr:
response = request.content.decode()
that will return a python 3 (unicode) string
why is this important ?
well right now, an api call in python 3 returns an unicode value of the python bytes string representation of the bytes returned by the request.
something like "b\'this is from qualys\\nwith escaped escape characters\\r\\nNot easy to parse.\'"
You can notice the leading "b\'"
and ending \'
that are problematic also.
instead of the expected b'this is from qualys\nwith normal escape characters\r\neasy to parse.'
Hello,
I am having some trouble getting qualysapi to work on xubuntu 14.04 with python 2.7.6.
Using the basic example qualysapi.connect(remember_me_always=True)
in the python shell returns the same error.
Trying from qualysapi import *
and from qualysapi import connect
both don't work when trying to use .connect.
Please let me know if there is anything that I can include to help troubleshoot this issue.
Hello. Are there any plans to migrate this package to Python 3? I was able to make a usable version with 2to3 and a few minor tweaks, but it'd be nice to see an official version!
Thanks.
Hi, as the subject says -- 6.0.0 seems to be git tagged, but in Pypi?
Is there any reason why you're doubling up with logging
and print()
statements?
I believe it should only use logging
, and the user of the package can then filter etc.
I recommend an update to the configuration file and credential parsing. Currently the credentials are in the clear. Obfuscating the credentials is preferred to prevent casual credential disclosure. Obfuscation is not security, but it does have its place.
Update the qualysapi/config.py code:
import base64 as b64
Change the 'get_auth' function from:
def get_auth(self):
''' Returns username from the configfile. '''
return (self._cfgparse.get('info', 'username'), self._cfgparse.get('info', 'password'))
to:
def get_auth(self):
''' Returns username from the configfile. '''
if self._cfgparse.get('info', 'encoded'):
return (b64.decodestring(self._cfgparse.get('info', 'username')), b64.decodestring(self._cfgparse.get('info', 'password')))
return (self._cfgparse.get('info', 'username'), self._cfgparse.get('info', 'password'))
Update the config file info block to include an 'encode' variable. It can be false if people don't want to use it.:
[info]
#hostname = qualysapi.serviceprovider.com
encoded = True
username = cHl0aG9uMi43
password = ISFPYmZ1c2NhdGlvbklzMkdvb2QhIQ==
Update the README to help people encode their credentials:
user> ipython
In [1]: import base64 as b64
In [2]: b64.encodestring('python2.7').strip()
Out[2]: 'cHl0aG9uMi43'
In [3]: b64.encodestring('!!ObfuscationIs2Good!!').strip()
Out[3]: 'ISFPYmZ1c2NhdGlvbklzMkdvb2QhIQ=='
Go forth and do good things,
Cutaway
From Qualys community:
Alex waitkus Jun 3, 2014 8:32 AM
When I try to install qualysapi on OSX, i get the following error
In file included from src/lxml/lxml.etree.c:346:
/private/tmp/pip_build_root/lxml/src/lxml/includes/etree_defs.h:9:10: fatal error: 'libxml/xmlversion.h' file not found
^
1 error generated.
error: command '/usr/bin/clang' failed with exit status 1
Cleaning up...
Command /Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python -c "import setuptools, tokenize;file='/private/tmp/pip_build_root/lxml/setup.py';exec(compile(getattr(tokenize, 'open', open)(file).read().replace('\r\n', '\n'), file, 'exec'))" install --record /tmp/pip-9pHqjS-record/install-record.txt --single-version-externally-managed --compile failed with error code 1 in /private/tmp/pip_build_root/lxml
Storing debug log for failure in /Users/awaitkus/.pip/pip.log
Any ideas? Python 2.7 and pip installed correctly
The future_strings
is required to support f-strings in Python 3.5. Newer versions of Python support f-strings natively.
Python 3.5 is EOL Sept 13, 2020 (see https://devguide.python.org/#status-of-python-branches). If support is dropped a little early the code base and dependencies can be simplified.
The library has caused some confusion, see #73.
Hi,
I have the following code:
$python
import qualysapi
q = qualysapi.connect('config.ini')
r = {'ud2': ' ', 'ud3': ' ', 'ud1': ' ', 'host_ips': '192.168.200.198', 'comment': ' ', 'tracking_method': 'IP', 'action': 'add'}
url = '/api/2.0/fo/asset/ip'
data = q.request(url,r)
WARNING:requests.packages.urllib3.connectionpool:Retrying (10 attempts remain) after connection broken by 'error(110, 'Connection timed out')': /api/2.0/fo/asset/ip/
Traceback (most recent call last):
File "", line 1, in
File "/usr/lib/python2.6/site-packages/qualysapi/connector.py", line 300, in request
request.raise_for_status()
File "/usr/lib/python2.6/site-packages/requests/models.py", line 773, in raise_for_status
raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 400 Client Error: Bad Request
Is there any error in my code or a big in qualysapi?
When running the function notScannedSince
, this will only pull the first page of results and show only those that applied to the filter within that first page.
Proposal:
Instead of having a single call, write this into a loop that will gather the affected systems, process against the filter, then check if there is another page (this is returned as part of a RESPONSE.WARNING) and then request the next page.
Hi,
I am trying to get a tag with the following code and get this error:
import qualysapi
q = qualysapi.connect('new_consolidated.ini')
d = q.request('/get/am/tag/1111')
d
'\n OPERATION_NOT_SUPPORTED\n \n Operation not supported for this object using POST method.\n Refer to the QPS guide for authorized operation for this domain object.\n \n'
Looking into your code (api_methods.py) this call is in the dictionary key [am get] so it should use GET method. Any idea what is wrong?
I have qualysapi 3.6.1
Best regards
Vladimir
The code styling is inconsistent in the project (i.e. both '
and "
, import order, etc). I suggest using Black
and isort
.
I can make the PR and integrate checks into the CI.
qualysapi/qualysapi/api_actions.py
Line 8 in 3605a44
should be getHost(self, host)
Hi folks, I will not be able to give this package the TLC it deserves. I'm looking for someone to takeover. Any volunteers?
Running pip install qualysapi fails to locate any matching module. Running python3 -m pip install qualysapi finds the module and installs.
However, running the build command with python2 fails with error:
File "setup.py", line 1
SyntaxError: encoding problem: future_fstrings
Running python3 setup.py build appears to work successfully; but running python3 setup.py install fails with this same error:
File "setup.py", line 1
SyntaxError: encoding problem: future_fstring
Recently had an issue transferring my script to another server. Installed qualysapi (doesn't work for python2 but thats fine). But when attempting to do qualysapi.connect() it accepted my username and password but would not find the correct API base url. (I am on qg3). Not sure if this functionality was removed on Qualys' end as when I first used this a while back it worked just fine.
Adding the base url to the config file does the trick, but flat out won't work unless you put the correct url. So effectively
connect()
connect(username,password)
Doesn't work.
Hi, I am trying to interact with Qualys API within Azure pipeline however, I was wondering if qualysapi
package is officially approved by Qualys?
I need to use this in enterprise CICD apps.
I'm trying to pull down a report that is a .zip binary - which is how Qualys present their HTML format reports. I'm having problems getting the results written to disk in a way that I can use unzip on it.
If I try the following:
from PIL import Image
from io import BytesIO
results = qgc.request(call, parameters)
z = Image.open(BytesIO(results.content))
I get the error
AttributeError: 'str' object has no attribute 'content'
Hi,
I keep getting the above error when trying to connect with credentials.
I haven't changed the script, apart from username and password obviously.
Any ideas?
I wasn't sure if I should comment on #14 or open a new request, but I figured since in 2015 python3 support was a "sometime, maybe" thing and now it's a "soon, hopefully" request, I'd make a new one.
I can probably volunteer some time (either my own or somebody else's :) ) to do this if there's no current plans, although I think that would probably look like a fork without regards to maintaining any (deliberate) compatibility with 2.x.
I am getting the below error when I try to run $pip install qualysapi
[[email protected] ~]# pip install qualysapi
DEPRECATION: Python 2.7 reached the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 is no longer maintained. pip 21.0 will drop support for Python 2.7 in January 2021. More details about Python 2 support in pip can be found at https://pip.pypa.io/en/latest/development/release-process/#python-2-support pip 21.0 will remove support for this functionality.
Collecting qualysapi
Using cached qualysapi-7.1.0.tar.gz (27 kB)
ERROR: Command errored out with exit status 1:
command: /usr/bin/python -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-fzvmi6/qualysapi/setup.py'"'"'; file='"'"'/tmp/pip-install-fzvmi6/qualysapi/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(file);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, file, '"'"'exec'"'"'))' egg_info --egg-base /tmp/pip-pip-egg-info-10z6LK
cwd: /tmp/pip-install-fzvmi6/qualysapi/
Complete output (6 lines):
Traceback (most recent call last):
File "", line 1, in
File "/tmp/pip-install-fzvmi6/qualysapi/setup.py", line 12
require(f"setuptools>={SETUPTOOLS_VER}")
^
SyntaxError: invalid syntax
----------------------------------------
ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.
Hi,
I am having an issue with calls to scheduled scans. I am using the "/api/2.0/fo/schedule/scan/?" URL for the call and the action=list parameter to pull the existing scheduled scans, however i am getting back the following error:
--SNIP--
Request method POST is incompatible with specified parameter(s): action=list
--SNIP--
The above mentioned URL is not listed in the api_methods.py file. Could this be the issue, or something else?
I'm interested in adding support for the certview API:
https://www.qualys.com/docs/qualys-certview-api-user-guide.pdf
I think, looking at the code, that the place to do this would be to add in api_methods.py a new dict, something like
api_methods["certview post"] = {
"certview/v1/certificates",
etc
}
Is that correct? I wouldn't necessarily implement the whole API immediately, I have my own needs, but I can probably at least get a start on it.
Hi,
I am trying to set the hostname to "https://myqualysinstance.com", but the issue is that it actually does a request to "://myqualysinstance.com", which will fail because this is not a valid URL. Seems like the library removes the "https" from the URL. If I provide the URL without the HTTP schema like "myqualysinstance.com", everything works fine.
Hi,
some Qualys API V2 (/api/2.0/fo/asset/host/ and /api/2.0/fo/asset/host/vm/detection/) responses have XML response at the end that points to the next URL. With this URL a next batch of assets can be downloaded.
Do you have a way to process this nextURL and use it in the next qualysapi call?
Cheers
Vladimir
Greetings dear,
My name is Jose Garcia. I am working on a Qualys API development inherited by another team of developers. That API in Python was designed in 2014 and at that time the API version was 1 and Python 2.7.
We are currently using the qualyapi available for Python. We are validating the functions we have created and the launch_scan function is failing.
I share with you the code of this function to know if it is possible your support to identify the failure.
###################################################
!/usr/bin/python3
from defusedxml.ElementTree import fromstring
from qualysapi import connect
import pdb
import requests
def launches_scan(dir_ip, scanner, scan_name, profile, client_name, when=None):
'''
:param
:return: Runs a Scan against Qualys, returns 1 if the scan was positive. If there was an error it returns 0.
'''
xml_output = ""
#qgc = conn
#option_title = profile
if when is not None:
print ("[+] Waiting for a moment to launch Scan.")
#tool.progress_delay(when)
print ('+-----------------------------------------------------------------------------+')
print("[+] Launching Scan for IP address=" + str(dir_ip) + " using name " + str(scan_name))
#api_url = '/api/2.0/fo/scan/'
parameters = {'ip': dir_ip,'action' :'Launch','scan_name' : scan_name,'option_title' : profile,'iscanner_name' : 'CGSI_SCANNER_1','priority' : 6,'client_name' : client_name }
pdb.set_trace()
resp = conn.request(api_url, parameters)
#dict('ip': dir_ip,'action' :'Launch','scan_name' : scan_name,'option_title' : profile,'iscanner_id' : 'CGSI_SCANNER_1','priority' : 6,'client_name' : 'Multibank')
#print xml_output
#pdb.set_trace()
api_url = "/api/2.0/fo/scan/?action=Launch"
conn = connect(
username= "xxxxx", # Qualys Username
password= "xxxxxx", # Qualys Password
hostname= "qualysguard.qualys.com", # Optional api host url
max_retries= "10", # Optional # of retries
)
db_configs = {}
#pdb.set_trace()
launches_scan('192.168.254.7', 1, "SQ-RM-CGSI-I-FULL-20200228-192.168.254.220-001", "FULL SCAN PROFILE", 'Multibank', when=None)
I remain attentive to your comments.
It appears the scheduled scans endpoint for some reason doesn't take POST requests for listing scans... no idea why. The request needs to be performed as a GET with URL parameters instead.
>>> parameters = {'action': 'list', 'echo_request': 1}
>>> call = 'api/2.0/fo/schedule/scan/'
>>> xml_output = qgc.request(call, parameters)
DEBUG:qualysapi.connector:api_call =
api/2.0/fo/schedule/scan/
DEBUG:qualysapi.connector:api_version =
None
DEBUG:qualysapi.connector:data <type 'dict'> =
{'action': 'list', 'echo_request': 1}
DEBUG:qualysapi.connector:http_method =
None
DEBUG:qualysapi.connector:concurrent_scans_retries =
0
DEBUG:qualysapi.connector:concurrent_scans_retry_delay =
0
DEBUG:qualysapi.connector:Base url =
https://qualysapi.qg3.apps.qualys.com/
DEBUG:qualysapi.connector:headers =
{'X-Requested-With': 'Parag Baxi QualysAPI (python) v4.1.0'}
DEBUG:qualysapi.connector:http_method =
post
DEBUG:qualysapi.connector:api_call post strip =
api/2.0/fo/schedule/scan/
DEBUG:qualysapi.connector:api_call =
api/2.0/fo/schedule/scan/
DEBUG:qualysapi.connector:url =
https://qualysapi.qg3.apps.qualys.com/api/2.0/fo/schedule/scan/
DEBUG:qualysapi.connector:data =
{'action': 'list', 'echo_request': 1}
DEBUG:qualysapi.connector:headers =
{'X-Requested-With': 'Parag Baxi QualysAPI (python) v4.1.0'}
DEBUG:qualysapi.connector:POST request.
DEBUG:qualysapi.connector:response headers =
{'X-RateLimit-Remaining': '288', 'X-XSS-Protection': '1', 'X-Content-Type-Options': 'nosniff', 'X-Concurrency-Limit-Limit': '2', 'Transfer-Encoding': 'chunked', 'Server': 'Qualys', 'X-Concurrency-Limit-Running': '0', 'Connection': 'close', 'X-RateLimit-Limit': '300', 'X-RateLimit-ToWait-Sec': '0', 'Date': 'Tue, 13 Jun 2017 14:45:53 GMT', 'Content-Type': 'text/xml;charset=UTF-8', 'X-RateLimit-Window-Sec': '3600'}
DEBUG:qualysapi.connector:rate limit for api_call, api/2.0/fo/schedule/scan/ = 288
DEBUG:qualysapi.connector:response text =
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE SIMPLE_RETURN SYSTEM "https://qualysapi.qg3.apps.qualys.com/api/2.0/simple_return.dtd">
<SIMPLE_RETURN>
<REQUEST>
<DATETIME>2017-06-13T14:45:53Z</DATETIME>
<USER_LOGIN>user</USER_LOGIN>
<RESOURCE>https://qualysapi.qg3.apps.qualys.com/api/2.0/fo/schedule/scan/</RESOURCE>
<PARAM_LIST>
<PARAM>
<KEY>action</KEY>
<VALUE>list</VALUE>
</PARAM>
<PARAM>
<KEY>echo_request</KEY>
<VALUE>1</VALUE>
</PARAM>
</PARAM_LIST>
</REQUEST>
<RESPONSE>
<DATETIME>2017-06-13T14:45:53Z</DATETIME>
<CODE>1908</CODE>
<TEXT>Request method POST is incompatible with specified parameter(s): action=list</TEXT>
</RESPONSE>
</SIMPLE_RETURN>
Error! Received a 4XX client error or 5XX server error response.
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python2.7/site-packages/qualysapi/connector.py", line 343, in request
request.raise_for_status()
File "/usr/local/lib/python2.7/site-packages/requests/models.py", line 909, in raise_for_status
raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 400 Client Error: Bad Request for url: https://qualysapi.qg3.apps.qualys.com/api/2.0/fo/schedule/scan/
When I set the logging level to Debug the proxy credentials are logged. Can we remove the proxy creds being logged? I am happy to create a PR if that's fine.
Just a suggestion to set the repo to not make a PR merge-able until all test pass :)
Hi guys,
I'm getting MemoryError when I download a 700MB report (works fine for smaller reports, 10-15MB).
I can download the same 700MB report via curl call.
Iโm using a Windows machine with 8GB of RAM.
Here is the output:
import qualysapi
a = qualysapi.connect()
WARNING:root:config.ini permissions allows more than user access.
rep = a.request('/api/2.0/fo/report', {'action': 'fetch', 'id': '7882'})
Traceback (most recent call last):
File "", line 1, in
File "C:\Python27\lib\site-packages\qualysapi\connector.py", line 310, in request
logger.debug('response text =\n%s' % (response))
MemoryError
Thank you,
Mircea
Is it possible to obtain a list of tags using qualysapi?
Eventually, I am looking to create an Asset Tag with a condition of IPRange = X.X.X.X to Y.Y.Y.Y
Tried using Groovy but the documentation doesn't provide information if such a method as hasIPRange() exists.
Tried creating the file.xml as below but the error is simply not verbose enough.
<?xml version="1.0" encoding="UTF-8"?>
<ServiceRequest>
<data>
<Tag>
<name>UnixQualysTag</name>
<ruleType>Asset Search</ruleType>
<TAG_CRITERIA><IP_RANGES><IP_RANGE>X.X.X.X-Y.Y.Y.Y</IP_RANGE></IP_RANGES></TAG_CRITERIA>
<created>2014-02-06T19:14:50Z</created>
<modified>2014-02-06T19:14:50Z</modified>
<color>#FFFFFF</color>
</Tag>
</data>
</ServiceRequest>
XX:qualys vgori$ curl -u "username:password" -H "Content-type: text/xml" -X "POST" --data-binary @- "https://qualysapi.qualys.com/qps/rest/2.0/create/am/tag" < ./file.xml
Error:
<?xml version="1.0" encoding="UTF-8"?>
<ServiceResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://qualysapi.qualys.com/qps/xsd/2.0/am/tag.xsd">
<responseCode>INVALID_REQUEST</responseCode>
<responseErrorDetails>
<errorMessage>modified: An error occurred while validating the element. Please contact your account manager..</errorMessage>
</responseErrorDetails>
</ServiceResponse>
Since Python 2.7 is EOL January 1, 2020 and is currently failing in CI, can it be officially dropped from this project? I would be happy to make a PR.
It would be a nice feature if you can instead of give a file that contains the login info I can parse a string containing this information.
Bulk deactivation is page 45 : https://www.qualys.com/docs/qualys-ca-api-user-guide.pdf
This kind of endpoint:
Is this implemented in qualysapi Python library
Working curl call
curl -u xx:yy -X "POST" -H "X-Requested-With: curl" -H "Content-Type: text/xml" --data-binary @file.xml "https://qualysapi.qualys.com/qps/rest/2.0/search/am/hostasset/"
file.xml
<ServiceRequest>
<preferences>
<limitResults>2</limitResults>
</preferences>
<filters>
<Criteria field="trackingMethod" operator="EQUALS">QAGENT</Criteria>
<Criteria field = "id" operator = "GREATER">0</Criteria>
</filters>
</ServiceRequest>
Executing same call via python qualysapi module
Tried sending api_version="2"
also, but of no use.
from qualysapi import connect
conn = connect(username="xx", password="yy", hostname="qualysapi.qualys.com")
api = "/qps/rest/2.0/search/am/hostasset"
param = '''<ServiceRequest><preferences><limitResults>2</limitResults></preferences><filters><Criteria field="trackingMethod" operator="EQUALS">QAGENT</Criteria><Criteria field = "id" operator = "GREATER">0</Criteria></filters></ServiceRequest>'''
result = conn.request(api,param)
print(result)
output
?xml version="1.0" encoding="UTF-8"?>
<ServiceResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://qualysapi.qualys.com/qps/xsd/1.0/rest/2.0.xsd">
<responseCode>INVALID_API_VERSION</responseCode>
<responseErrorDetails>
<errorMessage>The API version v1.0 specified does not support objects of type 2.0.</errorMessage>
<errorResolution>Verify the versions supported for this API.</errorResolution>
</responseErrorDetails>
</ServiceResponse>
Hi all,
The variable type of the default max_retries
variable in qualysapi.connect() on line 26 is an str
, but this should probably be an int
.
Whenever a time-out occurs, this would otherwise create a TypeError in the underlying urllib3 retry code, due to the incompatibility between strings and integers when performing arithmetic operations.
We fixed this issue in our production code by setting qualysapi.connect(<snip>, max_retries=3)
ourselves when we initialize a new API connection, but this should probably also be fixed upstream in the package itself.
I have a script that will do bulk ticket updates based on a list of IPs and QIDs. I don't see anything that would possibly reference starting a new report. Any ideas on why it is creating a new report and not editing tickets?
#!/usr/bin/python
import xml.etree.ElementTree
import qualysapi
import sys
import os
# Setup connection to QualysGuard API -- only perform once per script.
qgc = qualysapi.connect('config.txt')
comment = raw_input("Enter Comment: ")
reopen = input("Days till reopen (1-720): ")
ip_file = open('ip_addresses.txt', 'r')
ips=ip_file.read().replace('\n', ', ')
ips=ips[:-2]
file = open("qids.txt", "r")
qids=file.read().splitlines()
for qid in qids:
print qid
parameters = {'change_state': 'IGNORED','add_comment': comment, 'reopen_ignored_days': reopen, 'ips': ips,'qids':qid}
response= qgc.request('ticket_edit.php',parameters)
##RESPONCE##
#e = xml.etree.ElementTree.parse('response.xml').getroot()
e=xml.etree.ElementTree.fromstring(response)
#os.system('clear')
changes=e.find("./CHANGES").get('count')
print "Number of Tickets Affected: " + changes
print "Ticket Numbers:"
tickets=e.findall("./CHANGES/TICKET_NUMBER_LIST/TICKET_NUMBER")
for ticket in tickets:
ticket_number = ticket.text
print ticket_number
datetime=e.find("./HEADER/DATETIME").text
file = open("Results/"+datetime+".txt", "w")
file.write("Scope: " + ips + "\n")
file.write("QID: " + str(qid) + "\n")
file.write("Comment: " + comment + "\n")
file.write("Days Till Reopen: " + str(reopen) + "\n")
file.write("Number of Tickets Affected: " + changes + "\n")
file.write("Ticket Numbers: \n")
for ticket in tickets:
ticket_number = ticket.text
file.write(ticket_number +"\n")
file.close()
Regarding https://github.com/paragbaxi/qualysapi/blob/master/setup.cfg#L32 ... isn't it meant to be python_requires
, as per https://packaging.python.org/guides/distributing-packages-using-setuptools/#python-requires ?
Didn't want to burn time with a PR if I'm missing something silly between pip
and others; but I just successfully installed 7.1.0 using Python 3.5, which shouldn't have worked.
Hi all,
It's been a while since I touched Qualys API but I'm getting back into it - back in the day I wrote my own connector in Perl but seeing this Python package exists seems great because it'll save a lot of time.
Despite this, it does not seem to work out of the box for me, i.e. the examples give the ltrim/int error, so there's something wrong with the parameters being passed in to the connector and also when I try to manually check connectivity, i.e. through the python console and doing a 'print a.request('about.php')' - I'm getting a 401 error as the connector tries to hit 'https://qualysapi.qualys.com/msp/about.php' ...
Has anybody tested/fixed the example files in a while? Is there any guidance on changes that have happened which I need to beware of?
Thank you!
Paul
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.