@@ -9,6 +9,7 @@ import com.coder.toolbox.cli.ex.MissingVersionException
9
9
import com.coder.toolbox.cli.ex.SSHConfigFormatException
10
10
import com.coder.toolbox.cli.ex.UnsignedBinaryExecutionDeniedException
11
11
import com.coder.toolbox.cli.gpg.GPGVerifier
12
+ import com.coder.toolbox.cli.gpg.VerificationResult
12
13
import com.coder.toolbox.cli.gpg.VerificationResult.Failed
13
14
import com.coder.toolbox.cli.gpg.VerificationResult.Invalid
14
15
import com.coder.toolbox.sdk.v2.models.Workspace
@@ -221,26 +222,21 @@ class CoderCLIManager(
221
222
}
222
223
223
224
else -> {
224
- val exception = when {
225
- result.isInvalid() -> {
226
- val reason = (result as Invalid ).reason
227
- UnsignedBinaryExecutionDeniedException (
228
- " Signature of ${cliResult.dst} is invalid." + reason?.let { " Reason: $it " }
229
- .orEmpty()
230
- )
231
- }
232
-
233
- result.signatureIsNotFound() -> {
234
- UnsignedBinaryExecutionDeniedException (
235
- " Can't verify signature of ${cliResult.dst} because ${signatureResult.dst} does not exist"
236
- )
237
- }
238
-
239
- else -> {
240
- UnsignedBinaryExecutionDeniedException ((result as Failed ).error.message)
241
- }
225
+ logFailure(result, cliResult, signatureResult)
226
+ // prompt the user if he wants to accept the risk
227
+ val shouldRunAnyway = context.ui.showYesNoPopup(
228
+ context.i18n.ptrl(" Security Warning" ),
229
+ context.i18n.pnotr(" Could not verify the authenticity of the ${cliResult.source} , it may be tampered with. Would you like to run it anyway?" ),
230
+ context.i18n.ptrl(" Run anyway" ),
231
+ context.i18n.ptrl(" Abort" ),
232
+ )
233
+
234
+ if (shouldRunAnyway) {
235
+ downloader.commit()
236
+ return true
237
+ } else {
238
+ throw UnsignedBinaryExecutionDeniedException (" Running unverified CLI from ${cliResult.source} was denied by the user" )
242
239
}
243
- throw exception
244
240
}
245
241
}
246
242
}
@@ -249,6 +245,30 @@ class CoderCLIManager(
249
245
}
250
246
}
251
247
248
+ private fun logFailure (
249
+ result : VerificationResult ,
250
+ cliResult : Downloaded ,
251
+ signatureResult : Downloaded
252
+ ) {
253
+ when {
254
+ result.isInvalid() -> {
255
+ val reason = (result as Invalid ).reason
256
+ context.logger.error(" Signature of ${cliResult.dst} is invalid." + reason?.let { " Reason: $it " }
257
+ .orEmpty())
258
+ }
259
+
260
+ result.signatureIsNotFound() -> {
261
+ context.logger.error(" Can't verify signature of ${cliResult.dst} because ${signatureResult.dst} does not exist" )
262
+ }
263
+
264
+ else -> {
265
+ UnsignedBinaryExecutionDeniedException ((result as Failed ).error.message)
266
+ val failure = result as DownloadResult .Failed
267
+ context.logger.error(failure.error, " Failed to verify signature for ${cliResult.dst} " )
268
+ }
269
+ }
270
+ }
271
+
252
272
/* *
253
273
* Use the provided token to initializeSession the CLI.
254
274
*/
0 commit comments