Exemple #1
0
def set_advanced(request):
    Preferences = set_up_single_user()
    if request.POST.get('engaged') == 'true':
        Preferences.show_advanced = True
    else:
        Preferences.show_advanced = False
    Preferences.save()
    return HttpResponse(json.dumps({'engaged':Preferences.show_advanced}),
                        content_type='application/json')
Exemple #2
0
def ip_address(request):
    Preferences = set_up_single_user()
    Preferences.ip_address_type = request.POST.get('ip-address-mode',
                                                   thirtythirty.models.preferences.DYNAMIC_IP)
    Preferences.set_ip(IP = request.POST.get('static-ip', '0.0.0.0'),
                       NM = request.POST.get('netmask', '0.0.0.0'),
                       GW = request.POST.get('gateway-ip', '0.0.0.0')
                       )
    Preferences.save()
    return HttpResponse(json.dumps({'engaged':True,
                                    'ip-address-mode':Preferences.ip_address_type}),
                        content_type='application/json')
Exemple #3
0
def symmetric_copy(request):
    Preferences = set_up_single_user()
    if request.POST.get('tx_engaged') == 'true':
        Preferences.tx_symmetric_copy = True
    else:
        Preferences.tx_symmetric_copy = False
    if request.POST.get('rx_engaged') == 'true':
        Preferences.rx_symmetric_copy = True
    else:
        Preferences.rx_symmetric_copy = False        
    Preferences.save()
    return HttpResponse(json.dumps({'tx_engaged':Preferences.tx_symmetric_copy,
                                    'rx_engaged':Preferences.rx_symmetric_copy,
                                    }),
                        content_type='application/json')
Exemple #4
0
def passphrase_cache(request):
    Preferences = set_up_single_user()
    Preferences.passphrase_cache_time = request.POST.get('cache_time',
                                                         thirtythirty.models.preferences.HOURLY)
    if request.POST.get('engaged') == 'true':
        Preferences.passphrase_cache = True
        logger.debug('PP cache enabled: %s' % Preferences.passphrase_cache_time)
    else:
        Preferences.passphrase_cache = False
        logger.debug('PP cache disabled')
    Preferences.save()
    return HttpResponse(json.dumps({'cache_time':Preferences.passphrase_cache_time,
                                    'engaged':Preferences.passphrase_cache,
                                    }),
                        content_type='application/json')
Exemple #5
0
def home(request, Index=None, advanced=False):
    Preferences = set_up_single_user()
    if Preferences.show_advanced: advanced = True

    Addressbook = addressbook.address.Address.objects.filter(system_use=False)
    if Index:
        Addressbook = addressbook.address.Address.objects.filter(
            Q(nickname__startswith = Index) |\
            Q(covername__startswith = Index) |\
            Q(covername__contains = ' %s' % Index) # filter last name too
            ).filter(system_use=False)

    Indices = set([
        X.magic()[0]
        for X in addressbook.address.Address.objects.filter(system_use=False)
    ])  # set() uniques the results
    state_hash = {}
    for K, V in addressbook.address.Address.user_state_choices:
        state_hash[K] = V

    # see if we've had our covername accepted by the headend server...
    Headend_Ok = False
    Me = addressbook.utils.my_address()
    if Me.comment and Me.comment != 'accepted LUKS passphrase':
        Headend_Ok = True

    context = RequestContext(
        request, {
            'title': 'Contacts',
            'nav': 'Contacts',
            'bg_image': 'the-stacks.jpg',
            'vitals': thirtythirty.utils.Vitals(request),
            'indices': sorted(Indices),
            'index': Index,
            'advanced': advanced,
            'friends': Addressbook,
            'headend_ok': Headend_Ok,
            'state_names': state_hash,
        })
    template = loader.get_template('addressbook.dtl')
    return HttpResponse(template.render(context))
