#!/usr/bin/env python2
'''
pCTF 2012 CLI interface
Email bug reports to plaid.parliament.of.pwning@gmail.com.
'''
import sys
import getpass
import json
import cookielib
import urllib
import urllib2
import urlparse
import textwrap
import getpass
try:
import readline
def completer(text, state):
commands = [
'help',
'hints',
'problems',
'score',
'show',
'submit',
'vote_clear',
'vote_down',
'vote_show',
'vote_summary',
'vote_up',
'quit',
]
options = [x for x in commands if x.startswith(text)]
if state < len(options):
return options[state]
else:
return None
readline.set_completer(completer)
readline.parse_and_bind("tab: complete")
except ImportError:
pass
class PCTFClient(object):
def __init__(self, username=None, password=None,
base_url='http://ctf.plaidctf.com'):
self._cookiejar = cookielib.CookieJar()
self._username = username
self._password = password
self._base_url = base_url
self._opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(self._cookiejar))
self._auth = None
self._csrftoken = None
def login(self):
# Get CSRF token
url = urlparse.urljoin(self._base_url, '/dropdowns/login')
self._opener.open(url)
for c in self._cookiejar:
if c.name == 'csrftoken':
self._csrftoken = c.value
url = urlparse.urljoin(self._base_url, '/teams/login')
form_data = {
'username': self._username,
'password': self._password,
'csrfmiddlewaretoken': self._csrftoken
}
try:
response = self._opener.open(url, urllib.urlencode(form_data))
except urllib2.URLError, reason:
return False
if 'Please try again.' in response.read():
return False
for c in self._cookiejar:
if c.name == 'auth':
self._auth = c.value
return True
def request(self, path, data):
url = urlparse.urljoin(self._base_url, path)
if data is None:
req = urllib2.Request(url)
else:
form_data = {
'data': json.dumps(data),
'csrfmiddlewaretoken': self._csrftoken
}
req = urllib2.Request(url, urllib.urlencode(form_data))
req.add_header('X-Auth', self._auth)
response = self._opener.open(req)
return response.read()
def getteam(self):
data = self.request('/teams/my_team', None)
my_team = json.loads(data)
if my_team['score'] is None:
my_team['score'] = 0
return my_team
def clean(self, s):
s = s.replace('
', '\n\n')
s = s.replace('
', '\n\n')
s = s.replace('
', '\n\n')
s = s.replace('<', '<')
s = s.replace('>', '>')
return '\n'.join(textwrap.wrap(s))
def getproblems(self, unsolved_only=True):
if unsolved_only:
data = self.request('/problems/list?unsolved_only', None)
else:
data = self.request('/problems/list', None)
problems = json.loads(data)
for p in problems:
p['description'] = self.clean(p['description'])
return problems
def clean_hints(self, s):
# silly split and join to get rid of