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')
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')
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')
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')
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))
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))
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))
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))
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))