Exemple #6
0
def home(request, Index=None, advanced=False):
    Preferences = set_up_single_user()
    if Preferences.show_advanced: advanced = True
    
    Addressbook = addressbook.address.Address.objects.filter(system_use=False)
    if Index:
        Addressbook = addressbook.address.Address.objects.filter(
            Q(nickname__startswith = Index) |\
            Q(covername__startswith = Index) |\
            Q(covername__contains = ' %s' % Index) # filter last name too
            ).filter(system_use=False)
        
    Indices = set([ X.magic()[0] for X in addressbook.address.Address.objects.filter(system_use=False) ]) # set() uniques the results
    state_hash = {}
    for K, V in addressbook.address.Address.user_state_choices:
        state_hash[K] = V

    # see if we've had our covername accepted by the headend server...
    Headend_Ok = False
    Me = addressbook.utils.my_address()
    if Me.comment and Me.comment != 'accepted LUKS passphrase':
        Headend_Ok = True
        
    context = RequestContext(
        request,
        {'title':'Contacts',
         'nav':'Contacts',
         'bg_image':'the-stacks.jpg',
         'vitals':thirtythirty.utils.Vitals(request),
         'indices':sorted(Indices),
         'index':Index,
         'advanced':advanced,
         'friends':Addressbook,
         'headend_ok':Headend_Ok,
         'state_names':state_hash,
         })
    template = loader.get_template('addressbook.dtl')
    return HttpResponse(template.render(context))
