The Microsoft Office 365 Endpoints V1 program did a good job of outputting the endpoint data into CSV files, but what if you wanted the URLs outputted for use as a PAC file? A Proxy Auto Configuration file tells a proxy how to handle traffic depending on URL, host or IP.
Imagine the program running regularly (ie. via CRON) and updating the proxy PAC file automatically, well thats possible be using the string options in Python.
#!/usr/bin/python3 # original source from https://support.office.com/en-us/article/managing-office-365-endpoints-99cab9d4-ef59-4207-9f2b-3728eb46bf9a?ui=en-US&rs=en-US&ad=US#ID0EACAAA=4._Web_service # modified by geektechstuff import json import os import urllib.request import uuid import smtplib from email_settings import ( smtp_server, port, login_user, login_pass, from_address, to_address ) # helper to call the webservice and parse the response def webApiGet(methodName, instanceName, clientRequestId): ws = "https://endpoints.office.com" requestPath = ws + '/' + methodName + '/' + instanceName + '?clientRequestId=' + clientRequestId request = urllib.request.Request(requestPath) with urllib.request.urlopen(request) as response: return json.loads(response.read().decode()) # path where client ID and latest version number will be stored datapath = '/Users/gary/Downloads/' + '/endpoints_clientid_latestversion.txt' # URL List for Proxy Server, outputs as pac url_list = '/Users/gary/Downloads/365_url_list.pac' # IPv4 List for Firewall, outputs as CSV ip_list = '/Users/gary/Downloads/365_ip_list.csv' # fetch client ID and version if data exists; otherwise create new file if os.path.exists(datapath): with open(datapath, 'r') as fin: clientRequestId = fin.readline().strip() latestVersion = fin.readline().strip() else: clientRequestId = str(uuid.uuid4()) latestVersion = '0000000000' with open(datapath, 'w') as fout: fout.write(clientRequestId + '\n' + latestVersion) # call version method to check the latest version, and pull new data if version number is different version = webApiGet('version', 'Worldwide', clientRequestId) if version['latest'] > latestVersion: print('New version of Office 365 worldwide commercial service instance endpoints detected') # write the new version number to the data file with open(datapath, 'w') as fout: fout.write(clientRequestId + '\n' + version['latest']) # invoke endpoints method to get the new data endpointSets = webApiGet('endpoints', 'Worldwide', clientRequestId) # filter results for Allow and Optimize endpoints, and transform these into tuples with port and category flatUrls = [] for endpointSet in endpointSets: if endpointSet['category'] in ('Optimize', 'Allow'): category = endpointSet['category'] urls = endpointSet['urls'] if 'urls' in endpointSet else [] tcpPorts = endpointSet['tcpPorts'] if 'tcpPorts' in endpointSet else '' udpPorts = endpointSet['udpPorts'] if 'udpPorts' in endpointSet else '' flatUrls.extend([(category, url, tcpPorts, udpPorts) for url in urls]) flatIps = [] for endpointSet in endpointSets: if endpointSet['category'] in ('Optimize', 'Allow'): ips = endpointSet['ips'] if 'ips' in endpointSet else [] category = endpointSet['category'] # IPv4 strings have dots while IPv6 strings have colons ip4s = [ip for ip in ips if '.' in ip] tcpPorts = endpointSet['tcpPorts'] if 'tcpPorts' in endpointSet else '' udpPorts = endpointSet['udpPorts'] if 'udpPorts' in endpointSet else '' flatIps.extend([(category, ip, tcpPorts, udpPorts) for ip in ip4s]) print('IPv4 Firewall IP Address Ranges') print(','.join(sorted(set([ip for (category, ip, tcpPorts, udpPorts) in flatIps])))) # outputs the details to the ip_list variable with open(ip_list, 'w') as data_write: data_write.write(','.join(sorted(set([ip for (category, ip, tcpPorts, udpPorts) in flatIps])))) print('URLs for Proxy Server') print('\n'.join(sorted(set([url for (category, url, tcpPorts, udpPorts) in flatUrls])))) # outputs the details to the url_list variable with open(url_list, 'w') as data_write: data_write.write('function FindProxyForURL(url, host) { \n') beg_line = ' if (shExpMatch(host, ' end_line = ')\n' URL_edited = (sorted(set([ip for (category, ip, tcpPorts, udpPorts) in flatUrls]))) for ip in URL_edited: URL2 = beg_line+ip+end_line print(URL2) data_write.write(URL2) data_write.write('{\n'+' return "DIRECT";'+'\n}') # smtp aka email settings smtpObj = smtplib.SMTP_SSL(smtp_server, port) smtpObj.login(login_user, login_pass) smtpObj.sendmail(from_address, to_address, 'From: from_address\nSubject: 365 EndPoints Updated\n\n') smtpObj.quit() else: print('Office 365 worldwide commercial service, no updates detected.')
The above should now output the Microsoft Office 365 Endpoint URLs into a (basic – it’s my first attempt) PAC file.
You must be logged in to post a comment.