-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbuildexch
executable file
·86 lines (74 loc) · 3.12 KB
/
buildexch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#! /usr/bin/env python
# This file is part of IVRE.
# Copyright 2011 - 2021 Pierre LALET <[email protected]>
#
# IVRE is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# IVRE is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
# License for more details.
#
# You should have received a copy of the GNU General Public License
# along with IVRE. If not, see <http://www.gnu.org/licenses/>.
"""This script fetches Microsoft Exchange build values and creates a
JSON document that matches a build number as reported by OWA a result
such as "Exchange Server 2019 CU6".
This can be used to enrich data reported by IVRE "fake" Nmap script
"http-app".
"""
import os
import re
import sys
from urllib.request import urlopen
# Previous expressions kept just in case...
# VERSION = re.compile(b'<tr>\\\n<td style="text-align: left;">(?:<a [^>]*>)?([^<]*)(?:</a>)?</td>\\\n<td style="text-align: left;">([^<]*)</td>\\\n<td style="text-align: left;">([^<]*)</td>\\\n(?:<td style="text-align: left;">([^<]*)</td>\\\n)?</tr>\\\n')
# VERSION = re.compile(b'<tr>\\\n<td>(?:<a [^>]*>)?([^<]*)(?:</a>)?</td>\\\n<td>([^<]*)</td>\\\n<td>([^<]*)</td>\\\n(?:<td>([^<]*)</td>\\\n)?</tr>\\\n')
VERSION = re.compile(
b"<tr>\\\n<td>(?:<a [^>]*>)?([^<]*)(?:</a>)?</td>\\\n<td[^>]*>([^<]*)</td>\\\n<td[^>]*>([^<]*)</td>\\\n(?:<td[^>]*>([^<]*)</td>\\\n)?</tr>\\\n"
)
def get_versions():
result = {}
uop = urlopen(
"https://docs.microsoft.com/en-us/exchange/new-features/build-numbers-and-release-dates"
)
for m in VERSION.finditer(uop.read()):
key = m.group(3).decode()
if not key:
continue
if key.startswith("15."):
# OWA does not report the last number
key = ".".join(key.split(".", 3)[:3])
value = m.group(1).decode()
if value.startswith("[") and value.endswith("]"):
value = value[1:-1]
result.setdefault(key, set()).add(value)
return result
def update_file(fname):
result = get_versions()
with open(fname) as fdesc:
content = fdesc.read().split("# GENERATED_DATA_EXCHANGE_BUILD\n", 2)
with open(fname, "w") as fdesc:
fdesc.write(content[0])
fdesc.write("# GENERATED_DATA_EXCHANGE_BUILD\n")
for k in sorted(result, key=lambda v: [int(x) for x in v.split(".")]):
v = result[k]
if len(v) != 1:
sys.stderr.write("WARNING: %r has %d values %r\n" % (k, len(v), v))
fdesc.write(f' "{k}": "{" / ".join(sorted(v))}",\n')
fdesc.write(" # GENERATED_DATA_EXCHANGE_BUILD\n")
fdesc.write(content[2])
if __name__ == "__main__":
update_file(
os.path.join(
os.path.dirname(__file__),
os.path.pardir,
"ivre",
"data",
"microsoft",
"exchange.py",
),
)