Exemple #7
0
def settings(request, advanced=False):
    Vitals = thirtythirty.utils.Vitals(request)
    Update_Version = '[No update available]'
    Update_Warn = ''
    Availed = Available()
    if Availed and Validate(Availed['filename'], Debug=False):
        Update_Version = 'Version %s now available!' % Availed['version']
        Update_Warn = 'Back up your settings before update!'
    Preferences = set_up_single_user()
    if Preferences.show_advanced: advanced = True
    
    Info_Panel = [
        {'desc':'Version',
         'name':'LGVersion',
         'value':TTS.LOOKINGGLASS_VERSION_STRING},
        {'desc':'Covername',
         'name':'covername',
         'value':Vitals['covername'],
         },
        {'desc':'Email address',
         'name':'email',
         'value':'%s' % Vitals['email'],
         },
        {'desc':'GPG Fingerprint',
         'name':'gpg',
         'value':Vitals['gpg_fp'],
         'help':'Back-up authentication method for out-of-band use.',
         },
        {'desc':'Bitcoin master public key',
         'name':'btc_mpk',
         'value':Vitals['btc_mpk'],
         'help':'Not yet implemented.',
         },
        {'desc':'WebUI SSL certificate',
         'name':'SSLCert',
         'value':'Download <a href="https://%s/docs/ca.cert.pem">here</a>.' % Vitals['server_addr'],
         },
        ]
    
    Settings = [
        {'title':'Passphrase reset',
         'id':'PassphraseR',
         'advanced':True,
         'desc':"You can change one, or both.",
         'controls':[
             {'desc':'Old drive passphrase',
              'type':'password', 'id':'prev-dpassphrase',
              'width':8,
              },
             {'desc':'New drive passphrase',
              'type':'password', 'id':'new-dpassphrase-1',
              'width':8,
              },
             {'desc':'Confirm drive passphrase',
              'type':'password', 'id':'new-dpassphrase-2',
              'width':8,
              },
             {'desc':'Old email passphrase',
              'type':'password', 'id':'prev-epassphrase',
              'width':8,
              },
             {'desc':'New email passphrase',
              'type':'password', 'id':'new-epassphrase-1',
              'width':8,
              },
             {'desc':'Confirm email passphrase',
              'type':'password', 'id':'new-epassphrase-2',
              'width':8,
              },
             ]},

        {'title':'IP Address settings',
         'id':'IP',
         'advanced':True,
         'controls':[
             {'desc':'Dynamic vs Static IP',
              'type':'select', 'id':'ip-address-mode',
              'choices':Preferences.ip_types,
              'option_checked':Preferences.ip_address_type,
              },
             {'desc':'Static IP address',
              'type':'text', 'id':'static-ip',
              'value':thirtythirty.utils.IP_Info('Address'),
              'disabled':Preferences.ip_address_type == Preferences.DYNAMIC_IP,
              },
             {'desc':'Netmask',
              'type':'text', 'id':'netmask',
              'value':thirtythirty.utils.IP_Info('Netmask'),
              'disabled':Preferences.ip_address_type == Preferences.DYNAMIC_IP,
              },
             {'desc':'Gateway IP address',
              'type':'text', 'id':'gateway-ip',
              'value':thirtythirty.utils.IP_Info('Gateway'),
              'disabled':Preferences.ip_address_type == Preferences.DYNAMIC_IP,
              },
             {'desc':'Accept', 'type':'button',
              'id':'static-ip-send', 'value':'Submit',
              'disabled':Preferences.ip_address_type == Preferences.DYNAMIC_IP,
              },
             ]},

        {'title':'Dead man switch',
         'id':'Dead-man',
         'advanced':True,
         'controls':[
             {'desc':'Dead man switch',
              'disabled':True, 'type':'checkbox',
              'help':'Let interested people know I am alive',
              },
             {'desc':'Timeout', 'id':'dms-timeout',
              'disabled':True, 'type':'text',
              'placeholder':'three days',
              },
             ]},

        {'title':'Radio interface',
         'id':'Radio',
         'advanced':True,
         'controls':[
             {'desc':'Enable mesh radio interface',
              'disabled':True, 'type':'checkbox',
              },
             ]},

        {'title':'Process management',
         'id':'Process',
         'controls':[
             {'desc':'NTP time sync',
              'type':'button',
              'class':'kick',
              'id':'ntp-sync',
              },
             {'desc':'Flush mail queue',
              'type':'button',
              'class':'kick',
              'id':'postqueue-flush',
              },
             {'desc':'Restart mail subsystem',
              'type':'button',
              'class':'kick',
              'id':'postfix-restart',
              },
             {'desc':'Restart Tor',
              'type':'button',
              'class':'kick',
              'id':'tor-restart',
              },
             {'desc':'Restart WebUI',
              'type':'button',
              'class':'kick',
              'id':'django-restart',
              },
             {'desc':'Force queue run',
              'type':'button',
              'class':'kick',
              'id':'qmanage-run',
              },
             {'desc':'Queue kicker',
              'type':'button',
              'class':'kick',
              'id':'rqworker',
              },
             ]},

        {'title':'Updates',
         'id':'Updates',
         'controls':[
             {'desc':'Update',
              'class':'bg-info',
              'type':'button', 'id':'update',
              'disabled':(not Available()),
              'help':Update_Version,
              'warn':Update_Warn,
              },
             {'desc':'Force update',
              'type':'button', 'id':'force-update',
              'warn':'No mercy.  No resistance.  Open up.',
              'advanced':True,
              },
             {'desc':'Drag upgrade file here to upload',
              'type':'file', 'id':'upgrade-file',
              'filetype':'upgrade',
              'action':reverse('settings.file_upload'),
              },
             ]},

        {'title':'Backup / Restore',
         'id':'Backups',
         'controls':[
             {'desc':'Backup',
              'type':'button', 'id':'sysbackup',
              'href':reverse('settings.backup'),
              },
             {'desc':'Restore',
              'type':'button', 'id':'sysrestore',
              'disabled':True,
              },
             {'desc':'Drag restore file here to upload',
              'type':'file', 'id':'restore-file',
              'filetype':'backup',
              'action':reverse('settings.file_upload'),
              },
             {'desc':'Recover database',
              'type':'button', 'id':'database-recover',
              'help':'If a power outage or some other badness occurred, you may need this',
              'warn':"You may lose messages and need to resynchronize with your contacts - don't click this idly",
              },
             ]},

        {'title':'System administration',
         'id':'Sysadmin',
         'controls':[
             {'desc':'Report bug',
              'type':'button', 'href':reverse('bug_report'),
             },
             {'desc':'Respond to status queries',
              'type':'checkbox', 'id':'allow-status',
              'help':'Respond to keyserver poll for system status',
              'checked':False, 'disabled':True,
             },
             {'desc':'Local wizard login',
              'type':'button', 'href':'https://%s:4200' % Vitals['server_addr'],
              'target':'_blank',
              'help':'Emergency login for nearby wizards',
              },
             {'desc':'Reboot',
              'type':'button', 'id':'reboot',
              'help':'Reboots, locks drives',
              },              
             {'desc':'Reset to defaults',
              'type':'button', 'id':'reset-to-defaults',
              'warn':'NUKES EVERYTHING.',
              },
             ]},

        {'title':'Passphrase convenience',
         'id':'PassphraseC',
         'advanced':True,
         'controls':[
             {'desc':'USB key token',
              'type':'checkbox', 'id':'usb-token',
              'help':'Use USB flash drive as encryption key',
              'disabled':True,
              },
             {'desc':'Passphrase cache',
              'type':'checkbox', 'id':'pp-cache-on',
              'help':'Allows authentication tasks to proceed more quickly',
              'warn':'Increaseses your window of vulnerability',
              'checked':Preferences.passphrase_cache,
              },
             {'desc':'Passphrase cache cleared:',
              'type':'select', 'id':'pp-cache-timeout',
              'choices':thirtythirty.models.preferences.passphrase_cache_timeouts,
              'option_checked':Preferences.passphrase_cache_time,
              }
             ]},
        
        {'title':'Blatantly insecure niceties',
         'id':'xBlatantly',
         'advanced':True,
         'controls':[
             {'desc':'Keep a copy of sent messages',
              'type':'checkbox', 'id':'tx-symmetric-on',
              'checked':Preferences.tx_symmetric_copy,
             },
             {'desc':'Keep a copy of read-once messages',
              'type':'checkbox', 'id':'rx-symmetric-on',
              'checked':Preferences.rx_symmetric_copy,
             },
             {'desc':'Local search',
              'type':'checkbox', 'id':'search-on',
              'disabled':True,
              },
             ]},

        {'title':'Darknet mode',
         'id':'Darknet',
         'advanced':True,
         'controls':[
             {'desc':'Darknet mode',
              'type':'checkbox', 'id':'darknet-on',
              'help':'Email whitelisting',
              'disabled':True,
              },
             {'desc':'Darknet key',
              'type':'text', 'id':'darknet-key',
              'placeholder':'Shared secret',
              'disabled':True,
              },
             ]},

        {'title':'Remote access',
         'id':'Remote',
         'advanced':True,
         'controls':[
             {'desc':'Remote user access',
              'type':'checkbox', 'id':'remote-user-on',
              'disabled':True,
              'help':'Provides experimental remote Tor access',
              },
             {'desc':'Allow remote assist',
              'type':'checkbox', 'id':'remote-admin-on',
              'warn':'Allows complete remote control of device',
              'disabled':True,
              },
             ]},

        {'title':'System logs',
         'id':'Logs',
         'viewport':'log-view',
         'view_ro':True,
         'advanced':True,
         'controls':[
             {'desc':'Mail log',
              'type':'link', 'id':'get-mail-log',
             },
             {'desc':'Mail queue',
              'type':'link', 'id':'get-mail-queue',
              },
             {'desc':'Recent login history',
              'type':'link', 'id':'get-user-log',
             },
             {'desc':'Web frontend',
              'type':'link', 'id':'get-web-log',
              },
             ]},

        {'title':'Mail filters',
         'id':'MailFilter',
         'viewport':'mail-filter',
         'view_ro':False,
         'advanced':True,
         'controls':[
             {'desc':'Update',
              'type':'link', 'id':'update-filter',
              },
             ]},

        {'title':'Mailing lists',
         'id':'Mailman',
         'advanced':True,
         'controls':[
             {'desc':'Run encrypted mail list',
              'id':'axo-mailman',
              'type':'checkbox', 'disabled':True,
              }
             ]},

        # https://en.wikipedia.org/wiki/Cypherpunk_anonymous_remailer
        {'title':'Anonymous remailing',
         'id':'AnonymousRemail',
         'advanced':True,
         'controls':[
             {'desc':'Provide remailing services to other users',
              'type':'checkbox', 'id':'cypherpunk-relay-on',
              'disabled':True,
              },
             {'desc':'Use remailing for outbound email',
              'type':'checkbox', 'id':'cypherpunk-outbound-on',
              'disabled':True,
              },
             {'desc':'Enable traffic analysis countermeasures',
              'type':'checkbox', 'id':'ta-counter-on',
              'disabled':True,
              },
             ]},

        {'title':'WooOOOooOOo folders',
         'id':'xAdminFolders',
         'advanced':True,
         'controls':[
             {'desc':'Administrator inbox',
              'type':'link', 'href':reverse('emailclient.folder', kwargs={'name':'admin'}),
              'badge':emailclient.filedb.message_count('admin'),
              },
             {'desc':'Trash',
              'type':'link', 'href':reverse('emailclient.folder', kwargs={'name':'trash'}),
              'badge':emailclient.filedb.message_count('trash'),
              },
             ]},

        {'title':'Double dog advanced',
         'id':'zAdvanced',
         'controls':[
             {'desc':'Barf forth apocalyptica',
              'type':'link', 'href':reverse('advanced_settings'),
              },
             {'desc':'Always show advanced controls',
              'type':'checkbox', 'id':'advanced-always-on',
              'checked':Preferences.show_advanced,
              'advanced':True,
              },
             ]},
        
        ]
    
    context = RequestContext(request, {
        'title':'Settings',
        'nav':'Settings',
        'bg_image':'dash.jpg',
        'vital_summary':Info_Panel,
        'vitals':Vitals,
        'mounts':thirtythirty.hdd.Volumes(),
        'services':thirtythirty.utils.query_daemon_states(),
        'advanced':advanced,
        'setting_list':Settings,
        })
    template = loader.get_template('settings.dtl')
    return HttpResponse(template.render(context))
