debian_advisory.py 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546
  1. #!/usr/bin/python3
  2. ###############################################################################
  3. ##
  4. ## Functions for downloading and parsing Debian Security Advisories (DSAs)
  5. ##
  6. ###############################################################################
  7. import re
  8. import datetime
  9. from html.parser import HTMLParser
  10. from bs4 import BeautifulSoup
  11. from bs4 import NavigableString
  12. from pymongo import MongoClient
  13. import urllib.request
  14. import logging, sys
  15. logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
  16. #Testing global variables
  17. config = dict([('dsa_base_url','https://www.debian.org/security/')])
  18. state = dict([('next_adv',3496)])
  19. dsatable = dict()
  20. # Track renamed packages here, easy but manual. We should look into ways
  21. # to automate this
  22. def unifySrcName(name):
  23. ## TODO: it should map to the most recent version, not unversioned
  24. ## TODO: we can partially automate this..
  25. ## -> make all lower-case
  26. ## -> replace -X.Y version numbers by highest encounter(?)
  27. ## -> handle special cases like xfree86
  28. # Have to go over this again!
  29. # Maybe have a file with all these things??
  30. newname = name
  31. if re.compile("mozilla-firefox").match(name):
  32. newname = "firefox-esr"
  33. elif re.compile("iceweasel").match(name):
  34. newname = "firefox-esr"
  35. elif re.compile("mozilla").match(name):
  36. newname = "firefox-esr"
  37. elif re.compile("mozilla-thunderbird").match(name):
  38. newname = "icedove"
  39. elif re.compile("thunderbird").match(name):
  40. newname = "icedove"
  41. elif re.compile("squid\d").match(name):
  42. newname = "squid3"
  43. elif re.compile("squid").match(name):
  44. newname = "squid3"
  45. elif re.compile("tk8.*").match(name):
  46. newname = "tk8"
  47. elif re.compile("xpdf-i").match(name):
  48. newname = "xpdf"
  49. elif re.compile("zope*").match(name):
  50. newname = "zope-common"
  51. elif re.compile("librmagick-ruby").match(name):
  52. newname = "ruby-rmagick"
  53. elif re.compile("libcompass-ruby").match(name):
  54. newname = "ruby-compass"
  55. elif re.compile("bio-ruby").match(name):
  56. newname = "ruby-bio"
  57. elif re.compile("request-tracker*").match(name):
  58. newname = "request-tracker4"
  59. elif re.compile("perl-5.005").match(name):
  60. newname = "perl"
  61. elif re.compile("openldap*").match(name):
  62. newname = "openldap"
  63. elif re.compile("openoffice*").match(name):
  64. newname = "libreoffice"
  65. elif re.compile("nsd3").match(name):
  66. newname = "nsd"
  67. elif re.compile("network-manager/network-manager-applet").match(name):
  68. newname = "network-manager"
  69. elif re.compile("nagios3").match(name):
  70. newname = "nagios"
  71. elif re.compile("nagios2").match(name):
  72. newname = "nagios"
  73. elif re.compile("^mysql-\d*").match(name):
  74. newname = "mysql-transitional"
  75. elif re.compile("linux-2.6*").match(name):
  76. newname = "linux"
  77. elif re.compile("linux-kernel-alpha").match(name):
  78. newname = "linux"
  79. elif re.compile("linux-kernel-i386").match(name):
  80. newname = "linux"
  81. elif re.compile("libmusicbrainz*").match(name):
  82. newname = "libmusicbrainz"
  83. elif re.compile("libgtop1").match(name):
  84. newname = "libgtop2"
  85. elif re.compile("libgd1").match(name):
  86. newname = "libgd2"
  87. elif re.compile("libast*").match(name):
  88. newname = "libast2"
  89. elif re.compile("libmozjs0d").match(name):
  90. newname = "libast"
  91. elif re.compile("^kernel-source*").match(name):
  92. newname = "linux"
  93. elif re.compile("^kernel-patch*").match(name):
  94. newname = "linux"
  95. # elif re.compile("kernel").match(name):
  96. # newname = "linux-2.4"
  97. elif re.compile("^kernel-source-2.4.*").match(name):
  98. newname = "linux"
  99. elif re.compile("^kernel-image-2.2.*").match(name):
  100. newname = "linux"
  101. elif re.compile("^kernel-image*").match(name):
  102. newname = "linux"
  103. elif re.compile("^kernel-patch-*").match(name):
  104. newname = "linux"
  105. elif re.compile("kernel-patch-benh").match(name):
  106. newname = "linux"
  107. elif re.compile("kernel-patch-vserver").match(name):
  108. newname = "linux"
  109. elif re.compile("^kernel-source*").match(name):
  110. newname = "linux"
  111. elif re.compile("gnutls*").match(name):
  112. newname = "gnutls28"
  113. elif re.compile("gallery2").match(name):
  114. newname = "gallery"
  115. elif re.compile("firebird*").match(name):
  116. newname = "firebird3.0"
  117. elif re.compile("fltk1.1").match(name):
  118. newname = "fltk1.3"
  119. elif re.compile("fox1.4").match(name):
  120. newname = "fox1.6"
  121. elif re.compile("exim-tls").match(name):
  122. newname = "exim4"
  123. elif re.compile("epic4").match(name):
  124. newname = "epic"
  125. elif re.compile("drupal\d").match(name):
  126. newname = "drupal7"
  127. elif re.compile("dhcp").match(name):
  128. newname = "dhcpcd5"
  129. elif re.compile("cyrus-sasl").match(name):
  130. newname = "cyrus-sasl2"
  131. elif re.compile("^cyrus-imapd.*").match(name):
  132. newname = "cyrus-imapd"
  133. elif re.compile("^kolab-cyrus-imapd.*").match(name):
  134. newname = "cyrus-imapd"
  135. elif re.compile("cfengine").match(name):
  136. newname = "cfengine2"
  137. elif re.compile("bind").match(name):
  138. newname = "bind9"
  139. elif re.compile("apache").match(name):
  140. newname = "apache2"
  141. elif re.compile("horde\d").match(name):
  142. newname = "php-horde"
  143. elif re.compile("mediawiki*").match(name):
  144. newname = "mediawiki"
  145. elif re.compile("ffmpeg-debian").match(name):
  146. newname = "ffmpeg"
  147. elif re.compile("xserver-xorg").match(name):
  148. newname = "xorg-server"
  149. elif re.compile("xfree86-1").match(name):
  150. newname = "xorg-server"
  151. elif re.compile("xfree86v3").match(name):
  152. newname = "xorg-server"
  153. elif re.compile("xfree86").match(name):
  154. newname = "xorg-server"
  155. elif re.compile("xfree86").match(name):
  156. newname = "xorg-server"
  157. elif re.compile("xorg").match(name):
  158. newname = "xorg-server"
  159. elif re.compile("typo3").match(name):
  160. newname = "typo3-src"
  161. elif re.compile("lvm10").match(name):
  162. newname = "lvm2"
  163. elif re.compile("cupsys").match(name):
  164. newname = "cups"
  165. elif re.compile("ethereal").match(name):
  166. newname = "wireshark"
  167. elif re.compile("libboost1.42").match(name):
  168. newname = "libboost"
  169. elif re.compile("cinelerra-cv").match(name):
  170. newname = "cinelerra"
  171. elif re.compile("mplayer-dmo").match(name):
  172. newname = "mplayer"
  173. elif re.compile("libcap").match(name):
  174. newname = "libgda2"
  175. elif re.compile("xkb-data-legacy").match(name):
  176. newname = "xkeyboard-config"
  177. elif re.compile("boost-defaults").match(name):
  178. newname = "boost"
  179. elif re.compile("xen-3").match(name):
  180. newname = "xen"
  181. elif re.compile("xen-utils").match(name):
  182. newname = "xen"
  183. elif re.compile("kde-icons-gorilla").match(name):
  184. newname = "kde-icons-korilla"
  185. elif re.compile("libcgi-application-extra-plugin-bundle-perl").match(name):
  186. newname = "libcgi-application-plugins-perl"
  187. elif re.compile("^openssl*").match(name):
  188. newname = "openssl"
  189. elif re.compile("^tomcat\d").match(name):
  190. newname = "tomcat8"
  191. elif re.compile("^tomcat\d.\d$").match(name):
  192. newname = "tomcat8"
  193. elif re.compile("^libgda\d").match(name):
  194. newname = "libgda"
  195. elif re.compile("^readline\d").match(name):
  196. newname = "readline6"
  197. elif re.compile("^libwnck\d").match(name):
  198. newname = "libwnck"
  199. elif re.compile("^xerces-c\d").match(name):
  200. newname = "xerces-c"
  201. elif re.compile("kde-icons-gorilla").match(name):
  202. newname = "kde-icons-korilla"
  203. elif re.compile("kde4libs").match(name):
  204. newname = "kdelibs"
  205. elif re.compile("libcgi-application-extra-plugin-bundle-perl").match(name):
  206. newname = "libcgi-application-plugins-perl"
  207. elif re.compile("^libticalcs\d").match(name):
  208. newname = "libticals"
  209. elif re.compile("^libtifiles\d").match(name):
  210. newname = "libtifiles"
  211. elif re.compile("^db\d.\d$").match(name):
  212. newname = "db4.8"
  213. elif re.compile("^gcc-.*").match(name):
  214. newname = "gcc"
  215. elif re.compile("^automake\d+.*").match(name):
  216. newname = "automake"
  217. elif re.compile("^sun-java\d").match(name):
  218. newname = "sun-java6"
  219. elif re.compile("^open-jdk\d").match(name):
  220. newname = "open-jdk7"
  221. elif re.compile("^mbrola-es\d").match(name):
  222. newname = "mbrola-es"
  223. elif re.compile("^mgltools-.*").match(name):
  224. newname = "mgltools"
  225. elif re.compile("^coin\d$").match(name):
  226. newname = "coin"
  227. elif re.compile("^adobereader-\.*").match(name):
  228. newname = "adobereader"
  229. elif re.compile("^picon-\.*").match(name):
  230. newname = "picon"
  231. elif re.compile("^nvidia-graphics-drivers\.*").match(name):
  232. newname = "nvidia-graphics-drivers"
  233. elif re.compile("^boost\d\.\d\d").match(name):
  234. newname = "boost"
  235. elif re.compile("^llvm-\d.\d").match(name):
  236. newname = "llvm"
  237. elif re.compile("^octave\d.\d").match(name):
  238. newname = "octave"
  239. elif re.compile("^libjibx\d.\d-java").match(name):
  240. newname = "libjibx-java"
  241. elif re.compile("^emacs2\d").match(name):
  242. newname = "emacs2"
  243. elif re.compile("^emacs2\d-non-dfsg").match(name):
  244. newname = "emacs2"
  245. elif re.compile("^libupnp\d").match(name):
  246. newname = "libupnp"
  247. elif re.compile("^python\d.\d").match(name):
  248. newname = "python3.5"
  249. elif re.compile("^python\d").match(name):
  250. newname = "python3.5"
  251. elif re.compile("^postgresql-\d*").match(name):
  252. newname = "postgresql-9.6"
  253. elif re.compile("^ruby\d.\d").match(name):
  254. newname = "ruby2.3"
  255. elif re.compile("^ruby").match(name):
  256. newname = "ruby2.3"
  257. #elif re.compile("^php\d").match(name):
  258. # newname = "php7.0"
  259. #elif re.compile("^PHP\d").match(name):
  260. # newname = "php7.0"
  261. #elif re.compile("^openjdk*").match(name):
  262. # newname = "openjdk-8"
  263. elif re.compile("^mariadb-10.*").match(name):
  264. newname = "mariadb-10.1"
  265. elif re.compile("^ruby-actionpack*").match(name):
  266. newname = "rails"
  267. elif re.compile("^ruby-activerecord*").match(name):
  268. newname = "rails"
  269. elif re.compile("^librack-ruby").match(name):
  270. newname = "ruby-rack"
  271. elif re.compile("^libopenssl-ruby").match(name):
  272. newname = "ruby-defaults"
  273. elif re.compile("krb4").match(name):
  274. newname = "krb5"
  275. elif re.compile("ssh-krb5").match(name):
  276. newname = "openssh"
  277. elif re.compile("ssh").match(name):
  278. newname = "openssh"
  279. elif re.compile("qemu-kvm").match(name):
  280. newname = "qemu"
  281. elif re.compile("kvm").match(name):
  282. newname = "qemu"
  283. elif re.compile("phpbb2").match(name):
  284. newname = "phpbb3"
  285. elif re.compile("libpng").match(name):
  286. newname = "libpng1.6"
  287. elif re.compile("eglibc").match(name):
  288. newname = "glibc"
  289. elif re.compile("gnupg").match(name):
  290. newname = "gnupg2"
  291. elif re.compile("xine-lib*").match(name):
  292. newname = "xine-lib-1.2"
  293. elif re.compile("kfreebsd-\d*").match(name):
  294. newname = "kfreebsd-10"
  295. elif re.compile("pdfkit*").match(name):
  296. newname = "pdfkit"
  297. elif re.compile("gforge").match(name):
  298. newname = "fusionforge"
  299. return newname
  300. ###############################################################################
  301. ## Should this advisory be skipped?+
  302. def blacklistedDSA(dsa_id):
  303. dsa_blacklist = ["DSA-1975", "DSA-2360", "DSA-2134", "DSA-3043", "DSA-3156"]
  304. if dsa_id in dsa_blacklist:
  305. return True
  306. else:
  307. return False
  308. ###############################################################################
  309. ## Static map to correct errors in DSAs
  310. ## Return fixed list of CVE IDs or 0 to skip DSA
  311. ## This code is still experimental
  312. def fixDSAquirks(dsa_id, dsa_state):
  313. new_names = dsa_state[0]
  314. new_date = dsa_state[1]
  315. new_cves = dsa_state[2]
  316. print('Are you here??')
  317. if dsa_id == 85:
  318. new_cves = ["CVE-2001-1562", "LOCAL-03/04/05", "LOCAL-08/24/08"]
  319. elif dsa_id == 745:
  320. newcves = ["CVE-2005-1921", "CVE-2005-2106", "CVE-2005-1921"]
  321. elif dsa_id == 1095:
  322. new_cves = ["CVE-2006-0747", "CVE-2006-1861", "CVE-2006-2661"]
  323. elif dsa_id == 1284:
  324. new_cves = ["CVE-2007-1320", "CVE-2007-1321", "CVE-2007-1322", "CVE-2007-2893", "CVE-2007-1366"]
  325. elif dsa_id == 1502:
  326. new_cves = ["CVE-2007-2821", "CVE-2007-3238", "CVE-2008-0193", "CVE-2008-0194"]
  327. elif dsa_id == 1706:
  328. new_cves = ["CVE-2009-0135", "CVE-2009-0136"]
  329. elif dsa_id == 1757:
  330. new_cves = ["CVE-2007-2383", "CVE-2008-7220", "CVE-2009-1208"]
  331. elif dsa_id == 1896:
  332. new_cves = ["CVE-2009-3474", "CVE-2009-3475", "CVE-2009-3476"]
  333. elif dsa_id == 1931:
  334. new_cves = ["CVE-2009-0689", "CVE-2009-2463"]
  335. elif dsa_id == 1989:
  336. new_cves = ["CVE-2010-0789"]
  337. elif dsa_id == 1941:
  338. new_cves = ["CVE-2009-0755", "CVE-2009-3903", "CVE-2009-3904", "CVE-2009-3905", "CVE-2009-3606", "CVE-2009-3607", "CVE-2009-3608", "CVE-2009-3909", "CVE-2009-3938"]
  339. elif dsa_id == 2004:
  340. new_cves = ["CVE-2010-0787", "CVE-2010-0547"]
  341. elif dsa_id == 2008:
  342. new_cves = ["LOCAL-02/23/10", "LOCAL-02/23/10", "LOCAL-02/23/10", "LOCAL-02/23/10"]
  343. elif dsa_id == 2043:
  344. new_cves = ["CVE-2010-2062"]
  345. elif dsa_id == 2044:
  346. new_cves = ["CVE-2010-2062"]
  347. elif dsa_id == 2056:
  348. new_cves = ["CVE-2010-2155", "CVE-2009-4882"]
  349. elif dsa_id == 2092:
  350. new_cves = ["CVE-2010-1625", "CVE-2010-1448", "CVE-2009-4497"]
  351. elif dsa_id == 2098:
  352. new_cves = ["CVE-2010-3659", "CVE-2010-3660", "CVE-2010-3661", "CVE-2010-3662", "CVE-2010-3663", "CVE-2010-3664", "CVE-2010-3665", "CVE-2010-3666", "CVE-2010-3667", "CVE-2010-3668", "CVE-2010-3669", "CVE-2010-3670", "CVE-2010-3671", "CVE-2010-3672", "CVE-2010-3673", "CVE-2010-3674"]
  353. elif dsa_id == 2103:
  354. new_cves = ["CVE-2010-3076"]
  355. elif dsa_id == 2218:
  356. new_cves = ["CVE-2011-1684"]
  357. elif dsa_id == 2229:
  358. new_cves = ["CVE-2005-4494", "CVE-2006-0517", "CVE-2006-0518", "CVE-2006-0519", "CVE-2006-0625", "CVE-2006-0626", "CVE-2006-1295", "CVE-2006-1702", "CVE-2007-4525", "CVE-2008-5812", "CVE-2008-5813", "CVE-2009-3041"]
  359. elif dsa_id == 2261:
  360. new_cves = ["CVE-2009-4078", "CVE-2009-4079", "CVE-2009-4059", "LOCAL-12/30/10", "LOCAL-12/30/10"]
  361. elif dsa_id == 2262:
  362. new_cves = ["LOCAL-03/01/11", "LOCAL-03/01/11", "LOCAL-03/01/11", "LOCAL-03/01/11", "LOCAL-05/18/11", "LOCAL-05/18/11"]
  363. elif dsa_id == 2286:
  364. new_names = ["phpmyadmin"]
  365. print(str(dsa_id) + 'whatsapp??')
  366. elif dsa_id == 1977:
  367. new_names = ["python3.5"]
  368. elif (dsa_id == 47 or dsa_id == 479 or dsa_id == 480 or dsa_id == 482 or dsa_id == 489 or dsa_id == 491 or dsa_id == 495):
  369. new_names = ["linux"]
  370. print('Substitution successful')
  371. elif dsa_id == 2289:
  372. new_cves = ["LOCAL-07/27/11", "LOCAL-07/27/11", "LOCAL-07/27/11", "LOCAL-07/27/11", "LOCAL-07/27/11", "LOCAL-07/27/11", "LOCAL-07/27/11", "LOCAL-07/27/11", "LOCAL-07/27/11", "LOCAL-07/27/11", "LOCAL-07/27/11", "LOCAL-07/27/11"]
  373. return (new_names, new_date, new_cves)
  374. ###############################################################################
  375. ## Fetch DSA from debian archive. Can't use tracker since dates are missing.
  376. ## DSA started counting in November 2000. We'll simply bruteforce which DSA
  377. ## was in which year and start in 2000 til current.
  378. def fetchDSA(dsa_id, base_url):
  379. year = 2000
  380. now = datetime.datetime.now()
  381. current_year = now.year
  382. logging.info('Fetching DSA-%d records\n', dsa_id)
  383. if dsa_id >= 3751:
  384. year = 2017
  385. elif dsa_id >= 3431:
  386. year = 2016
  387. elif dsa_id >= 3118:
  388. year = 2015
  389. elif dsa_id >= 2832:
  390. year = 2014
  391. elif dsa_id >= 2597:
  392. year = 2013
  393. elif dsa_id >= 2377:
  394. year = 2012
  395. elif dsa_id >= 2140:
  396. year = 2011
  397. elif dsa_id >= 1965:
  398. year = 2010
  399. elif dsa_id >= 1694:
  400. year = 2009
  401. elif dsa_id >= 1443:
  402. year = 2008
  403. elif dsa_id >= 1245:
  404. year = 2007
  405. elif dsa_id >= 929:
  406. year = 2006
  407. elif dsa_id >= 622:
  408. year = 2005
  409. elif dsa_id >= 406:
  410. year = 2004
  411. elif dsa_id >= 220:
  412. year = 2003
  413. elif dsa_id >= 96:
  414. year = 2002
  415. elif dsa_id >= 11:
  416. year = 2001
  417. dsa_id2string = '%03d' % dsa_id
  418. flag = True
  419. while flag:
  420. try:
  421. flag = False
  422. logging.info('Opening url: ' + base_url + str(year) + '/dsa-' + dsa_id2string + '\n')
  423. req = urllib.request.urlopen(base_url + str(year) + '/dsa-' + dsa_id2string)
  424. charset = req.info().get_content_charset()
  425. if charset is None:
  426. charset = 'utf-8'
  427. dsa = req.read().decode(charset)
  428. return dsa
  429. except urllib.error.HTTPError as err:
  430. if year < current_year:
  431. year += 1
  432. flag = True
  433. else:
  434. dsa = ''
  435. return dsa
  436. ###############################################################################
  437. ## Try to find new DSAs by iteration, return table of DSAs to process
  438. def checkDSAs(state, config):
  439. next_dsa = int(state['next_adv'])
  440. #state implemented as dictionary
  441. base_url = config['URL']['dsa_base_url']
  442. logging.info('Checking for new DSAs.. \n')
  443. if next_dsa < int(config['DSA']['first_dsa']):
  444. logging.debug('Cache was deleted, starting at DSA ' + str(next_dsa) + '\n')
  445. next_dsa = int(config['DSA']['first_dsa'])
  446. next_dsa2string = '%03d' % next_dsa
  447. if blacklistedDSA('DSA-' + next_dsa2string):
  448. next_dsa += 1
  449. #print(config)
  450. dsa = fetchDSA(next_dsa, base_url)
  451. while dsa != '':
  452. logging.debug('Got DSA-' + str(next_dsa) + '\n')
  453. soup = BeautifulSoup(dsa,'html.parser')
  454. #crop the DSA from unecessary weight
  455. dsa = soup.find(id="content")
  456. if dsa == '':
  457. raise NameError('html file format unexpected')
  458. dsatable[next_dsa] = str(dsa)
  459. next_dsa += 1
  460. if blacklistedDSA('DSA-' + str(next_dsa)):
  461. next_dsa += 1
  462. dsa = fetchDSA(next_dsa, base_url)
  463. state['next_adv'] = next_dsa
  464. return dsatable
  465. ###############################################################################
  466. ## Parse DSA html data and return array
  467. ## (src-pkg-name date (CVE-id)*)
  468. def parseDSAhtml(dsa):
  469. dsa_date = []
  470. dsa_names = []
  471. dsa_CVEs = []
  472. # Date Reported -> dsa_date
  473. soup = BeautifulSoup(dsa, 'html.parser')
  474. tmp = soup.find("dt",string=re.compile(".*Date Repo.*:"))
  475. tmp = str(tmp.find_next().contents[0])
  476. # dsa_date = tmp.split()
  477. # date in datetime python format
  478. dsa_date = datetime.datetime.strptime(tmp, "%d %b %Y")
  479. if dsa_date == []:
  480. print('Unable to extract date. Raising exception...')
  481. raise NameError('DSA parsing problem')
  482. # Affected Packages -> dsa_names
  483. #print(dsa)
  484. tmp = soup.find("dt",string=re.compile("Affected Packages:"))
  485. tmp = tmp.find_next().contents
  486. #Need to check with multiple vulnerable packages
  487. for i in tmp:
  488. if (not isinstance(i, NavigableString)) and i.has_attr('href'):
  489. #greedy 'and' operation assumed
  490. unified = unifySrcName(i.string)
  491. dsa_names.append(unified)
  492. pass
  493. if dsa_names == []:
  494. print('Unable to find src package in DSA. unnamed package...')
  495. dsa_names.append('unnamed')
  496. print('Unnamed dsa:' + str(dsa) + '\n')
  497. # Security database references (CVEs) -> dsa_CVEs
  498. tmp = soup.find("dt", string=re.compile("Security database references:"))
  499. tmp = tmp.find_next().descendants
  500. for i in tmp:
  501. if (not isinstance(i, NavigableString)) and i.has_attr('href'):
  502. #don't count bug database
  503. if not re.compile("^Bug*").match(i.string):
  504. dsa_CVEs.append(i.string)
  505. return (dsa_names, dsa_date, dsa_CVEs)
  506. #dsa = fetchDSA(3200,'https://www.debian.org/security/')
  507. #dsatable = checkDSAs(state,config)
  508. #print(dsatable[3701])
  509. #parseDSAhtml(dsatable[3498])
  510. #checkDSAs(state,config)