| 
									
										
										
										
											2020-04-03 18:52:18 +00:00
										 |  |  | __filename__ = "pgp.py" | 
					
						
							|  |  |  | __author__ = "Bob Mottram" | 
					
						
							|  |  |  | __license__ = "AGPL3+" | 
					
						
							| 
									
										
										
										
											2021-01-26 10:07:42 +00:00
										 |  |  | __version__ = "1.2.0" | 
					
						
							| 
									
										
										
										
											2020-04-03 18:52:18 +00:00
										 |  |  | __maintainer__ = "Bob Mottram" | 
					
						
							| 
									
										
										
										
											2021-09-10 16:14:50 +00:00
										 |  |  | __email__ = "bob@libreserver.org" | 
					
						
							| 
									
										
										
										
											2020-04-03 18:52:18 +00:00
										 |  |  | __status__ = "Production" | 
					
						
							| 
									
										
										
										
											2021-06-15 15:08:12 +00:00
										 |  |  | __module_group__ = "Profile Metadata" | 
					
						
							| 
									
										
										
										
											2019-12-17 20:44:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-11 20:33:45 +00:00
										 |  |  | import os | 
					
						
							| 
									
										
										
										
											2021-03-11 17:15:32 +00:00
										 |  |  | import subprocess | 
					
						
							| 
									
										
										
										
											2021-03-11 20:33:45 +00:00
										 |  |  | from pathlib import Path | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | from person import get_actor_json | 
					
						
							| 
									
										
										
										
											2021-12-26 19:15:36 +00:00
										 |  |  | from utils import contains_pgp_public_key | 
					
						
							|  |  |  | from utils import is_pgp_encrypted | 
					
						
							| 
									
										
										
										
											2021-12-26 12:45:03 +00:00
										 |  |  | from utils import get_full_domain | 
					
						
							| 
									
										
										
										
											2021-12-27 17:42:35 +00:00
										 |  |  | from utils import get_status_number | 
					
						
							| 
									
										
										
										
											2021-12-26 10:19:59 +00:00
										 |  |  | from utils import local_actor_url | 
					
						
							| 
									
										
										
										
											2021-12-26 17:21:37 +00:00
										 |  |  | from utils import replace_users_with_at | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | from webfinger import webfinger_handle | 
					
						
							|  |  |  | from posts import get_person_box | 
					
						
							| 
									
										
										
										
											2021-12-28 21:36:27 +00:00
										 |  |  | from auth import create_basic_auth_header | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | from session import post_json | 
					
						
							| 
									
										
										
										
											2021-03-11 17:15:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-17 20:44:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-28 17:33:54 +00:00
										 |  |  | def get_email_address(actor_json: {}) -> str: | 
					
						
							| 
									
										
										
										
											2019-12-17 20:44:18 +00:00
										 |  |  |     """Returns the email address for the given actor
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2021-12-26 10:29:52 +00:00
										 |  |  |     if not actor_json.get('attachment'): | 
					
						
							| 
									
										
										
										
											2019-12-17 20:44:18 +00:00
										 |  |  |         return '' | 
					
						
							| 
									
										
										
										
											2021-12-26 10:32:45 +00:00
										 |  |  |     for property_value in actor_json['attachment']: | 
					
						
							|  |  |  |         if not property_value.get('name'): | 
					
						
							| 
									
										
										
										
											2019-12-17 20:44:18 +00:00
										 |  |  |             continue | 
					
						
							| 
									
										
										
										
											2021-12-26 10:32:45 +00:00
										 |  |  |         if not property_value['name'].lower().startswith('email'): | 
					
						
							| 
									
										
										
										
											2019-12-17 20:44:18 +00:00
										 |  |  |             continue | 
					
						
							| 
									
										
										
										
											2021-12-26 10:32:45 +00:00
										 |  |  |         if not property_value.get('type'): | 
					
						
							| 
									
										
										
										
											2019-12-17 20:44:18 +00:00
										 |  |  |             continue | 
					
						
							| 
									
										
										
										
											2021-12-26 10:32:45 +00:00
										 |  |  |         if not property_value.get('value'): | 
					
						
							| 
									
										
										
										
											2019-12-17 20:44:18 +00:00
										 |  |  |             continue | 
					
						
							| 
									
										
										
										
											2021-12-26 10:32:45 +00:00
										 |  |  |         if property_value['type'] != 'PropertyValue': | 
					
						
							| 
									
										
										
										
											2019-12-17 20:44:18 +00:00
										 |  |  |             continue | 
					
						
							| 
									
										
										
										
											2021-12-26 10:32:45 +00:00
										 |  |  |         if '@' not in property_value['value']: | 
					
						
							| 
									
										
										
										
											2019-12-17 20:44:18 +00:00
										 |  |  |             continue | 
					
						
							| 
									
										
										
										
											2021-12-26 10:32:45 +00:00
										 |  |  |         if '.' not in property_value['value']: | 
					
						
							| 
									
										
										
										
											2019-12-17 20:44:18 +00:00
										 |  |  |             continue | 
					
						
							| 
									
										
										
										
											2021-12-26 10:32:45 +00:00
										 |  |  |         return property_value['value'] | 
					
						
							| 
									
										
										
										
											2019-12-17 20:44:18 +00:00
										 |  |  |     return '' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-03 18:52:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-28 17:33:54 +00:00
										 |  |  | def get_pgp_pub_key(actor_json: {}) -> str: | 
					
						
							| 
									
										
										
										
											2019-12-17 20:44:18 +00:00
										 |  |  |     """Returns PGP public key for the given actor
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2021-12-26 10:29:52 +00:00
										 |  |  |     if not actor_json.get('attachment'): | 
					
						
							| 
									
										
										
										
											2019-12-17 20:44:18 +00:00
										 |  |  |         return '' | 
					
						
							| 
									
										
										
										
											2021-12-26 10:32:45 +00:00
										 |  |  |     for property_value in actor_json['attachment']: | 
					
						
							|  |  |  |         if not property_value.get('name'): | 
					
						
							| 
									
										
										
										
											2019-12-17 20:44:18 +00:00
										 |  |  |             continue | 
					
						
							| 
									
										
										
										
											2021-12-26 10:32:45 +00:00
										 |  |  |         if not property_value['name'].lower().startswith('pgp'): | 
					
						
							| 
									
										
										
										
											2019-12-17 20:44:18 +00:00
										 |  |  |             continue | 
					
						
							| 
									
										
										
										
											2021-12-26 10:32:45 +00:00
										 |  |  |         if not property_value.get('type'): | 
					
						
							| 
									
										
										
										
											2019-12-17 20:44:18 +00:00
										 |  |  |             continue | 
					
						
							| 
									
										
										
										
											2021-12-26 10:32:45 +00:00
										 |  |  |         if not property_value.get('value'): | 
					
						
							| 
									
										
										
										
											2019-12-17 20:44:18 +00:00
										 |  |  |             continue | 
					
						
							| 
									
										
										
										
											2021-12-26 10:32:45 +00:00
										 |  |  |         if property_value['type'] != 'PropertyValue': | 
					
						
							| 
									
										
										
										
											2019-12-17 20:44:18 +00:00
										 |  |  |             continue | 
					
						
							| 
									
										
										
										
											2021-12-26 19:15:36 +00:00
										 |  |  |         if not contains_pgp_public_key(property_value['value']): | 
					
						
							| 
									
										
										
										
											2019-12-17 20:44:18 +00:00
										 |  |  |             continue | 
					
						
							| 
									
										
										
										
											2021-12-26 10:32:45 +00:00
										 |  |  |         return property_value['value'] | 
					
						
							| 
									
										
										
										
											2019-12-17 20:44:18 +00:00
										 |  |  |     return '' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-03 18:52:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-28 17:33:54 +00:00
										 |  |  | def get_pgp_fingerprint(actor_json: {}) -> str: | 
					
						
							| 
									
										
										
										
											2020-07-06 09:52:06 +00:00
										 |  |  |     """Returns PGP fingerprint for the given actor
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2021-12-26 10:29:52 +00:00
										 |  |  |     if not actor_json.get('attachment'): | 
					
						
							| 
									
										
										
										
											2020-07-06 09:52:06 +00:00
										 |  |  |         return '' | 
					
						
							| 
									
										
										
										
											2021-12-26 10:32:45 +00:00
										 |  |  |     for property_value in actor_json['attachment']: | 
					
						
							|  |  |  |         if not property_value.get('name'): | 
					
						
							| 
									
										
										
										
											2020-07-06 09:52:06 +00:00
										 |  |  |             continue | 
					
						
							| 
									
										
										
										
											2021-12-26 10:32:45 +00:00
										 |  |  |         if not property_value['name'].lower().startswith('openpgp'): | 
					
						
							| 
									
										
										
										
											2020-07-06 09:52:06 +00:00
										 |  |  |             continue | 
					
						
							| 
									
										
										
										
											2021-12-26 10:32:45 +00:00
										 |  |  |         if not property_value.get('type'): | 
					
						
							| 
									
										
										
										
											2020-07-06 09:52:06 +00:00
										 |  |  |             continue | 
					
						
							| 
									
										
										
										
											2021-12-26 10:32:45 +00:00
										 |  |  |         if not property_value.get('value'): | 
					
						
							| 
									
										
										
										
											2020-07-06 09:52:06 +00:00
										 |  |  |             continue | 
					
						
							| 
									
										
										
										
											2021-12-26 10:32:45 +00:00
										 |  |  |         if property_value['type'] != 'PropertyValue': | 
					
						
							| 
									
										
										
										
											2020-07-06 09:52:06 +00:00
										 |  |  |             continue | 
					
						
							| 
									
										
										
										
											2021-12-26 10:32:45 +00:00
										 |  |  |         if len(property_value['value']) < 10: | 
					
						
							| 
									
										
										
										
											2020-07-06 09:52:06 +00:00
										 |  |  |             continue | 
					
						
							| 
									
										
										
										
											2021-12-26 10:32:45 +00:00
										 |  |  |         return property_value['value'] | 
					
						
							| 
									
										
										
										
											2020-07-06 09:52:06 +00:00
										 |  |  |     return '' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-31 18:11:17 +00:00
										 |  |  | def set_email_address(actor_json: {}, email_address: str) -> None: | 
					
						
							| 
									
										
										
										
											2019-12-17 20:44:18 +00:00
										 |  |  |     """Sets the email address for the given actor
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |     not_email_address = False | 
					
						
							| 
									
										
										
										
											2021-12-31 18:11:17 +00:00
										 |  |  |     if '@' not in email_address: | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |         not_email_address = True | 
					
						
							| 
									
										
										
										
											2021-12-31 18:11:17 +00:00
										 |  |  |     if '.' not in email_address: | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |         not_email_address = True | 
					
						
							| 
									
										
										
										
											2021-12-31 18:11:17 +00:00
										 |  |  |     if '<' in email_address: | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |         not_email_address = True | 
					
						
							| 
									
										
										
										
											2021-12-31 18:11:17 +00:00
										 |  |  |     if email_address.startswith('@'): | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |         not_email_address = True | 
					
						
							| 
									
										
										
										
											2020-07-06 10:25:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-26 10:29:52 +00:00
										 |  |  |     if not actor_json.get('attachment'): | 
					
						
							|  |  |  |         actor_json['attachment'] = [] | 
					
						
							| 
									
										
										
										
											2019-12-17 20:44:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-17 23:35:59 +00:00
										 |  |  |     # remove any existing value | 
					
						
							| 
									
										
										
										
											2022-01-03 10:27:55 +00:00
										 |  |  |     property_found = None | 
					
						
							| 
									
										
										
										
											2021-12-26 10:32:45 +00:00
										 |  |  |     for property_value in actor_json['attachment']: | 
					
						
							|  |  |  |         if not property_value.get('name'): | 
					
						
							| 
									
										
										
										
											2019-12-17 23:35:59 +00:00
										 |  |  |             continue | 
					
						
							| 
									
										
										
										
											2021-12-26 10:32:45 +00:00
										 |  |  |         if not property_value.get('type'): | 
					
						
							| 
									
										
										
										
											2019-12-17 23:35:59 +00:00
										 |  |  |             continue | 
					
						
							| 
									
										
										
										
											2021-12-26 10:32:45 +00:00
										 |  |  |         if not property_value['name'].lower().startswith('email'): | 
					
						
							| 
									
										
										
										
											2019-12-17 23:35:59 +00:00
										 |  |  |             continue | 
					
						
							| 
									
										
										
										
											2022-01-03 10:27:55 +00:00
										 |  |  |         property_found = property_value | 
					
						
							| 
									
										
										
										
											2019-12-17 23:35:59 +00:00
										 |  |  |         break | 
					
						
							| 
									
										
										
										
											2022-01-03 10:27:55 +00:00
										 |  |  |     if property_found: | 
					
						
							|  |  |  |         actor_json['attachment'].remove(property_found) | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |     if not_email_address: | 
					
						
							| 
									
										
										
										
											2019-12-17 20:44:18 +00:00
										 |  |  |         return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-26 10:32:45 +00:00
										 |  |  |     for property_value in actor_json['attachment']: | 
					
						
							|  |  |  |         if not property_value.get('name'): | 
					
						
							| 
									
										
										
										
											2019-12-17 20:44:18 +00:00
										 |  |  |             continue | 
					
						
							| 
									
										
										
										
											2021-12-26 10:32:45 +00:00
										 |  |  |         if not property_value.get('type'): | 
					
						
							| 
									
										
										
										
											2019-12-17 20:44:18 +00:00
										 |  |  |             continue | 
					
						
							| 
									
										
										
										
											2021-12-26 10:32:45 +00:00
										 |  |  |         if not property_value['name'].lower().startswith('email'): | 
					
						
							| 
									
										
										
										
											2019-12-17 20:44:18 +00:00
										 |  |  |             continue | 
					
						
							| 
									
										
										
										
											2021-12-26 10:32:45 +00:00
										 |  |  |         if property_value['type'] != 'PropertyValue': | 
					
						
							| 
									
										
										
										
											2019-12-17 20:44:18 +00:00
										 |  |  |             continue | 
					
						
							| 
									
										
										
										
											2021-12-31 18:11:17 +00:00
										 |  |  |         property_value['value'] = email_address | 
					
						
							| 
									
										
										
										
											2019-12-17 20:44:18 +00:00
										 |  |  |         return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |     new_email_address = { | 
					
						
							| 
									
										
										
										
											2019-12-17 20:44:18 +00:00
										 |  |  |         "name": "Email", | 
					
						
							|  |  |  |         "type": "PropertyValue", | 
					
						
							| 
									
										
										
										
											2021-12-31 18:11:17 +00:00
										 |  |  |         "value": email_address | 
					
						
							| 
									
										
										
										
											2019-12-17 20:44:18 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |     actor_json['attachment'].append(new_email_address) | 
					
						
							| 
									
										
										
										
											2019-12-17 20:44:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-03 18:52:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-31 18:11:17 +00:00
										 |  |  | def set_pgp_pub_key(actor_json: {}, pgp_pub_key: str) -> None: | 
					
						
							| 
									
										
										
										
											2019-12-17 20:44:18 +00:00
										 |  |  |     """Sets a PGP public key for the given actor
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |     remove_key = False | 
					
						
							| 
									
										
										
										
											2021-12-31 18:11:17 +00:00
										 |  |  |     if not pgp_pub_key: | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |         remove_key = True | 
					
						
							| 
									
										
										
										
											2020-07-06 09:52:06 +00:00
										 |  |  |     else: | 
					
						
							| 
									
										
										
										
											2021-12-31 18:11:17 +00:00
										 |  |  |         if not contains_pgp_public_key(pgp_pub_key): | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |             remove_key = True | 
					
						
							| 
									
										
										
										
											2021-12-31 18:11:17 +00:00
										 |  |  |         if '<' in pgp_pub_key: | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |             remove_key = True | 
					
						
							| 
									
										
										
										
											2020-07-06 09:52:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-26 10:29:52 +00:00
										 |  |  |     if not actor_json.get('attachment'): | 
					
						
							|  |  |  |         actor_json['attachment'] = [] | 
					
						
							| 
									
										
										
										
											2019-12-17 20:44:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-17 23:35:59 +00:00
										 |  |  |     # remove any existing value | 
					
						
							| 
									
										
										
										
											2022-01-03 10:27:55 +00:00
										 |  |  |     property_found = None | 
					
						
							| 
									
										
										
										
											2021-12-26 10:32:45 +00:00
										 |  |  |     for property_value in actor_json['attachment']: | 
					
						
							|  |  |  |         if not property_value.get('name'): | 
					
						
							| 
									
										
										
										
											2019-12-17 23:35:59 +00:00
										 |  |  |             continue | 
					
						
							| 
									
										
										
										
											2021-12-26 10:32:45 +00:00
										 |  |  |         if not property_value.get('type'): | 
					
						
							| 
									
										
										
										
											2019-12-17 23:35:59 +00:00
										 |  |  |             continue | 
					
						
							| 
									
										
										
										
											2021-12-26 10:32:45 +00:00
										 |  |  |         if not property_value['name'].lower().startswith('pgp'): | 
					
						
							| 
									
										
										
										
											2019-12-17 23:35:59 +00:00
										 |  |  |             continue | 
					
						
							| 
									
										
										
										
											2022-01-03 10:27:55 +00:00
										 |  |  |         property_found = property_value | 
					
						
							| 
									
										
										
										
											2019-12-17 23:35:59 +00:00
										 |  |  |         break | 
					
						
							| 
									
										
										
										
											2022-01-03 10:27:55 +00:00
										 |  |  |     if property_found: | 
					
						
							| 
									
										
										
										
											2021-12-26 10:32:45 +00:00
										 |  |  |         actor_json['attachment'].remove(property_value) | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |     if remove_key: | 
					
						
							| 
									
										
										
										
											2019-12-17 20:44:18 +00:00
										 |  |  |         return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-26 10:32:45 +00:00
										 |  |  |     for property_value in actor_json['attachment']: | 
					
						
							|  |  |  |         if not property_value.get('name'): | 
					
						
							| 
									
										
										
										
											2019-12-17 20:44:18 +00:00
										 |  |  |             continue | 
					
						
							| 
									
										
										
										
											2021-12-26 10:32:45 +00:00
										 |  |  |         if not property_value.get('type'): | 
					
						
							| 
									
										
										
										
											2019-12-17 20:44:18 +00:00
										 |  |  |             continue | 
					
						
							| 
									
										
										
										
											2021-12-26 10:32:45 +00:00
										 |  |  |         if not property_value['name'].lower().startswith('pgp'): | 
					
						
							| 
									
										
										
										
											2019-12-17 20:44:18 +00:00
										 |  |  |             continue | 
					
						
							| 
									
										
										
										
											2021-12-26 10:32:45 +00:00
										 |  |  |         if property_value['type'] != 'PropertyValue': | 
					
						
							| 
									
										
										
										
											2019-12-17 20:44:18 +00:00
										 |  |  |             continue | 
					
						
							| 
									
										
										
										
											2021-12-31 18:11:17 +00:00
										 |  |  |         property_value['value'] = pgp_pub_key | 
					
						
							| 
									
										
										
										
											2019-12-17 20:44:18 +00:00
										 |  |  |         return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-31 18:11:17 +00:00
										 |  |  |     newpgp_pub_key = { | 
					
						
							| 
									
										
										
										
											2019-12-17 20:44:18 +00:00
										 |  |  |         "name": "PGP", | 
					
						
							|  |  |  |         "type": "PropertyValue", | 
					
						
							| 
									
										
										
										
											2021-12-31 18:11:17 +00:00
										 |  |  |         "value": pgp_pub_key | 
					
						
							| 
									
										
										
										
											2019-12-17 20:44:18 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-12-31 18:11:17 +00:00
										 |  |  |     actor_json['attachment'].append(newpgp_pub_key) | 
					
						
							| 
									
										
										
										
											2020-07-06 09:52:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-28 17:33:54 +00:00
										 |  |  | def set_pgp_fingerprint(actor_json: {}, fingerprint: str) -> None: | 
					
						
							| 
									
										
										
										
											2020-07-06 09:52:06 +00:00
										 |  |  |     """Sets a PGP fingerprint for the given actor
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |     remove_fingerprint = False | 
					
						
							| 
									
										
										
										
											2020-07-06 09:52:06 +00:00
										 |  |  |     if not fingerprint: | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |         remove_fingerprint = True | 
					
						
							| 
									
										
										
										
											2020-07-06 09:52:06 +00:00
										 |  |  |     else: | 
					
						
							|  |  |  |         if len(fingerprint) < 10: | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |             remove_fingerprint = True | 
					
						
							| 
									
										
										
										
											2020-07-06 09:52:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-26 10:29:52 +00:00
										 |  |  |     if not actor_json.get('attachment'): | 
					
						
							|  |  |  |         actor_json['attachment'] = [] | 
					
						
							| 
									
										
										
										
											2020-07-06 09:52:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # remove any existing value | 
					
						
							| 
									
										
										
										
											2022-01-03 10:27:55 +00:00
										 |  |  |     property_found = None | 
					
						
							| 
									
										
										
										
											2021-12-26 10:32:45 +00:00
										 |  |  |     for property_value in actor_json['attachment']: | 
					
						
							|  |  |  |         if not property_value.get('name'): | 
					
						
							| 
									
										
										
										
											2020-07-06 09:52:06 +00:00
										 |  |  |             continue | 
					
						
							| 
									
										
										
										
											2021-12-26 10:32:45 +00:00
										 |  |  |         if not property_value.get('type'): | 
					
						
							| 
									
										
										
										
											2020-07-06 09:52:06 +00:00
										 |  |  |             continue | 
					
						
							| 
									
										
										
										
											2021-12-26 10:32:45 +00:00
										 |  |  |         if not property_value['name'].lower().startswith('openpgp'): | 
					
						
							| 
									
										
										
										
											2020-07-06 09:52:06 +00:00
										 |  |  |             continue | 
					
						
							| 
									
										
										
										
											2022-01-03 10:27:55 +00:00
										 |  |  |         property_found = property_value | 
					
						
							| 
									
										
										
										
											2020-07-06 09:52:06 +00:00
										 |  |  |         break | 
					
						
							| 
									
										
										
										
											2022-01-03 10:27:55 +00:00
										 |  |  |     if property_found: | 
					
						
							| 
									
										
										
										
											2021-12-26 10:32:45 +00:00
										 |  |  |         actor_json['attachment'].remove(property_value) | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |     if remove_fingerprint: | 
					
						
							| 
									
										
										
										
											2020-07-06 09:52:06 +00:00
										 |  |  |         return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-26 10:32:45 +00:00
										 |  |  |     for property_value in actor_json['attachment']: | 
					
						
							|  |  |  |         if not property_value.get('name'): | 
					
						
							| 
									
										
										
										
											2020-07-06 09:52:06 +00:00
										 |  |  |             continue | 
					
						
							| 
									
										
										
										
											2021-12-26 10:32:45 +00:00
										 |  |  |         if not property_value.get('type'): | 
					
						
							| 
									
										
										
										
											2020-07-06 09:52:06 +00:00
										 |  |  |             continue | 
					
						
							| 
									
										
										
										
											2021-12-26 10:32:45 +00:00
										 |  |  |         if not property_value['name'].lower().startswith('openpgp'): | 
					
						
							| 
									
										
										
										
											2020-07-06 09:52:06 +00:00
										 |  |  |             continue | 
					
						
							| 
									
										
										
										
											2021-12-26 10:32:45 +00:00
										 |  |  |         if property_value['type'] != 'PropertyValue': | 
					
						
							| 
									
										
										
										
											2020-07-06 09:52:06 +00:00
										 |  |  |             continue | 
					
						
							| 
									
										
										
										
											2021-12-26 10:32:45 +00:00
										 |  |  |         property_value['value'] = fingerprint.strip() | 
					
						
							| 
									
										
										
										
											2020-07-06 09:52:06 +00:00
										 |  |  |         return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-31 18:11:17 +00:00
										 |  |  |     newpgp_fingerprint = { | 
					
						
							| 
									
										
										
										
											2020-07-06 09:52:06 +00:00
										 |  |  |         "name": "OpenPGP", | 
					
						
							|  |  |  |         "type": "PropertyValue", | 
					
						
							|  |  |  |         "value": fingerprint | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-12-31 18:11:17 +00:00
										 |  |  |     actor_json['attachment'].append(newpgp_fingerprint) | 
					
						
							| 
									
										
										
										
											2021-03-11 14:23:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | def extract_pgp_public_key(content: str) -> str: | 
					
						
							| 
									
										
										
										
											2021-03-11 14:23:03 +00:00
										 |  |  |     """Returns the PGP key from the given text
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |     start_block = '--BEGIN PGP PUBLIC KEY BLOCK--' | 
					
						
							|  |  |  |     end_block = '--END PGP PUBLIC KEY BLOCK--' | 
					
						
							|  |  |  |     if start_block not in content: | 
					
						
							| 
									
										
										
										
											2021-03-11 14:23:03 +00:00
										 |  |  |         return None | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |     if end_block not in content: | 
					
						
							| 
									
										
										
										
											2021-03-11 14:23:03 +00:00
										 |  |  |         return None | 
					
						
							|  |  |  |     if '\n' not in content: | 
					
						
							|  |  |  |         return None | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |     lines_list = content.split('\n') | 
					
						
							| 
									
										
										
										
											2021-03-11 14:23:03 +00:00
										 |  |  |     extracting = False | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |     public_key = '' | 
					
						
							|  |  |  |     for line in lines_list: | 
					
						
							| 
									
										
										
										
											2021-03-11 14:23:03 +00:00
										 |  |  |         if not extracting: | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |             if start_block in line: | 
					
						
							| 
									
										
										
										
											2021-03-11 14:23:03 +00:00
										 |  |  |                 extracting = True | 
					
						
							|  |  |  |         else: | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |             if end_block in line: | 
					
						
							|  |  |  |                 public_key += line | 
					
						
							| 
									
										
										
										
											2021-03-11 14:23:03 +00:00
										 |  |  |                 break | 
					
						
							|  |  |  |         if extracting: | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |             public_key += line + '\n' | 
					
						
							|  |  |  |     return public_key | 
					
						
							| 
									
										
										
										
											2021-03-11 17:15:32 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  | def _pgp_import_pub_key(recipient_pub_key: str) -> str: | 
					
						
							| 
									
										
										
										
											2021-03-11 17:15:32 +00:00
										 |  |  |     """ Import the given public key
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     # do a dry run | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |     cmd_import_pub_key = \ | 
					
						
							|  |  |  |         'echo "' + recipient_pub_key + \ | 
					
						
							|  |  |  |         '" | gpg --dry-run --import 2> /dev/null' | 
					
						
							|  |  |  |     proc = subprocess.Popen([cmd_import_pub_key], | 
					
						
							| 
									
										
										
										
											2021-03-11 17:15:32 +00:00
										 |  |  |                             stdout=subprocess.PIPE, shell=True) | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |     (import_result, err) = proc.communicate() | 
					
						
							| 
									
										
										
										
											2021-03-11 17:15:32 +00:00
										 |  |  |     if err: | 
					
						
							|  |  |  |         return None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # this time for real | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |     cmd_import_pub_key = \ | 
					
						
							|  |  |  |         'echo "' + recipient_pub_key + '" | gpg --import 2> /dev/null' | 
					
						
							|  |  |  |     proc = subprocess.Popen([cmd_import_pub_key], | 
					
						
							| 
									
										
										
										
											2021-03-11 17:15:32 +00:00
										 |  |  |                             stdout=subprocess.PIPE, shell=True) | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |     (import_result, err) = proc.communicate() | 
					
						
							| 
									
										
										
										
											2021-03-11 17:15:32 +00:00
										 |  |  |     if err: | 
					
						
							|  |  |  |         return None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # get the key id | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |     cmd_import_pub_key = \ | 
					
						
							|  |  |  |         'echo "' + recipient_pub_key + '" | gpg --show-keys' | 
					
						
							|  |  |  |     proc = subprocess.Popen([cmd_import_pub_key], | 
					
						
							| 
									
										
										
										
											2021-03-11 17:15:32 +00:00
										 |  |  |                             stdout=subprocess.PIPE, shell=True) | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |     (import_result, err) = proc.communicate() | 
					
						
							|  |  |  |     if not import_result: | 
					
						
							| 
									
										
										
										
											2021-03-11 17:15:32 +00:00
										 |  |  |         return None | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |     import_result = import_result.decode('utf-8').split('\n') | 
					
						
							|  |  |  |     key_id = '' | 
					
						
							|  |  |  |     for line in import_result: | 
					
						
							| 
									
										
										
										
											2021-03-11 17:15:32 +00:00
										 |  |  |         if line.startswith('pub'): | 
					
						
							|  |  |  |             continue | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |         if line.startswith('uid'): | 
					
						
							| 
									
										
										
										
											2021-03-11 17:15:32 +00:00
										 |  |  |             continue | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |         if line.startswith('sub'): | 
					
						
							| 
									
										
										
										
											2021-03-11 17:15:32 +00:00
										 |  |  |             continue | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |         key_id = line.strip() | 
					
						
							| 
									
										
										
										
											2021-03-11 17:15:32 +00:00
										 |  |  |         break | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |     return key_id | 
					
						
							| 
									
										
										
										
											2021-03-11 17:15:32 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  | def _pgp_encrypt(content: str, recipient_pub_key: str) -> str: | 
					
						
							| 
									
										
										
										
											2021-03-11 17:15:32 +00:00
										 |  |  |     """ Encrypt using your default pgp key to the given recipient
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |     key_id = _pgp_import_pub_key(recipient_pub_key) | 
					
						
							|  |  |  |     if not key_id: | 
					
						
							| 
									
										
										
										
											2021-03-11 17:15:32 +00:00
										 |  |  |         return None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |     cmd_encrypt = \ | 
					
						
							| 
									
										
										
										
											2021-03-11 17:15:32 +00:00
										 |  |  |         'echo "' + content + '" | gpg --encrypt --armor --recipient ' + \ | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |         key_id + ' 2> /dev/null' | 
					
						
							|  |  |  |     proc = subprocess.Popen([cmd_encrypt], | 
					
						
							| 
									
										
										
										
											2021-03-11 17:15:32 +00:00
										 |  |  |                             stdout=subprocess.PIPE, shell=True) | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |     (encrypt_result, _) = proc.communicate() | 
					
						
							|  |  |  |     if not encrypt_result: | 
					
						
							| 
									
										
										
										
											2021-03-11 17:15:32 +00:00
										 |  |  |         return None | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |     encrypt_result = encrypt_result.decode('utf-8') | 
					
						
							|  |  |  |     if not is_pgp_encrypted(encrypt_result): | 
					
						
							| 
									
										
										
										
											2021-03-11 17:15:32 +00:00
										 |  |  |         return None | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |     return encrypt_result | 
					
						
							| 
									
										
										
										
											2021-03-11 17:15:32 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | def _get_pgp_public_key_from_actor(signing_priv_key_pem: str, | 
					
						
							|  |  |  |                                    domain: str, handle: str, | 
					
						
							|  |  |  |                                    actor_json: {} = None) -> str: | 
					
						
							| 
									
										
										
										
											2021-03-11 19:13:41 +00:00
										 |  |  |     """Searches tags on the actor to see if there is any PGP
 | 
					
						
							|  |  |  |     public key specified | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2021-12-26 10:29:52 +00:00
										 |  |  |     if not actor_json: | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |         actor_json, _ = \ | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |             get_actor_json(domain, handle, False, False, False, True, | 
					
						
							|  |  |  |                            signing_priv_key_pem, None) | 
					
						
							| 
									
										
										
										
											2021-12-26 10:29:52 +00:00
										 |  |  |     if not actor_json: | 
					
						
							| 
									
										
										
										
											2021-03-11 19:13:41 +00:00
										 |  |  |         return None | 
					
						
							| 
									
										
										
										
											2021-12-26 10:29:52 +00:00
										 |  |  |     if not actor_json.get('attachment'): | 
					
						
							| 
									
										
										
										
											2021-03-11 19:13:41 +00:00
										 |  |  |         return None | 
					
						
							| 
									
										
										
										
											2021-12-26 10:29:52 +00:00
										 |  |  |     if not isinstance(actor_json['attachment'], list): | 
					
						
							| 
									
										
										
										
											2021-03-11 19:13:41 +00:00
										 |  |  |         return None | 
					
						
							| 
									
										
										
										
											2021-03-11 20:33:45 +00:00
										 |  |  |     # search through the tags on the actor | 
					
						
							| 
									
										
										
										
											2021-12-26 10:29:52 +00:00
										 |  |  |     for tag in actor_json['attachment']: | 
					
						
							| 
									
										
										
										
											2021-03-11 20:33:45 +00:00
										 |  |  |         if not isinstance(tag, dict): | 
					
						
							|  |  |  |             continue | 
					
						
							| 
									
										
										
										
											2021-03-11 19:13:41 +00:00
										 |  |  |         if not tag.get('value'): | 
					
						
							|  |  |  |             continue | 
					
						
							| 
									
										
										
										
											2021-03-11 20:35:48 +00:00
										 |  |  |         if not isinstance(tag['value'], str): | 
					
						
							|  |  |  |             continue | 
					
						
							| 
									
										
										
										
											2021-12-26 19:15:36 +00:00
										 |  |  |         if contains_pgp_public_key(tag['value']): | 
					
						
							| 
									
										
										
										
											2021-03-12 09:50:08 +00:00
										 |  |  |             return tag['value'] | 
					
						
							| 
									
										
										
										
											2021-03-11 19:13:41 +00:00
										 |  |  |     return None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | def has_local_pg_pkey() -> bool: | 
					
						
							| 
									
										
										
										
											2021-03-11 20:33:45 +00:00
										 |  |  |     """Returns true if there is a local .gnupg directory
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |     home_dir = str(Path.home()) | 
					
						
							|  |  |  |     gpg_dir = home_dir + '/.gnupg' | 
					
						
							|  |  |  |     if os.path.isdir(gpg_dir): | 
					
						
							|  |  |  |         key_id = pgp_local_public_key() | 
					
						
							|  |  |  |         if key_id: | 
					
						
							| 
									
										
										
										
											2021-05-05 09:31:35 +00:00
										 |  |  |             return True | 
					
						
							| 
									
										
										
										
											2021-03-11 20:33:45 +00:00
										 |  |  |     return False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | def pgp_encrypt_to_actor(domain: str, content: str, toHandle: str, | 
					
						
							|  |  |  |                          signing_priv_key_pem: str) -> str: | 
					
						
							| 
									
										
										
										
											2021-03-11 20:33:45 +00:00
										 |  |  |     """PGP encrypt a message to the given actor or handle
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     # get the actor and extract the pgp public key from it | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |     recipient_pub_key = \ | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |         _get_pgp_public_key_from_actor(signing_priv_key_pem, domain, toHandle) | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |     if not recipient_pub_key: | 
					
						
							| 
									
										
										
										
											2021-03-11 20:33:45 +00:00
										 |  |  |         return None | 
					
						
							|  |  |  |     # encrypt using the recipient public key | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |     return _pgp_encrypt(content, recipient_pub_key) | 
					
						
							| 
									
										
										
										
											2021-03-11 20:33:45 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | def pgp_decrypt(domain: str, content: str, fromHandle: str, | 
					
						
							|  |  |  |                 signing_priv_key_pem: str) -> str: | 
					
						
							| 
									
										
										
										
											2021-03-11 17:15:32 +00:00
										 |  |  |     """ Encrypt using your default pgp key to the given recipient
 | 
					
						
							| 
									
										
										
										
											2021-03-11 19:13:41 +00:00
										 |  |  |     fromHandle can be a handle or actor url | 
					
						
							| 
									
										
										
										
											2021-03-11 17:15:32 +00:00
										 |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2021-12-26 19:15:36 +00:00
										 |  |  |     if not is_pgp_encrypted(content): | 
					
						
							| 
									
										
										
										
											2021-03-11 17:15:32 +00:00
										 |  |  |         return content | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # if the public key is also included within the message then import it | 
					
						
							| 
									
										
										
										
											2021-12-26 19:15:36 +00:00
										 |  |  |     if contains_pgp_public_key(content): | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |         pub_key = extract_pgp_public_key(content) | 
					
						
							| 
									
										
										
										
											2021-03-11 19:13:41 +00:00
										 |  |  |     else: | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |         pub_key = \ | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |             _get_pgp_public_key_from_actor(signing_priv_key_pem, | 
					
						
							|  |  |  |                                            domain, content, fromHandle) | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |     if pub_key: | 
					
						
							|  |  |  |         _pgp_import_pub_key(pub_key) | 
					
						
							| 
									
										
										
										
											2021-03-11 17:15:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |     cmd_decrypt = \ | 
					
						
							| 
									
										
										
										
											2021-03-11 17:15:32 +00:00
										 |  |  |         'echo "' + content + '" | gpg --decrypt --armor 2> /dev/null' | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |     proc = subprocess.Popen([cmd_decrypt], | 
					
						
							| 
									
										
										
										
											2021-03-11 17:15:32 +00:00
										 |  |  |                             stdout=subprocess.PIPE, shell=True) | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |     (decrypt_result, _) = proc.communicate() | 
					
						
							|  |  |  |     if not decrypt_result: | 
					
						
							| 
									
										
										
										
											2021-03-11 17:15:32 +00:00
										 |  |  |         return content | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |     decrypt_result = decrypt_result.decode('utf-8').strip() | 
					
						
							|  |  |  |     return decrypt_result | 
					
						
							| 
									
										
										
										
											2021-03-17 20:18:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | def _pgp_local_public_key_id() -> str: | 
					
						
							| 
									
										
										
										
											2021-03-17 20:18:00 +00:00
										 |  |  |     """Gets the local pgp public key ID
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |     cmd_str = \ | 
					
						
							| 
									
										
										
										
											2021-03-17 20:18:00 +00:00
										 |  |  |         "gpgconf --list-options gpg | " + \ | 
					
						
							|  |  |  |         "awk -F: '$1 == \"default-key\" {print $10}'" | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |     proc = subprocess.Popen([cmd_str], | 
					
						
							| 
									
										
										
										
											2021-03-17 20:18:00 +00:00
										 |  |  |                             stdout=subprocess.PIPE, shell=True) | 
					
						
							|  |  |  |     (result, err) = proc.communicate() | 
					
						
							|  |  |  |     if err: | 
					
						
							|  |  |  |         return None | 
					
						
							|  |  |  |     if not result: | 
					
						
							|  |  |  |         return None | 
					
						
							|  |  |  |     if len(result) < 5: | 
					
						
							|  |  |  |         return None | 
					
						
							| 
									
										
										
										
											2021-03-17 20:23:44 +00:00
										 |  |  |     return result.decode('utf-8').replace('"', '').strip() | 
					
						
							| 
									
										
										
										
											2021-03-17 20:18:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | def pgp_local_public_key() -> str: | 
					
						
							| 
									
										
										
										
											2021-03-17 20:18:00 +00:00
										 |  |  |     """Gets the local pgp public key
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |     key_id = _pgp_local_public_key_id() | 
					
						
							|  |  |  |     if not key_id: | 
					
						
							|  |  |  |         key_id = '' | 
					
						
							|  |  |  |     cmd_str = "gpg --armor --export " + key_id | 
					
						
							|  |  |  |     proc = subprocess.Popen([cmd_str], | 
					
						
							| 
									
										
										
										
											2021-03-17 20:18:00 +00:00
										 |  |  |                             stdout=subprocess.PIPE, shell=True) | 
					
						
							|  |  |  |     (result, err) = proc.communicate() | 
					
						
							|  |  |  |     if err: | 
					
						
							|  |  |  |         return None | 
					
						
							|  |  |  |     if not result: | 
					
						
							|  |  |  |         return None | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |     return extract_pgp_public_key(result.decode('utf-8')) | 
					
						
							| 
									
										
										
										
											2021-03-17 20:18:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | def pgp_public_key_upload(base_dir: str, session, | 
					
						
							|  |  |  |                           nickname: str, password: str, | 
					
						
							|  |  |  |                           domain: str, port: int, | 
					
						
							|  |  |  |                           http_prefix: str, | 
					
						
							|  |  |  |                           cached_webfingers: {}, person_cache: {}, | 
					
						
							|  |  |  |                           debug: bool, test: str, | 
					
						
							|  |  |  |                           signing_priv_key_pem: str) -> {}: | 
					
						
							| 
									
										
										
										
											2021-03-17 20:18:00 +00:00
										 |  |  |     if debug: | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |         print('pgp_public_key_upload') | 
					
						
							| 
									
										
										
										
											2021-03-17 20:18:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if not session: | 
					
						
							|  |  |  |         if debug: | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |             print('WARN: No session for pgp_public_key_upload') | 
					
						
							| 
									
										
										
										
											2021-03-17 20:18:00 +00:00
										 |  |  |         return None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if not test: | 
					
						
							|  |  |  |         if debug: | 
					
						
							|  |  |  |             print('Getting PGP public key') | 
					
						
							| 
									
										
										
										
											2021-12-31 18:11:17 +00:00
										 |  |  |         pgp_pub_key = pgp_local_public_key() | 
					
						
							|  |  |  |         if not pgp_pub_key: | 
					
						
							| 
									
										
										
										
											2021-03-17 20:18:00 +00:00
										 |  |  |             return None | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |         pgp_pub_key_id = _pgp_local_public_key_id() | 
					
						
							| 
									
										
										
										
											2021-03-17 20:18:00 +00:00
										 |  |  |     else: | 
					
						
							|  |  |  |         if debug: | 
					
						
							|  |  |  |             print('Testing with PGP public key ' + test) | 
					
						
							| 
									
										
										
										
											2021-12-31 18:11:17 +00:00
										 |  |  |         pgp_pub_key = test | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |         pgp_pub_key_id = None | 
					
						
							| 
									
										
										
										
											2021-03-17 20:18:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-26 12:45:03 +00:00
										 |  |  |     domain_full = get_full_domain(domain, port) | 
					
						
							| 
									
										
										
										
											2021-03-17 20:18:00 +00:00
										 |  |  |     if debug: | 
					
						
							| 
									
										
										
										
											2021-12-26 10:00:46 +00:00
										 |  |  |         print('PGP test domain: ' + domain_full) | 
					
						
							| 
									
										
										
										
											2021-03-17 20:18:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-26 10:00:46 +00:00
										 |  |  |     handle = nickname + '@' + domain_full | 
					
						
							| 
									
										
										
										
											2021-03-17 20:18:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if debug: | 
					
						
							|  |  |  |         print('Getting actor for ' + handle) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |     actor_json, _ = \ | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |         get_actor_json(domain_full, handle, False, False, debug, True, | 
					
						
							|  |  |  |                        signing_priv_key_pem, session) | 
					
						
							| 
									
										
										
										
											2021-12-26 10:29:52 +00:00
										 |  |  |     if not actor_json: | 
					
						
							| 
									
										
										
										
											2021-03-17 20:18:00 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('No actor returned for ' + handle) | 
					
						
							|  |  |  |         return None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if debug: | 
					
						
							|  |  |  |         print('Actor for ' + handle + ' obtained') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-26 10:19:59 +00:00
										 |  |  |     actor = local_actor_url(http_prefix, nickname, domain_full) | 
					
						
							| 
									
										
										
										
											2021-12-26 17:21:37 +00:00
										 |  |  |     handle = replace_users_with_at(actor) | 
					
						
							| 
									
										
										
										
											2021-03-17 20:18:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # check that this looks like the correct actor | 
					
						
							| 
									
										
										
										
											2021-12-26 10:29:52 +00:00
										 |  |  |     if not actor_json.get('id'): | 
					
						
							| 
									
										
										
										
											2021-03-17 20:18:00 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('Actor has no id') | 
					
						
							|  |  |  |         return None | 
					
						
							| 
									
										
										
										
											2021-12-26 10:29:52 +00:00
										 |  |  |     if not actor_json.get('url'): | 
					
						
							| 
									
										
										
										
											2021-03-17 20:18:00 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('Actor has no url') | 
					
						
							|  |  |  |         return None | 
					
						
							| 
									
										
										
										
											2021-12-26 10:29:52 +00:00
										 |  |  |     if not actor_json.get('type'): | 
					
						
							| 
									
										
										
										
											2021-03-17 20:18:00 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('Actor has no type') | 
					
						
							|  |  |  |         return None | 
					
						
							| 
									
										
										
										
											2021-12-26 10:29:52 +00:00
										 |  |  |     if actor_json['id'] != actor: | 
					
						
							| 
									
										
										
										
											2021-03-17 20:18:00 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('Actor id is not ' + actor + | 
					
						
							| 
									
										
										
										
											2021-12-26 10:29:52 +00:00
										 |  |  |                   ' instead is ' + actor_json['id']) | 
					
						
							| 
									
										
										
										
											2021-03-17 20:18:00 +00:00
										 |  |  |         return None | 
					
						
							| 
									
										
										
										
											2021-12-26 10:29:52 +00:00
										 |  |  |     if actor_json['url'] != handle: | 
					
						
							| 
									
										
										
										
											2021-03-17 20:18:00 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('Actor url is not ' + handle) | 
					
						
							|  |  |  |         return None | 
					
						
							| 
									
										
										
										
											2021-12-26 10:29:52 +00:00
										 |  |  |     if actor_json['type'] != 'Person': | 
					
						
							| 
									
										
										
										
											2021-03-17 20:18:00 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('Actor type is not Person') | 
					
						
							|  |  |  |         return None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # set the pgp details | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |     if pgp_pub_key_id: | 
					
						
							|  |  |  |         set_pgp_fingerprint(actor_json, pgp_pub_key_id) | 
					
						
							| 
									
										
										
										
											2021-03-17 20:18:00 +00:00
										 |  |  |     else: | 
					
						
							|  |  |  |         if debug: | 
					
						
							|  |  |  |             print('No PGP key Id. Continuing anyway.') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if debug: | 
					
						
							|  |  |  |         print('Setting PGP key within ' + actor) | 
					
						
							| 
									
										
										
										
											2021-12-31 18:11:17 +00:00
										 |  |  |     set_pgp_pub_key(actor_json, pgp_pub_key) | 
					
						
							| 
									
										
										
										
											2021-03-17 20:18:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # create an actor update | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |     status_number, _ = get_status_number() | 
					
						
							|  |  |  |     actor_update = { | 
					
						
							| 
									
										
										
										
											2021-03-17 20:18:00 +00:00
										 |  |  |         '@context': 'https://www.w3.org/ns/activitystreams', | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |         'id': actor + '#updates/' + status_number, | 
					
						
							| 
									
										
										
										
											2021-03-17 20:18:00 +00:00
										 |  |  |         'type': 'Update', | 
					
						
							|  |  |  |         'actor': actor, | 
					
						
							|  |  |  |         'to': [actor], | 
					
						
							|  |  |  |         'cc': [], | 
					
						
							| 
									
										
										
										
											2021-12-26 10:29:52 +00:00
										 |  |  |         'object': actor_json | 
					
						
							| 
									
										
										
										
											2021-03-17 20:18:00 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     if debug: | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |         print('actor update is ' + str(actor_update)) | 
					
						
							| 
									
										
										
										
											2021-03-17 20:18:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # lookup the inbox for the To handle | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     wf_request = \ | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |         webfinger_handle(session, handle, http_prefix, cached_webfingers, | 
					
						
							|  |  |  |                          domain, __version__, debug, False, | 
					
						
							|  |  |  |                          signing_priv_key_pem) | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     if not wf_request: | 
					
						
							| 
									
										
										
										
											2021-03-17 20:18:00 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: pgp actor update webfinger failed for ' + | 
					
						
							|  |  |  |                   handle) | 
					
						
							|  |  |  |         return None | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     if not isinstance(wf_request, dict): | 
					
						
							| 
									
										
										
										
											2021-03-17 20:18:00 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('WARN: Webfinger for ' + handle + | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                   ' did not return a dict. ' + str(wf_request)) | 
					
						
							| 
									
										
										
										
											2021-03-17 20:18:00 +00:00
										 |  |  |         return None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |     post_to_box = 'outbox' | 
					
						
							| 
									
										
										
										
											2021-03-17 20:18:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # get the actor inbox for the To handle | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |     origin_domain = domain | 
					
						
							|  |  |  |     (inbox_url, _, _, from_person_id, _, _, | 
					
						
							|  |  |  |      _, _) = get_person_box(signing_priv_key_pem, origin_domain, | 
					
						
							|  |  |  |                             base_dir, session, wf_request, | 
					
						
							|  |  |  |                             person_cache, | 
					
						
							|  |  |  |                             __version__, http_prefix, nickname, | 
					
						
							|  |  |  |                             domain, post_to_box, 35725) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if not inbox_url: | 
					
						
							| 
									
										
										
										
											2021-03-17 20:18:00 +00:00
										 |  |  |         if debug: | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |             print('DEBUG: No ' + post_to_box + ' was found for ' + handle) | 
					
						
							| 
									
										
										
										
											2021-03-17 20:18:00 +00:00
										 |  |  |         return None | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |     if not from_person_id: | 
					
						
							| 
									
										
										
										
											2021-03-17 20:18:00 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: No actor was found for ' + handle) | 
					
						
							|  |  |  |         return None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |     auth_header = create_basic_auth_header(nickname, password) | 
					
						
							| 
									
										
										
										
											2021-03-17 20:18:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     headers = { | 
					
						
							|  |  |  |         'host': domain, | 
					
						
							|  |  |  |         'Content-type': 'application/json', | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |         'Authorization': auth_header | 
					
						
							| 
									
										
										
										
											2021-03-17 20:18:00 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     quiet = not debug | 
					
						
							| 
									
										
										
										
											2021-03-17 21:23:52 +00:00
										 |  |  |     tries = 0 | 
					
						
							| 
									
										
										
										
											2021-03-17 20:18:00 +00:00
										 |  |  |     while tries < 4: | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |         post_result = \ | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |             post_json(http_prefix, domain_full, | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |                       session, actor_update, [], inbox_url, | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                       headers, 5, quiet) | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |         if post_result: | 
					
						
							| 
									
										
										
										
											2021-03-17 20:18:00 +00:00
										 |  |  |             break | 
					
						
							|  |  |  |         tries += 1 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |     if post_result is None: | 
					
						
							| 
									
										
										
										
											2021-03-17 20:18:00 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: POST pgp actor update failed for c2s to ' + | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |                   inbox_url) | 
					
						
							| 
									
										
										
										
											2021-03-17 20:18:00 +00:00
										 |  |  |         return None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if debug: | 
					
						
							|  |  |  |         print('DEBUG: c2s POST pgp actor update success') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-03 15:06:00 +00:00
										 |  |  |     return actor_update |