#!/usr/bin/python
#
# Smartphone Pentest Framework
#
# By: Antimoon
#
# Based extensively off of work by Georgia Weidman and
# Bulb Security
#
#
# spf_core.py
#
# This file contains the core functions of the smartphone pentest framework.
# Stuff like menu construction, a subprocess wrapper, and the basic structure
# of agent interactions lives here.
#
# The only dependencies in here are python packages and spf-modem.py 
#

version = '0.5'

header  = '################################################\n'
header += '#                                              #\n'
header += '# Welcome to the Smartphone Pentest Framework! #\n'
header += '#                   v%s                     #\n' % version
header += '#         Antimoon  /  viaForensics Remix      #\n'
header += '#                                              #\n'
header += '################################################\n'
header += '\n\n'

# Console output beautification courtesy of Graham King
def bold(msg):
    return str(u'\033[1m%s\033[0m' % msg)


def color(this_color, string):
    return str("\033[" + str(this_color) + "m" + string + "\033[0m")


from modem import get_modem

try:
    import MySQLdb
    import sys
    import shlex
    import subprocess
    import ConfigParser
    import struct
except ImportError, e:
    # Generate error and exit here, as other modules require these
    # imports. Saves dependency-checking time.
    print color(31, '[!] Error while importing: %s' % e)
    sys.exit(1)


config  = ConfigParser.ConfigParser()
config.read('config.cfg')


# SQL config vars
sqlserver = config.get('SQL','server')
username  = config.get('SQL','username')
password  = config.get('SQL','password')


# Web Server Config Vars
webserver      = config.get('Web','server')
webroot        = config.get('Web','webroot')
ipaddress      = config.get('Web','ipaddress')
shellipaddress = config.get('Web','shellipaddress')

#db     = MySQLdb.connect(sqlserver, username, password, 'framework')
#cursor = db.cursor()

def system(command):
    # Subprocess wrapper
    # Don't pass commands that require user interaction to this 
    # method, as it doesn't provide handlers for stdin, stdout, or
    # stderr

    command = shlex.split(command)

    try:
        return_code = subprocess.Popen(command)
    except Exception, e:
        print color(31, '[!] Error while executing system command: %s' % e)
        return_code = 1

    # return_code should be 0 if command executed successfully
    return return_code


#def spf_db():
#    '''Wrapper for MySQLdb.connect, rereads SQL config vars in case 
#       they change.'''
#    config  = ConfigParser.ConfigParser()
#    config.read('config.cfg')
#
#    # SQL config vars
#    sqlserver = config.get('SQL','server')
#    username  = config.get('SQL','username')
#    password  = config.get('SQL','password')
#
#    try:
#        db = MySQLdb.connect(sqlserver, username, password, 'framework')
#    except Exception, e:
#        print '[!] Error connecting to database: %s' % e
#        db = None
#    return db


def menu(options, title='[*] Select an Option from the Menu:\n'):
    # Display a menu
    # Options is a list of menu option titles, title is the title
    # for the whole menu. Title should be followed by a newline
    # for consistency
    print color(35, title)

    i=1
    while i <= len(options):
        print color(35,'\t%s.)' % i) +' %s' % options[i-1]
        i+=1

    # 0 is always back or exit, for consistency
    print color(35,'\t0.)') + ' Back\n'

    try:
        #prompt = color(36, '[*] spf>')
        prompt = color(31, '[*] spf> ')
        choice = int(raw_input(prompt))
    except:
        choice = 'Error'

    return choice


def delivery(key, command, deliverymethod, returnmethod, control, explicit=False):
    # Communicate with agent
    global webroot
    try:
        returnmethod = returnmethod.lower()
    except Exception, e:
        print color(31, '[!] Error: %s' % e)
        return 1

    if returnmethod is 'http':
        returnmethod = ''

    if control in ('', None):
        control = webroot + 'spf/putfunc'

    if explicit is False:
        command = '%s %s %s %s' % (key, command, deliverymethod, returnmethod)   

        if returnmethod is 'sms':
            modem = get_modem()

            if modem is 0:
                print color(31, '\n[!] No modems found. Attach a modem to use this functionality\n')
                # Exit here to prevent writing to file
                return 1
            else:
                command += modem + '\n'

        elif returnmethod is '':
            command += '\n'

    file = open(control, 'w')
    file.write(command)
    file.close()

    return 0

