Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitcb3aae6

Browse files
authored
impl: verify cli signature (#148)
This PR introduces support for verifying the CLI binary using a detachedPGP signature. Starting with version 2.24, Coder signs all CLI binaries.For clients using older versions or running TBX in air-gappedenvironments, unsigned CLIs can still be executed — but users will haveto confirm it each time.In terms of code changes - the PR includes a big refactor around CLIdownloading with most of the code refactored and extracted in variouscomponents that provide clean steps and result state in the maindownload method. Then the pgp verification logic was added on top, withsome particularities:- the pgp public key is embedded in the plugin as a jar resource- we support multiple key rings in the public key- the user has the option of running the CLI if no signature was found- the signature search has a fallback approach: first we look in theCoder deployment, and then fall back to releases.coder.com to search forthe signature if the user allows it.- we expect the signature to be under the same relative path as the CLI(we have an option which allows user to pick the CLI from a differentsource other than the Coder deployment)
1 parente02c866 commitcb3aae6

23 files changed

+1230
-322
lines changed

‎CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
###Added
66

77
- support for matching workspace agent in the URI via the agent name
8+
- support for checking if CLI is signed
89

910
###Removed
1011

‎build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ dependencies {
6363
ksp(libs.moshi.codegen)
6464
implementation(libs.retrofit)
6565
implementation(libs.retrofit.moshi)
66+
implementation(libs.bundles.bouncycastle)
6667
testImplementation(kotlin("test"))
6768
testImplementation(libs.mokk)
6869
testImplementation(libs.bundles.toolbox.plugin.api)

‎gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
version=0.4.0
1+
version=0.5.0
22
group=com.coder.toolbox
33
name=coder-toolbox

‎gradle/libs.versions.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ gettext = "0.7.0"
1616
plugin-structure ="3.310"
1717
mockk ="1.14.4"
1818
detekt ="1.23.8"
19+
bouncycastle ="1.81"
1920

2021
[libraries]
2122
toolbox-core-api = {module ="com.jetbrains.toolbox:core-api",version.ref ="toolbox-plugin-api" }
@@ -34,10 +35,13 @@ retrofit-moshi = { module = "com.squareup.retrofit2:converter-moshi", version.re
3435
plugin-structure = {module ="org.jetbrains.intellij.plugins:structure-toolbox",version.ref ="plugin-structure" }
3536
mokk = {module ="io.mockk:mockk",version.ref ="mockk" }
3637
marketplace-client = {module ="org.jetbrains.intellij:plugin-repository-rest-client",version.ref ="marketplace-client" }
38+
bouncycastle-bcpg = {module ="org.bouncycastle:bcpg-jdk18on",version.ref ="bouncycastle" }
39+
bouncycastle-bcprov = {module ="org.bouncycastle:bcprov-jdk18on",version.ref ="bouncycastle" }
3740

3841
[bundles]
3942
serialization = ["serialization-core","serialization-json","serialization-json-okio"]
4043
toolbox-plugin-api = ["toolbox-core-api","toolbox-ui-api","toolbox-remote-dev-api"]
44+
bouncycastle = ["bouncycastle-bcpg","bouncycastle-bcprov"]
4145

4246
[plugins]
4347
kotlin = {id ="org.jetbrains.kotlin.jvm",version.ref ="kotlin" }

‎src/main/kotlin/com/coder/toolbox/CoderRemoteProvider.kt

Lines changed: 40 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import kotlinx.coroutines.launch
3535
importkotlinx.coroutines.selects.onTimeout
3636
importkotlinx.coroutines.selects.select
3737
importjava.net.URI
38+
importjava.util.UUID
3839
importkotlin.coroutines.cancellation.CancellationException
3940
importkotlin.time.Duration.Companion.seconds
4041
importkotlin.time.TimeSource
@@ -302,31 +303,51 @@ class CoderRemoteProvider(
302303
* Handle incoming links (like from the dashboard).
303304
*/
304305
overridesuspendfunhandleUri(uri:URI) {
305-
linkHandler.handle(
306-
uri, shouldDoAutoSetup(),
307-
{
308-
coderHeaderPage.isBusyCreatingNewEnvironment.update {
309-
true
306+
try {
307+
linkHandler.handle(
308+
uri, shouldDoAutoSetup(),
309+
{
310+
coderHeaderPage.isBusyCreatingNewEnvironment.update {
311+
true
312+
}
313+
},
314+
{
315+
coderHeaderPage.isBusyCreatingNewEnvironment.update {
316+
false
317+
}
310318
}
311-
},
312-
{
313-
coderHeaderPage.isBusyCreatingNewEnvironment.update {
319+
) { restClient, cli->
320+
// stop polling and de-initialize resources
321+
close()
322+
isInitialized.update {
314323
false
315324
}
325+
// start initialization with the new settings
326+
this@CoderRemoteProvider.client= restClient
327+
coderHeaderPage.setTitle(context.i18n.pnotr(restClient.url.toString()))
328+
329+
environments.showLoadingMessage()
330+
pollJob= poll(restClient, cli)
331+
isInitialized.waitForTrue()
316332
}
317-
) { restClient, cli->
318-
// stop polling and de-initialize resources
319-
close()
320-
isInitialized.update {
333+
}catch (ex:Exception) {
334+
context.logger.error(ex,"")
335+
val textError=if (exisAPIResponseException) {
336+
if (!ex.reason.isNullOrBlank()) {
337+
ex.reason
338+
}else ex.message
339+
}else ex.message
340+
341+
context.ui.showSnackbar(
342+
UUID.randomUUID().toString(),
343+
context.i18n.ptrl("Error encountered while handling Coder URI"),
344+
context.i18n.pnotr(textError?:""),
345+
context.i18n.ptrl("Dismiss")
346+
)
347+
}finally {
348+
coderHeaderPage.isBusyCreatingNewEnvironment.update {
321349
false
322350
}
323-
// start initialization with the new settings
324-
this@CoderRemoteProvider.client= restClient
325-
coderHeaderPage.setTitle(context.i18n.pnotr(restClient.url.toString()))
326-
327-
environments.showLoadingMessage()
328-
pollJob= poll(restClient, cli)
329-
isInitialized.waitForTrue()
330351
}
331352
}
332353

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp