@@ -242,7 +242,7 @@ def import_gpg_key(source):
242242 source: String containing env var name, file path, URL, or key content
243243
244244 Returns:
245- True if import succeeded, False otherwise
245+ Fingerprint string if import succeeded, None otherwise
246246 """
247247 try :
248248 key_content = None
@@ -334,19 +334,55 @@ def download_key_operation():
334334 temp_key_file = f .name
335335
336336 try :
337+ # First, extract fingerprint using show-only
338+ fingerprint = None
339+ try :
340+ show_cmd = ['gpg' , '--batch' , '--import-options' , 'show-only' , '--import' , '--with-colons' , temp_key_file ]
341+ show_result = subprocess .run (show_cmd , capture_output = True , text = True , check = True )
342+ for line in show_result .stdout .split ('\n ' ):
343+ if line .startswith ('fpr:' ):
344+ fields = line .split (':' )
345+ if len (fields ) >= 10 and len (fields [9 ]) == 40 :
346+ fingerprint = fields [9 ]
347+ print (" Extracted fingerprint: %s" % fingerprint )
348+ break
349+ except :
350+ pass # Will try after import
351+
352+ # Import the key
337353 cmd = ['gpg' , '--batch' , '--import' , temp_key_file ]
338354 result = subprocess .run (cmd , capture_output = True , text = True , check = True )
339355
356+ # Check if key was skipped due to missing user ID
357+ if 'contains no user ID' in result .stderr or 'w/o user IDs' in result .stderr :
358+ print ("\n ERROR: GPG key import failed - key has no user ID" )
359+ print ("ERROR: The key from '%s' does not contain a user ID." % source_description )
360+ print ("ERROR: This typically happens with keys from keys.openpgp.org when the email isn't verified." )
361+ print ("ERROR:" )
362+ print ("ERROR: Solutions:" )
363+ print ("ERROR: 1. Verify your email on keys.openpgp.org and use the by-email URL" )
364+ print ("ERROR: 2. Provide the full PGP public key block directly (with user ID)" )
365+ print ("ERROR: 3. Upload your key to keyserver.ubuntu.com with full user ID" )
366+ return None
367+
340368 print (" Successfully imported GPG key from %s" % source_description )
341369
342- # Show imported key info if available in stderr
343- if result .stderr :
344- # GPG outputs import info to stderr
345- for line in result .stderr .split ('\n ' ):
346- if 'imported:' in line .lower () or 'public key' in line .lower ():
347- print (" %s" % line .strip ())
370+ # If fingerprint extraction failed before import, try after
371+ if not fingerprint :
372+ try :
373+ list_cmd = ['gpg' , '--batch' , '--list-keys' , '--with-colons' ]
374+ list_result = subprocess .run (list_cmd , capture_output = True , text = True , check = True )
375+ for line in list_result .stdout .split ('\n ' ):
376+ if line .startswith ('fpr:' ):
377+ fields = line .split (':' )
378+ if len (fields ) >= 10 and len (fields [9 ]) == 40 :
379+ fingerprint = fields [9 ]
380+ break
381+ except :
382+ pass
348383
349- return True
384+ # Return fingerprint if found, otherwise True for backwards compatibility
385+ return fingerprint if fingerprint else True
350386
351387 finally :
352388 # Clean up temp file
@@ -355,7 +391,7 @@ def download_key_operation():
355391
356392 except Exception as e :
357393 print (" WARNING: Failed to import GPG key: %s" % str (e ))
358- return False
394+ return None
359395
360396
361397def encrypt_file_gpg (input_file , recipient ):
@@ -1886,14 +1922,19 @@ def process_account(config):
18861922 # Import GPG key if specified (for encryption)
18871923 if config .get ('gpg_import_key' ) and config .get ('gpg_encrypt' ):
18881924 print ("\n Importing GPG public key..." )
1889- key_imported = import_gpg_key (config ['gpg_import_key' ])
1890- if not key_imported :
1925+ key_result = import_gpg_key (config ['gpg_import_key' ])
1926+ if not key_result :
18911927 print ("\n ERROR: Failed to import GPG key for account '%s'" % config .get ('account_name' , 'unknown' ))
18921928 print ("ERROR: Cannot proceed with GPG encryption enabled but key import failed" )
18931929 print ("ERROR: Aborting backup to prevent unencrypted data from being created" )
18941930 server .logout ()
18951931 return False
18961932
1933+ # If import returned a fingerprint, use it instead of the configured recipient
1934+ if isinstance (key_result , str ) and len (key_result ) >= 16 :
1935+ print (" Using imported key fingerprint for encryption: %s" % key_result )
1936+ config ['gpg_recipient' ] = key_result
1937+
18971938 # S3 Restore: Download and decrypt files before restore
18981939 if config .get ('restore' ) and config .get ('s3_upload' ):
18991940 print ("\n Downloading files from S3 for restore..." )
0 commit comments