2525# Unless the URL is an absolute URL, use this prefix to complete the URL.
2626BASE_URL = "https://storage.googleapis.com/greenlight-artifacts/cln"
2727MANIFEST_URL = f"{ BASE_URL } /manifest.json"
28- PUBKEY_FINGERPRINT = "0976C14E5F02F4EE03210680F1F616F50DD92681 "
28+ PUBKEY_FINGERPRINT = "0FB52698B085B96B53F898DAEE90C7135881CA0C "
2929PUBKEY_URL = f"{ BASE_URL } /{ PUBKEY_FINGERPRINT } .pub"
3030_LIGHTNINGD_REL_PATH = Path ("usr/local/bin/lightningd" )
3131_BIN_REL_PATH = Path ("usr/local/bin" )
32-
32+ GPG_OPTS = [ '--no-default-keyring' , '--keyring=/tmp/clnvm-keyring.gpg' ]
3333
3434@dataclass
3535class VersionDescriptor :
@@ -42,6 +42,42 @@ class VersionDescriptor:
4242logger = logging .getLogger (__name__ )
4343
4444
45+ def _get_cache_dir ():
46+ cln_cache_dir = os .environ .get ("CLNVM_CACHE_DIR" )
47+ if cln_cache_dir is not None :
48+ return Path (cln_cache_dir ).resolve ()
49+
50+ xdg_cache_home = os .environ .get ("XDG_CACHE_HOME" )
51+ if xdg_cache_home is not None :
52+ return Path (xdg_cache_home ).resolve () / "clnvm"
53+
54+ else :
55+ return Path ("~/.cache" ).expanduser ().resolve () / "clnvm"
56+
57+ def _ensure_pubkey ():
58+ """Ensure we have the pubkey that signs the releases in the cache.
59+
60+ Download if we don't yet.
61+ """
62+ fpath = _get_cache_dir ()
63+ pubkey_path = fpath / f"{ PUBKEY_FINGERPRINT } .asc"
64+ if not pubkey_path .exists ():
65+ logger .debug ("Fetching public key from %s" , PUBKEY_URL )
66+ pubkey_response = requests .get (PUBKEY_URL )
67+ if pubkey_response .status_code != 200 :
68+ raise ValueError (
69+ f"Failed to fetch public key: { pubkey_response .status_code } "
70+ )
71+ with Path (pubkey_path ).open (mode = "w" ) as f :
72+ f .write (pubkey_response .text )
73+ try :
74+ subprocess .check_call (["gpg" , * GPG_OPTS , "--import" , pubkey_path ])
75+ except :
76+ raise SignatureVerificationFailed (tag = tag , reason = "Failed to import public key" )
77+ logger .debug ("Imported public key." )
78+
79+ return pubkey_path
80+
4581def _verify_signature (
4682 file_path : Path ,
4783 signature : str ,
@@ -62,31 +98,13 @@ def _verify_signature(
6298 """
6399 logger .debug ("Verifying GPG signature for version %s" , tag )
64100
65- # Create a temporary GPG keyring
66- logger .debug ("Fetching public key from %s" , PUBKEY_URL )
67- pubkey_response = requests .get (PUBKEY_URL )
68- if pubkey_response .status_code != 200 :
69- raise SignatureVerificationFailed (
70- tag = tag , reason = f"Failed to fetch public key: { pubkey_response .status_code } "
71- )
72-
73- pubkey_data = pubkey_response .text
74- pubkey_path = file_path .parent / "pubkey.pem"
75- with Path (pubkey_path ).open (mode = "w" ) as f :
76- f .write (pubkey_data )
77-
78- try :
79- subprocess .check_call (["gpg" , "--import" , pubkey_path ])
80- except :
81- raise SignatureVerificationFailed (tag = tag , reason = "Failed to import public key" )
82- logger .debug ("Imported public key." )
83-
101+ pubkey_path = _ensure_pubkey ()
84102 sig_file = Path (file_path .parent / "signature.asc" )
85103 with sig_file .open (mode = "w" ) as f :
86104 f .write (signature )
87105
88106 try :
89- subprocess .check_call (["gpg" , "--verify" , sig_file , file_path ])
107+ subprocess .check_call (["gpg" , * GPG_OPTS , "--verify" , sig_file , file_path ])
90108 except Exception as e :
91109 raise SignatureVerificationFailed (
92110 tag = tag , reason = f"Invalid signature: { repr (e )} "
@@ -104,17 +122,7 @@ def _get_cln_version_path(cln_path: Optional[PathLike] = None) -> Path:
104122 """
105123 if cln_path is not None :
106124 return Path (cln_path ).resolve ()
107-
108- cln_cache_dir = os .environ .get ("CLNVM_CACHE_DIR" )
109- if cln_cache_dir is not None :
110- return Path (cln_cache_dir ).resolve ()
111-
112- xdg_cache_home = os .environ .get ("XDG_CACHE_HOME" )
113- if xdg_cache_home is not None :
114- return Path (xdg_cache_home ).resolve () / "clnvm"
115-
116- else :
117- return Path ("~/.cache" ).expanduser ().resolve () / "clnvm"
125+ return _get_cache_dir ()
118126
119127
120128class ClnVersionManager :
0 commit comments