CH-J Server ManagerSerververwaltung über SSH
Menü
Veröffentlichte Quellen

CH-J Server Manager

Durchsuchen Sie Verzeichnisse und Dateien einer bestimmten Anwendungsausgabe.

Quellen als ZIP herunterladen
CH-J Proprietary Software License 1.14

Die Quellen werden unter der CH-J Proprietary Software License 1.14 bereitgestellt. Ihre Verfügbarkeit ändert die Lizenzbedingungen nicht und gewährt keine zusätzlichen Rechte.

5,6 KB · 96 ZeilenDatei herunterladen
1#!/usr/bin/python3
2"""Private one-request helper: fprintd on system D-Bus + libsecret on session D-Bus.
3No PAM changes, root access, plaintext key files or Electron basic_text backend.
4"""
5import json,sys,signal,base64
6class Failure(Exception): pass
7def failure(code): raise Failure(code)
8def main():
9 request=json.loads(sys.stdin.buffer.read(4097))
10 try:
11 import gi
12 gi.require_version('Secret','1')
13 from gi.repository import Gio,GLib,Secret
14 except (ImportError,ValueError): failure('BIOMETRIC_KEYRING_UNAVAILABLE')
15 op=request.get('op');entry=request.get('entryId');reason=str(request.get('reason','CH-J Server Manager'))[:200]
16 schema=Secret.Schema.new('de.ch-j.servermanager.vault.biometry.v1',Secret.SchemaFlags.NONE,{'vault':Secret.SchemaAttributeType.STRING})
17 def keyring():
18 try:
19 service=Secret.Service.get_sync(Secret.ServiceFlags.OPEN_SESSION | Secret.ServiceFlags.LOAD_COLLECTIONS,None)
20 if service is None: failure('BIOMETRIC_KEYRING_UNAVAILABLE')
21 # Only the explicit Secret Service API is used; there is no fallback backend.
22 collection=Secret.Collection.for_alias_sync(service,Secret.COLLECTION_DEFAULT,Secret.CollectionFlags.NONE,None)
23 if collection is None: failure('BIOMETRIC_KEYRING_UNAVAILABLE')
24 return service
25 except GLib.Error: failure('BIOMETRIC_KEYRING_UNAVAILABLE')
26 def device():
27 try:
28 manager=Gio.DBusProxy.new_for_bus_sync(Gio.BusType.SYSTEM,Gio.DBusProxyFlags.NONE,None,'net.reactivated.Fprint','/net/reactivated/Fprint/Manager','net.reactivated.Fprint.Manager',None)
29 path=manager.call_sync('GetDefaultDevice',None,Gio.DBusCallFlags.NONE,5000,None).unpack()[0]
30 proxy=Gio.DBusProxy.new_for_bus_sync(Gio.BusType.SYSTEM,Gio.DBusProxyFlags.NONE,None,'net.reactivated.Fprint',path,'net.reactivated.Fprint.Device',None)
31 fingers=proxy.call_sync('ListEnrolledFingers',GLib.Variant('(s)',('',)),Gio.DBusCallFlags.NONE,5000,None).unpack()[0]
32 if not fingers: failure('BIOMETRIC_NO_ENROLLMENT')
33 return proxy
34 except GLib.Error as e:
35 if 'NoEnrolledPrints' in str(e): failure('BIOMETRIC_NO_ENROLLMENT')
36 failure('BIOMETRIC_UNAVAILABLE')
37 def authenticate():
38 proxy=device();loop=GLib.MainLoop();state={'code':'BIOMETRIC_FAILED','claimed':False,'started':False,'timeout':None}
39 def call(method,args=None):return proxy.call_sync(method,args,Gio.DBusCallFlags.NONE,5000,None)
40 def on_signal(_proxy,_sender,name,params):
41 if name!='VerifyStatus':return
42 result,done=params.unpack()
43 if result=='verify-match':state['code']=None;loop.quit()
44 elif result=='verify-no-match':state['code']='BIOMETRIC_FAILED';loop.quit()
45 elif result=='verify-disconnected':state['code']='BIOMETRIC_DEVICE_UNAVAILABLE';loop.quit()
46 elif done:loop.quit()
47 def stop(code):state['code']=code;loop.quit();return False
48 handler=proxy.connect('g-signal',on_signal)
49 old_handlers={}
50 try:
51 call('Claim',GLib.Variant('(s)',('',)));state['claimed']=True
52 for sig in [signal.SIGTERM,signal.SIGINT]:old_handlers[sig]=signal.signal(sig,lambda _s,_f:stop('BIOMETRIC_CANCELLED'))
53 state['timeout']=GLib.timeout_add_seconds(60,lambda:stop('BIOMETRIC_TIMEOUT'))
54 call('VerifyStart',GLib.Variant('(s)',('any',)));state['started']=True
55 loop.run()
56 if state['code']:failure(state['code'])
57 except GLib.Error:failure('BIOMETRIC_DEVICE_UNAVAILABLE')
58 finally:
59 if state['timeout']:
60 try:GLib.source_remove(state['timeout'])
61 except Exception:pass
62 if state['started']:
63 try:call('VerifyStop')
64 except Exception:pass
65 if state['claimed']:
66 try:call('Release')
67 except Exception:pass
68 proxy.disconnect(handler)
69 for sig,handler in old_handlers.items():signal.signal(sig,handler)
70 if op=='status':
71 try:keyring();device();return {'ok':True,'available':True,'code':'BIOMETRIC_AVAILABLE'}
72 except Failure as e:return {'ok':True,'available':False,'code':str(e)}
73 if op=='authenticate':authenticate();return {'ok':True}
74 if not isinstance(entry,str) or len(entry)!=64 or any(c not in '0123456789abcdef' for c in entry):failure('BIOMETRIC_FAILED')
75 keyring();attrs={'vault':entry}
76 try:
77 if op=='store':
78 encoded=request.get('key','');key=bytearray(base64.b64decode(encoded,validate=True))
79 if len(key)!=32:failure('BIOMETRIC_INVALID_KEY')
80 try:
81 if not Secret.password_store_sync(schema,attrs,Secret.COLLECTION_DEFAULT,'CH-J Server Manager Vault',encoded,None):failure('BIOMETRIC_CREDENTIAL_FAILED')
82 finally:key[:]=b'\0'*len(key)
83 return {'ok':True}
84 if op=='remove':Secret.password_clear_sync(schema,attrs,None);return {'ok':True}
85 if op=='retrieve':
86 authenticate()
87 value=Secret.password_lookup_sync(schema,attrs,None)
88 if value is None:failure('BIOMETRIC_ENROLLMENT_INVALIDATED')
89 if len(base64.b64decode(value,validate=True))!=32:failure('BIOMETRIC_INVALID_KEY')
90 return {'ok':True,'key':value}
91 except GLib.Error:failure('BIOMETRIC_CREDENTIAL_FAILED')
92 failure('BIOMETRIC_FAILED')
93try:
94 result=main();print(json.dumps(result));sys.exit(0)
95except Failure as e:print(json.dumps({'ok':False,'code':str(e)}));sys.exit(1)
96except Exception:print(json.dumps({'ok':False,'code':'BIOMETRIC_FAILED'}));sys.exit(1)

SHA-256: b014f6adff38c73a806a0b0f3c399959d8564732c63b5212c78bf161d0ec5a95

SHA-256 des Archivs: 5ac91caf4fa32a6fdb114f2430deed486fbe7489d5eea343d1f034169fafb5e0