def add_web_service(): """ The AddWebServiceForm posts to this page. Add a Web service to the database, and redirect back to the configure page. """ if app.config['ALLOW_CONFIG']: if 'file' not in request.files: return redirect('configure') file = request.files['file'] if file.filename == '': return redirect('configure') team_id = request.form['team_name'] team_choices = [str(team['team_id']) for team in db.execute_db_query('select team_id from team')] if not team_id in team_choices: return redirect('configure') service_name = request.form['service_name'] service_url = urlparse(request.form['service_url']) service_type_name = service_url.scheme service_connection = service_url.netloc filename = secure_filename(file.filename) file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename)) service_request = service_url.path service_expected_result = filename service_type_id = db.execute_db_query('select service_type_id from service_type where service_type_name = ?', [service_type_name])[0]['service_type_id'] db.execute_db_query('INSERT INTO service(service_type_id, team_id, service_name, service_connection, service_request, service_expected_result) VALUES(?, ?, ?, ?, ?, ?)', [service_type_id, team_id, service_name, service_connection, service_request, service_expected_result]) else: return redirect(url_for('scoreboard')) return redirect(url_for('configure'))
def remove_service(): """ The RemoveServiceForm posts to this page. Removes a service from the database and redirects back to the configure page. """ if app.config['ALLOW_CONFIG']: service_id = request.form['service_id'] db.execute_db_query('DELETE from service where service_id = ?', [service_id]) else: return redirect(url_for('scoreboard')) return redirect(url_for('configure'))
def remove_team(): """ The RemoveTeamForm posts to this page. Remove a team from the database, and redirect back to the configure page. """ team_id = request.form['team_id'] if app.config['ALLOW_CONFIG']: db.execute_db_query('DELETE from service where team_id = ?', [team_id]) db.execute_db_query('DELETE from team WHERE team_id = ?', [team_id]) else: return redirect(url_for('scoreboard')) return redirect(url_for('configure'))
def add_team(): """ The AddTeamForm posts to this page. Add a team to the database, and redirect back to the configure page. """ form = AddTeamForm(request.form, csrf_enabled=False) if app.config['ALLOW_CONFIG']: if form.validate(): db.execute_db_query('INSERT INTO team(team_name) VALUES(?)', [form.team_name.data]) else: flash('Form not validated') else: return redirect(url_for('scoreboard')) return redirect(url_for('configure'))
def add_dns_service(): """ The AddDNSServiceForm posts to this page. Add a DNS service to the database, and redirect back to the configure page. """ form = AddDNSServiceForm(request.form, csrf_enabled=False) if app.config['ALLOW_CONFIG']: choices = [(team['team_id'], team['team_name']) for team in db.execute_db_query('select team_id, team_name from team')] form.team_name.choices = choices if form.validate(): service_type_id = db.execute_db_query("select service_type_id from service_type where service_type_name = 'dns'")[0]['service_type_id'] team_id = form.team_name.data db.execute_db_query('INSERT INTO service(service_type_id, team_id, service_name, service_connection, service_request, service_expected_result) VALUES(?, ?, ?, ?, ?, ?)', [service_type_id, team_id, form.service_name.data, form.service_connection.data, form.service_request.data, form.service_expected_result.data]) else: flash('Form not validated') else: return redirect(url_for('scoreboard')) return redirect(url_for('configure'))
def poll(): """ Iterates over all the active services in the database and attempt to execute that service's functionality. The success or failure of the service and any error messages are stored in the database. """ for service in execute_db_query('select * from service where service_active = 1'): sleep(2) # Grab the service from the database row = execute_db_query('select * from service_type join service ON (service_type.service_type_id = service.service_type_id) where service.service_type_id = ?', [service['service_type_id']])[0] if row: type = row['service_type_name'] # Perform DNS Request if type == 'dns': poll_dns.delay(timeout, service['service_id'], service['service_connection'], service['service_request'], service['service_expected_result']) # Perform HTTP(S) Request elif type == 'http' or type == 'https': poll_web.delay(timeout, service['service_id'], row['service_type_name'], service['service_connection'], service['service_request'], service['service_expected_result']) # Perform FTP Request elif type == 'ftp': poll_ftp.delay(timeout, service['service_id'], service['service_connection'], service['service_request'], service['service_expected_result']) # Perform SMTP request to send mail, POP3 to retrieve it back elif type == 'mail': poll_mail.delay(timeout, service['service_id'], service['service_connection'], service['service_request'], service['service_expected_result'])
def configure(): """ The configure page is used to add/remove teams/services. """ if app.config['ALLOW_CONFIG']: forms = {} forms['addTeamForm'] = AddTeamForm(request.form, csrf_enabled=False) choices = [(team['team_id'], team['team_name']) for team in db.execute_db_query('select team_id, team_name from team')] forms['addDNSServiceForm'] = AddDNSServiceForm(request.form, csrf_enabled=False) forms['addWebServiceForm'] = AddWebServiceForm(CombinedMultiDict((request.files, request.form))) forms['addMailServiceForm'] = AddMailServiceForm(request.form, csrf_enabled=False) forms['addWebServiceForm'].team_name.choices = choices forms['addDNSServiceForm'].team_name.choices = choices forms['addMailServiceForm'].team_name.choices = choices return render_template('configure.html', forms=forms, active_page='configure') else: return redirect(url_for('scoreboard'))
def poll_web(poll_timeout, service_id, service_type, service_connection, service_request, service_expected_result): try: try: try: result = s.get(service_type + '://' + service_connection + service_request, timeout=poll_timeout, verify=False).text except requests.exceptions.Timeout as e: execute_db_query('insert into error(service_id,error_message) values(?,?)', [service_id, 'HTTP(S) Request resulted in a Timeout exception: ' + repr(e)]) execute_db_query('insert into poll(poll_score,service_id) values(0,?)', [service_id]) return except requests.exceptions.ConnectionError as e: execute_db_query('insert into error(service_id,error_message) values(?,?)', [service_id, 'HTTP(S) Request resulted in a ConnectionError exception: ' + repr(e) + '. This could be thre result of DNS failure, a refused connection, etc.']) execute_db_query('insert into poll(poll_score,service_id) values(0,?)', [service_id]) return except requests.exceptions.HTTPError as e: execute_db_query('insert into error(service_id,error_message) values(?,?)', [service_id, 'HTTP(S) Request resulted in a HTTPError exception: ' + repr(e) + '. This means the HTTP response returned an unsuccessful status code.']) execute_db_query('insert into poll(poll_score,service_id) values(0,?)', [service_id]) return except requests.exceptions.TooManyRedirects as e: execute_db_query('insert into error(service_id,error_message) values(?,?)', [service_id, 'HTTP(S) Request resulted in a TooManyRedirects exception: ' + repr(e)]) execute_db_query('insert into poll(poll_score,service_id) values(0,?)', [service_id]) return except requests.exceptions.RequestException as e: execute_db_query('insert into error(service_id,error_message) values(?,?)', [service_id, 'HTTP(S) Request resulted in an unknown request exception: ' + repr(e)]) execute_db_query('insert into poll(poll_score,service_id) values(0,?)', [service_id]) return match = False if os.path.isfile(service_expected_result): upload = open(service_expected_result, 'r') service_expected_result = upload.read() upload.close() # Only comparing first 10 lines for now. Have no good way to compare dynamic portions of a webpage. one = service_expected_result.splitlines(0)[0:10] two = result.splitlines(0)[0:10] if one == two: match = True else: diff = difflib.unified_diff(one, two) execute_db_query('insert into error(service_id,error_message) values(?,?)', [service_id, 'HTTP(S) Request result did not match expected. Diff: \n' + ''.join(diff)]) else: execute_db_query('insert into error(service_id, error_message) values(?,?)', [service_id, 'Local filename for expected result: ' + service_expected_result + ' does not exist.']) if match: execute_db_query('insert into poll(poll_score,service_id) values(1,?)', [service_id]) else: execute_db_query('insert into poll(poll_score,service_id) values(0,?)', [service_id]) except Exception as e: execute_db_query('insert into error(service_id,error_message) values(?,?)', [service_id, 'HTTP(S) Request resulted in exception: ' + repr(e)]) execute_db_query('insert into poll(poll_score,service_id) values(0,?)', [service_id]) pass except SoftTimeLimitExceeded: execute_db_query('insert into error(service_id, error_message) values(?,?)', [service_id, 'Task timed out. No error message received.']) execute_db_query('insert into poll(poll_score,service_id) values(0,?)', [service_id])
def poll_dns(poll_timeout, service_id, service_connection, service_request, service_expected_result): try: try: result = '' try: resolv = dns.resolver.Resolver() resolv.nameservers = [service_connection] resolv.timeout = poll_timeout resolv.lifetime = poll_timeout answers = resolv.query(service_request, 'A') for rdata in answers: result = rdata.to_text() except DNSException: execute_db_query('insert into error(service_id, error_message) values(?,?)', [service_id, 'DNS Timeout on request for: ' + service_request + ' using server: ' + service_connection]) if result == service_expected_result: execute_db_query('insert into poll(poll_score,service_id) values(1,?)', [service_id]) else: execute_db_query('insert into error(service_id,error_message) values(?,?)', [service_id, 'DNS Request result: ' + result + ' did not match expected: ' + service_expected_result]) execute_db_query('insert into poll(poll_score,service_id) values(0,?)', [service_id]) except Exception as e: execute_db_query('insert into error(service_id, error_message) values(?,?)', [service_id, 'DNS Request resulted in exception: ' + repr(e)]) execute_db_query('insert into poll(poll_score,service_id) values(0,?)', [service_id]) pass except SoftTimeLimitExceeded: execute_db_query('insert into error(service_id, error_message) values(?,?)', [service_id, 'Task timed out. No error message received.']) execute_db_query('insert into poll(poll_score,service_id) values(0,?)', [service_id])
def poll_mail(poll_timeout, service_id, service_connection, service_request, service_expected_result): try: try: sender = service_request.split(',')[0] recipient = service_request.split(',')[1] msg = service_request.split(',')[2] sender_user = sender.split(':')[0] sender_pass = sender.split(':')[1].split('@')[0] sender = sender_user + '@' + sender.split('@')[1] try: smtpServer = smtplib.SMTP(service_connection,timeout=(poll_timeout*2)) smtpServer.sendmail(sender,recipient,msg) smtpServer.quit() except Exception as e: execute_db_query('insert into error(service_id,error_message) values(?,?)', [service_id, 'SMTP Request resulted in exception: ' + repr(e)]) execute_db_query('insert into poll(poll_score,service_id) values(0,?)', [service_id]) return match = False try: Mailbox = poplib.POP3(service_connection, timeout=(poll_timeout*2)) Mailbox.user(sender_user) Mailbox.pass_(sender_pass) numMessages = len(Mailbox.list()[1]) if numMessages < 1: execute_db_query('insert into error(service_id,error_message) values(?,?)', [service_id, 'POP3 Request returned an empty mailbox. SMTP send or POP3 receive may have failed.']) else: # Retrieve only the latest message message = Mailbox.retr(numMessages)[1] result = message[-1] if result == service_expected_result: match = True else: diff = difflib.unified_diff(service_expected_result, result) execute_db_query('insert into error(service_id,error_message) values(?,?)', [service_id, 'POP3 response did not match expected result. Diff: \n' + ''.join(diff)]) except Exception as e: execute_db_query('insert into error(service_id,error_message) values(?,?)', [service_id, 'POP3 Request resulted in exception: ' + repr(e)]) pass if match: execute_db_query('insert into poll(poll_score,service_id) values(1,?)', [service_id]) else: execute_db_query('insert into poll(poll_score,service_id) values(0,?)', [service_id]) except Exception as e: execute_db_query('insert into error(service_id, error_message) values(?,?)', [service_id, 'Mail request resulted in exception: ' + repr(e)]) execute_db_query('insert into poll(poll_score,service_id) values(0,?)', [service_id]) pass except SoftTimeLimitExceeded: execute_db_query('insert into error(service_id, error_message) values(?,?)', [service_id, 'Task timed out. No error message received.']) execute_db_query('insert into poll(poll_score,service_id) values(0,?)', [service_id])
def poll_ftp(poll_timeout, service_id, service_connection, service_request, service_expected_result): try: try: match = False ftp = FTP(host=service_connection, timeout=(poll_timeout*2)) ftp.login() resultStringIO = StringIO() ftp.retrbinary('RETR ' + service_request, resultStringIO.write) result = resultStringIO.getvalue() if os.path.isfile(service_expected_result): upload = open(service_expected_result, 'r') service_expected_result = upload.read() upload.close() if result == service_expected_result: match = True else: diff = difflib.unified_diff(service_expected_result, result) execute_db_query('insert into error(service_id,error_message) values(?,?)', [service_id, 'FTP Request result did not match expected. Diff: \n' + ''.join(diff)]) else: execute_db_query('insert into error(service_id, error_message) values(?,?)', [service_id, 'Local filename for expected result: ' + service_expected_result + ' does not exist.']) if match: execute_db_query('insert into poll(poll_score,service_id) values(1,?)', [service_id]) else: execute_db_query('insert into poll(poll_score,service_id) values(0,?)', [service_id]) except Exception as e: execute_db_query('insert into error(service_id, error_message) values(?,?)', [service_id, 'FTP request resulted in exception: ' + repr(e)]) execute_db_query('insert into poll(poll_score,service_id) values(0,?)', [service_id]) return except SoftTimeLimitExceeded: execute_db_query('insert into error(service_id, error_message) values(?,?)', [service_id, 'Task timed out. No error message received.']) execute_db_query('insert into poll(poll_score,service_id) values(0,?)', [service_id])