Exemple #8
0
def dossier(request, Fingerprint=None, advanced=False):
    Preferences = set_up_single_user()
    if Preferences.show_advanced: advanced = True    

    Vitalis = thirtythirty.utils.Vitals(request)

    state_hash = {}
    for K, V in addressbook.address.Address.user_state_choices:
        state_hash[K] = V
    try:
        Addr = addressbook.address.Address.objects.get(fingerprint=Fingerprint)
    except:
        return HttpResponse("""
        <script>
        window.location.href = '%s';
        </script>
        """ % reverse('addressbook'))
    req = {'K':Addr,
           'state_names':state_hash,
           'advanced':advanced,
           'key_expiration_warning':KEY_EXPIRATION_WARNING,
           'today':datetime.date.today(),
           'Verbose':{},
           }

    if req['K'].user_state == addressbook.address.Address.NOT_VETTED:
        req['Handshake_Title'] = 'Send Handshake'
    else:
        req['Handshake_Title'] = 'Resend Handshake'

    PP = None
    SMP_Step = 0

    if 'passphrase' in request.session:
        PP = request.session['passphrase']

        try: SMP_Objects.decrypt_database(PP)
        except thirtythirty.exception.Target_Exists: pass
        try: Ratchet_Objects.decrypt_database(PP)
        except thirtythirty.exception.Target_Exists: pass

        MyRatchet = ratchet.conversation.Conversation.objects.filter(
            UniqueKey=Fingerprint
            ).first()
        if MyRatchet:
            req['my_fingerprint'] = MyRatchet.my_fingerprint()
            req['their_fingerprint'] = MyRatchet.their_fingerprint()
        MySMP = smp.models.SMP.objects.filter(
            UniqueKey=Fingerprint
            ).first()
        Query = None
        try:
            Query = addressbook.queue.Queue.objects.filter(
            address__fingerprint=Fingerprint
            ).latest()
        except addressbook.queue.Queue.DoesNotExist: pass
        if Query:
            req['previous_smp_step'] = Query.body
        if MySMP:
            SMP_Step = MySMP.step
            req['Question'] = MySMP.Question

    
    for K, V in addressbook.address.Address.Verbose.iteritems():
        BR = re.sub('BUG_REPORT_URL', reverse('bug_report'), V)
        ADV = re.sub('RELOAD_ADVANCED', '%s#%s' % (
                reverse('addressbook.advanced'),
                Fingerprint,
                ), BR)
        SMP = re.sub('SMP_STEP', str(SMP_Step), ADV)
        req['Verbose'][K] = SMP
        
    context = RequestContext(request, req)
    template = loader.get_template('dossier.dtl')
    return HttpResponse(template.render(context))
