Helpviewer/VirusTotalApi.py

changeset 978
11f8adbcac97
child 979
0ae0c8852d31
equal deleted inserted replaced
977:7a523bd4b00d 978:11f8adbcac97
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2011 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing the <a href="http://www.virustotal.com">VirusTotal</a> API class.
8 """
9
10 import json
11
12 from PyQt4.QtCore import QObject, QUrl, QByteArray, QCoreApplication, QThread
13 from PyQt4.QtNetwork import QNetworkRequest, QNetworkReply, QNetworkAccessManager
14
15 import Helpviewer.HelpWindow
16
17 import Preferences
18
19 class VirusTotalAPI(QObject):
20 """
21 Class implementing the <a href="http://www.virustotal.com">VirusTotal</a> API.
22 """
23 TestServiceKeyScanID = \
24 "4feed2c2e352f105f6188efd1d5a558f24aee6971bdf96d5fdb19c197d6d3fad"
25
26 ServiceResult_RequestLimitReached = -2
27 ServiceResult_InvalidServiceKey = -1
28 ServiceResult_ItemNotPresent = 0
29 ServiceResult_ItemPresent = 1
30
31 GetFileReportPattern = "{0}://www.virustotal.com/api/get_file_report.json"
32 ScanUrlPattern = "{0}://www.virustotal.com/api/scan_url.json"
33 GetUrlReportPattern = "{0}://www.virustotal.com/api/get_url_report.json"
34
35 ReportUrlScanPagePattern = "http://www.virustotal.com/url-scan/report.html?id={0}"
36 ReportFileScanPagePattern = "http://www.virustotal.com/file-scan/report.html?id={0}"
37
38 SearchUrl = "http://www.virustotal.com/search.html"
39
40 def __init__(self, parent=None):
41 """
42 Constructor
43
44 @param parent reference to the parent object (QObject)
45 """
46 QObject.__init__(self, parent)
47
48 self.__loadSettings()
49
50 def __loadSettings(self):
51 """
52 Private method to load the settings.
53 """
54 if Preferences.getHelp("VirusTotalSecure"):
55 protocol = "https"
56 else:
57 protocol = "http"
58 self.GetFileReportUrl = self.GetFileReportPattern.format(protocol)
59 self.ScanUrlUrl = self.ScanUrlPattern.format(protocol)
60 self.GetUrlReportUrl = self.GetUrlReportPattern.format(protocol)
61
62 self.errorMessages = {
63 -2: self.trUtf8("Request limit has been reached."),
64 -1: self.trUtf8("Invalid key given."),
65 0: self.trUtf8("Requested item is not present.")
66 }
67
68 def checkServiceKeyValidity(self, key, protocol=""):
69 """
70 Public method to check the validity of the given service key.
71
72 @param key service key (string)
73 @param protocol protocol used to access VirusTotal (string)
74 @return flag indicating validity (boolean) and an error message in
75 case of a network error (string)
76 """
77 if protocol == "":
78 urlStr = self.GetFileReportUrl
79 else:
80 urlStr = self.GetFileReportPattern.format(protocol)
81 request = QNetworkRequest(QUrl(urlStr))
82 request.setHeader(QNetworkRequest.ContentTypeHeader,
83 "application/x-www-form-urlencoded")
84 params = QByteArray("key={0}&resource={1}".format(
85 key, self.TestServiceKeyScanID))
86
87 nam = Helpviewer.HelpWindow.HelpWindow.networkAccessManager()
88 reply = nam.post(request, params)
89 while not reply.isFinished():
90 QCoreApplication.processEvents()
91 QThread.msleep(100)
92 if QCoreApplication.closingDown():
93 reply.abort()
94 QCoreApplication.processEvents()
95 if reply.error() == QNetworkReply.NoError:
96 result = json.loads(str(reply.readAll(), "utf-8"))
97 if result["result"] != self.ServiceResult_InvalidServiceKey:
98 return True, ""
99 else:
100 return False, ""
101
102 return False, reply.errorString()
103
104 def submitUrl(self, url):
105 """
106 Public method to submit an URL to be scanned.
107
108 @param url url to be scanned (QUrl)
109 @return flag indicating success (boolean) and the scan ID (string)
110 """
111 request = QNetworkRequest(QUrl(self.ScanUrlUrl))
112 request.setHeader(QNetworkRequest.ContentTypeHeader,
113 "application/x-www-form-urlencoded")
114 params = QByteArray(
115 "key={0}&url=".format(Preferences.getHelp("VirusTotalServiceKey")))\
116 .append(QUrl.toPercentEncoding(url.toString()))
117
118 nam = Helpviewer.HelpWindow.HelpWindow.networkAccessManager()
119 reply = nam.post(request, params)
120 while not reply.isFinished():
121 QCoreApplication.processEvents()
122 QThread.msleep(100)
123 if QCoreApplication.closingDown():
124 reply.abort()
125 QCoreApplication.processEvents()
126 if reply.error() == QNetworkReply.NoError:
127 result = json.loads(str(reply.readAll(), "utf-8"))
128 if result["result"] == self.ServiceResult_ItemPresent:
129 return True, result["scan_id"]
130 else:
131 return False, self.errorMessages[result["result"]]
132
133 return False, reply.errorString()
134
135 def getUrlScanReportUrl(self, scanId):
136 """
137 Public method to get the report URL for a URL scan.
138
139 @param scanId ID of the scan to get the report URL for (string)
140 @return URL scan report URL (string)
141 """
142 return self.ReportUrlScanPagePattern.format(scanId)
143
144 def getFileScanReportUrl(self, scanId):
145 """
146 Public method to get the report URL for a file scan.
147
148 @param scanId ID of the scan to get the report URL for (string)
149 @return file scan report URL (string)
150 """
151 fileScanPageUrl = "" # default value
152
153 request = QNetworkRequest(QUrl(self.GetUrlReportUrl))
154 request.setHeader(QNetworkRequest.ContentTypeHeader,
155 "application/x-www-form-urlencoded")
156 params = QByteArray("key={0}&resource={1}".format(
157 Preferences.getHelp("VirusTotalServiceKey"), scanId))
158
159 nam = Helpviewer.HelpWindow.HelpWindow.networkAccessManager()
160 reply = nam.post(request, params)
161 while not reply.isFinished():
162 QCoreApplication.processEvents()
163 QThread.msleep(100)
164 if QCoreApplication.closingDown():
165 reply.abort()
166 QCoreApplication.processEvents()
167 if reply.error() == QNetworkReply.NoError:
168 result = json.loads(str(reply.readAll(), "utf-8"))
169 if "file-report" in result:
170 fileScanPageUrl = self.ReportFileScanPagePattern.format(
171 result["file-report"])
172
173 return fileScanPageUrl
174
175 @classmethod
176 def getSearchRequestData(cls, term):
177 """
178
179 """
180 request = QNetworkRequest(QUrl(cls.SearchUrl))
181 request.setHeader(QNetworkRequest.ContentTypeHeader,
182 "application/x-www-form-urlencoded")
183 op = QNetworkAccessManager.PostOperation
184 params = QByteArray("chain=").append(QUrl.toPercentEncoding(term))
185
186 return (request, op, params)

eric ide

mercurial