Main Program Loop

def main():
    '''Main Program Loop'''

    # First we need to get the login information.
    print 'Security Center Remediation Report Generator\n----------------------------------------------'
    sc_address = raw_input('Address : ')
    sc_user = raw_input('Username : ')
    sc_pass = getpass('Password : ')
    try:
        sc = securitycenter.SecurityCenter4(sc_address)
        sc.login(sc_user, sc_pass)
    except:
        print 'Invalid Host or Account Information.'
        exit()

    # Next Determine how we want to limit the data.
    data = sc.assets()
    print 'Repositories\n------------'
    for repo in data['repositories']:
        print repo['id'], repo['name']
    repos = raw_input('Repository ID : ').strip()

    print '\nAssets\n------'
    for asset in data['assets']:
        print asset['id'], asset['name']
    asset = raw_input('Asset List ID : ').strip()

    try:
        reponame = [r['name'] for r in data['repositories'] if r['id'] == repos][0]
        if asset != '':
          assetname = [a['name'] for a in data['assets'] if a['id'] == asset][0]
    except:
        print 'Either the Repository ID or the Asset ID are invalid.'
        exit()

    report_name = raw_input('Report Output Filename : ')

    # Now to get the data
    filterset = {
      'pluginID': '66334', 
      'repositoryIDs': repos,
    }
    if asset != '':
      filterset['assetID'] = asset
    print '\n* Querying Security Center...'
    try:
        details = sc.query('vulndetails', **filterset)
    except securitycenter.APIError, msg:
        print str(msg).replace('\\n','\n')
        exit()

    report = open('%s.md' % report_name, 'w')
    skipper = []
    # Chapter 1: Discovered Hosts
    print '* Building Chaper 1'
    report.write('# Discovered Systems\n\n')
    report.write(' * __Repository :__ %s\n' % reponame)
    if asset != '':
      report.write(' * __Asset List :__ %s\n' % assetname)
    report.write('\n')
    report.write('|IP|NetBIOS|Operating System|Risk|Patches|Low|Medium|High|Critical|\n')
    report.write('|:-|:------|:---------------|:---|:------|:--|:-----|:---|:-------|\n')
    for item in details:
        info = sc.ip_info(item['ip'], [repos])['records'][0]
        rems = sc.query('sumremediation', repositoryIDs=repos, ip=item['ip'])
        if len(rems) > 0:
          print 'Building Summary for %s...' % item['ip']
          report.write('|[%s](#%s)|%s|%s|%s|%s|%s|%s|%s|%s|\n' % (item['ip'], item['ip'],
                                                  info['netbiosName'],
                                                  info['os'].replace('<br/>', ' '),
                                                  info['score'],
                                                  len(rems),
                                                  info['severityLow'],
                                                  info['severityMedium'], 
                                                  info['severityHigh'], 
                                                  info['severityCritical']))
        else:
          skipper.append(item['ip'])

    # Chapter 2: Detail
    print '* Building Chapter 2'
    pout = re.compile('<plugin_output>(.*)</plugin_output>')
    ms = re.compile(r'- {0,1}(KB[^\<\:\n]*)')
    fix1 = re.compile(r'- (.* \(\d{5,6}\):)((?:\n(?! -).*){1,})')
    fix2 = re.compile(r'\[ (.*) \]\n\n\+ Action to take: (.*)\n\n\+ Impact: (.*)')
    kbids = re.compile(r'KB(\d{6,8})')
    msids = re.compile(r'(MS\d{2}\-\d{2,3})')
    msvulns = re.compile(r'\((\d{1,3}) vulnerabilit')
    report.write('\n# Remediation Plan\n')
    for item in details:
        if item['ip'] in skipper:
          continue
        # We need to parse out all of the data using regex
        item['pOut'] = pout.findall(item['pluginText'])[0].replace('<br/>','\n')
        item['MSBulletins'] = ms.findall(item['pOut'])
        item['patch'] = fix1.findall(item['pOut'])
        [item['patch'].append(a) for a in fix2.findall(item['pOut'])]

        # And now to write the item in the chapter...
        report.write('\n\n## <a id="%s"></a>Remediation Plan for %s\n\n' % (item['ip'], item['ip']))
        if len(item['MSBulletins']) > 0:
            report.write('\n__To patch the remote system, you need to install the following Microsoft patches:__\n\n')
            for kba in item['MSBulletins']:
                entry = '  * '
                kbid = kbids.findall(kba)
                msid = msids.findall(kba)
                vnum = msvulns.findall(kba)
                if len(kbid) > 0:
                    entry += '[KB%s](http://support.microsoft.com/kb/%s) ' % (kbid[0], kbid[0])
                if len(msid) > 0:
                    entry += '([%s](http://technet.microsoft.com/en-us/security/bulletin/%s))' % (msid[0], msid[0])
                if len(vnum) > 0:
                    vnum = int(vnum[0])
                    if vnum == 1:
                        entry += ' (1 vulnerability)'
                    else:
                        entry += ' (%s vulnerabilities)' % vnum
                if entry == '  * ':
                    entry += kba
                report.write('%s\n' % entry)
        if len(item['patch']) > 0:
            report.write('\n__You need to take the following %d actions:__\n\n' % len(item['patch']))
            for patch in item['patch']:
                if len(patch) == 2:
                    report.write('  * %s\n' % patch[0])
                    report.write('    * %s\n' % patch[1].replace('\n', ' '))
                if len(patch) == 3:
                    report.write('  * %s\n' % patch[0])
                    report.write('    * __Action to take :__ %s\n' % patch[1])
                    report.write('    * __Impact :__ %s\n' % patch[2])

    report.close()

    # Now to Generate the PDF...
    print '* Saving HTML File...'
    with file('%s.html' % report_name, 'w') as html:
        html.write(html_head)
        html.write(markdown.markdown(file('%s.md' % report_name).read(), ['tables']))
        html.write('</div></body></html>')