Exemple #9
0
def dossier(request, Fingerprint=None, advanced=False):
    Preferences = set_up_single_user()
    if Preferences.show_advanced: advanced = True

    Vitalis = thirtythirty.utils.Vitals(request)

    state_hash = {}
    for K, V in addressbook.address.Address.user_state_choices:
        state_hash[K] = V
    try:
        Addr = addressbook.address.Address.objects.get(fingerprint=Fingerprint)
    except:
        return HttpResponse("""
        <script>
        window.location.href = '%s';
        </script>
        """ % reverse('addressbook'))
    req = {
        'K': Addr,
        'state_names': state_hash,
        'advanced': advanced,
        'key_expiration_warning': KEY_EXPIRATION_WARNING,
        'today': datetime.date.today(),
        'Verbose': {},
    }

    if req['K'].user_state == addressbook.address.Address.NOT_VETTED:
        req['Handshake_Title'] = 'Send Handshake'
    else:
        req['Handshake_Title'] = 'Resend Handshake'

    PP = None
    SMP_Step = 0

    if 'passphrase' in request.session:
        PP = request.session['passphrase']

        try:
            SMP_Objects.decrypt_database(PP)
        except thirtythirty.exception.Target_Exists:
            pass
        try:
            Ratchet_Objects.decrypt_database(PP)
        except thirtythirty.exception.Target_Exists:
            pass

        MyRatchet = ratchet.conversation.Conversation.objects.filter(
            UniqueKey=Fingerprint).first()
        if MyRatchet:
            req['my_fingerprint'] = MyRatchet.my_fingerprint()
            req['their_fingerprint'] = MyRatchet.their_fingerprint()
        MySMP = smp.models.SMP.objects.filter(UniqueKey=Fingerprint).first()
        Query = None
        try:
            Query = addressbook.queue.Queue.objects.filter(
                address__fingerprint=Fingerprint).latest()
        except addressbook.queue.Queue.DoesNotExist:
            pass
        if Query:
            req['previous_smp_step'] = Query.body
        if MySMP:
            SMP_Step = MySMP.step
            req['Question'] = MySMP.Question

    for K, V in addressbook.address.Address.Verbose.iteritems():
        BR = re.sub('BUG_REPORT_URL', reverse('bug_report'), V)
        ADV = re.sub(
            'RELOAD_ADVANCED', '%s#%s' % (
                reverse('addressbook.advanced'),
                Fingerprint,
            ), BR)
        SMP = re.sub('SMP_STEP', str(SMP_Step), ADV)
        req['Verbose'][K] = SMP

    context = RequestContext(request, req)
    template = loader.get_template('dossier.dtl')
    return HttpResponse(template.render(context))