Giter Site home page Giter Site logo

qualysapi's People

Contributors

alles-klar avatar batbast avatar bml0aglu avatar deanwpa avatar drts01 avatar goggin avatar kilo59 avatar lamusmaser avatar lingfish avatar mariang avatar martinspielmann avatar paragbaxi avatar qmontal avatar ramspoluri avatar red5d avatar schercav avatar sjames-au avatar teranpeterson avatar trolldbois avatar uovobw avatar yestinj avatar zany2dmax avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

qualysapi's Issues

launching scan with v2 from Qualys community

Hi Parag,

got one small issues with launching scan using V2 API. My code:

usr_account = 'Name of asset group'

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

The usage of print() statements?!

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.

API version str(2) creates qps url

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/
...

chardet MemoryError

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?

Need a collaborator

Hi folks, I will not be able to give this package the TLC it deserves. I'm looking for someone to takeover. Any volunteers?

notScannedSince function will only pull the first page

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.

Error installing qualysapi on Amazon Linux 2

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.

http method is incompatible with request

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?

Drop support for Python 2.x

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.

adding certview support

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.

Failure to execute module lanzar_scan

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

Use the defusedxml package for all xml parsing. See bandit docs:

https://bandit.readthedocs.io/en/latest/blacklists/blacklist_imports.html#b405-import-xml-etree

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 to pull data from. See qualys docs for a list of APIs

api_url = "/api/2.0/fo/scan/?action=Launch"

Options for API request. See qualys docs for a list of all options

Create a connection object used to pull data from Qualys

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.

Encode User Creds

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

How to get a list of tags?

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>

Can't list scheduled scans

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/

Identifying "nextURL" in Qualys responses

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

Mishandling of http request content bytes in Python 3

response = str(request.content)

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.'

Error if I provide Qualys URL with schema

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.

MemoryError when downloading big reports

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

connect() doesn't properly pull the correct API url

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.

/get/am/tag/xxxxxx not working

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

Changelog updates?

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!

Is this official from Qualys?

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.

Connector broken?

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

http_method not transmit after identification

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.

User Credential

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.

Downloading an zipped HTML report

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'

Incorrect default type of `max_retries` value in qualysapi.connect() function

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.
image

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.
image

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.

Python 3 support?

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.

The API version v1.0 specified does not support objects of type 2.0.

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>

Can't fully configure with code.

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.

Revisit python3 porting plans

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.

'module' object has no attribute 'connect'

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.

Ticket update script is causing a new report to run.

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()

Install on Mac OSX issue

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

include "libxml/xmlversion.h"

     ^

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

Adding new IPs to Qualys

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?

Integrated with web applications for large systems

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:

  • progressively changing named keyword arguments to args/*kwargs with default kwargs.pop(default)
  • adding credential injection to the connect method from util rather than assuming a configuration file
  • adding an API cache (redis) layer that can be specified in the config or connect argument. This layer effectively just builds keys based on api parameters and endpoints. This basically makes a responsive qualys interface that doesn't hammer qualys to death and possibly saturate your account limits. In addition, qualys often requires multiple api calls in order to return information to map report names to ids using the query apis. Especially for automation this is a bit of a drag.
  • adding stream handling for large results. In stream handling mode, the requests API is configured to stream the raw results to an lxml parsing iterator which the calling code can then implement and begin operating on results without waiting.
  • byte unicode to utf-8 encoded unicode.
  • python3 support

Lemme know.

Install and build fail with python2, pip install qualysapi only works with python3

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

Python 2 parse module import error

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.

qualys-stacktrace

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.