Skip to content

Commit

Permalink
Add codeql-action/start-proxy
Browse files Browse the repository at this point in the history
  • Loading branch information
aibaars committed Jul 24, 2024
1 parent 5669f66 commit 7b43b7c
Show file tree
Hide file tree
Showing 7 changed files with 386 additions and 0 deletions.
45 changes: 45 additions & 0 deletions lib/start-proxy-action-post.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions lib/start-proxy-action-post.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

140 changes: 140 additions & 0 deletions lib/start-proxy-action.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions lib/start-proxy-action.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 23 additions & 0 deletions src/start-proxy-action-post.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* This file is the entry point for the `post:` hook of `start-proxy-action.yml`.
* It will run after the all steps in this job, in reverse order in relation to
* other `post:` hooks.
*/
import * as core from "@actions/core";

import { wrapError } from "./util";

async function runWrapper() {
try {
const pid = core.getState("proxy-process-pid");
if (pid) {
process.kill(Number(pid));
}
} catch (error) {
core.setFailed(
`start-proxy post-action step failed: ${wrapError(error).message}`,
);
}
}

void runWrapper();
154 changes: 154 additions & 0 deletions src/start-proxy-action.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
import { ChildProcess, spawn } from "child_process";
import * as path from "path";

import * as core from "@actions/core";
import { pki } from "node-forge";

import * as actionsUtil from "./actions-util";
import * as util from "./util";

const PROXY_USER = "proxy_user";
const KEY_SIZE = 2048;
const KEY_EXPIRY_YEARS = 2;

export type CertificateAuthority = {
cert: string;
key: string;
};

export type Credential = {
type: string;
host: string;
username?: string;
password?: string;
token?: string;
};

export type BasicAuthCredentials = {
username: string;
password: string;
};

export type ProxyConfig = {
all_credentials: Credential[];
ca: CertificateAuthority;
proxy_auth?: BasicAuthCredentials;
};

const CERT_SUBJECT = [
{
name: "commonName",
value: "Dependabot Internal CA",
},
{
name: "organizationName",
value: "GitHub ic.",
},
{
shortName: "OU",
value: "Dependabot",
},
{
name: "countryName",
value: "US",
},
{
shortName: "ST",
value: "California",
},
{
name: "localityName",
value: "San Francisco",
},
];

function generateCertificateAuthority(): CertificateAuthority {
const keys = pki.rsa.generateKeyPair(KEY_SIZE);
const cert = pki.createCertificate();
cert.publicKey = keys.publicKey;
cert.serialNumber = "01";
cert.validity.notBefore = new Date();
cert.validity.notAfter = new Date();
cert.validity.notAfter.setFullYear(
cert.validity.notBefore.getFullYear() + KEY_EXPIRY_YEARS,
);

cert.setSubject(CERT_SUBJECT);
cert.setIssuer(CERT_SUBJECT);
cert.setExtensions([{ name: "basicConstraints", cA: true }]);
cert.sign(keys.privateKey);

const pem = pki.certificateToPem(cert);
const key = pki.privateKeyToPem(keys.privateKey);
return { cert: pem, key };
}

async function runWrapper() {
const tempDir = actionsUtil.getTemporaryDirectory();
const logFilePath = path.resolve(tempDir, "proxy.log");
const input = actionsUtil.getOptionalInput("registry_secrets") || "[]";
const credentials = JSON.parse(input) as Credential[];
const ca = generateCertificateAuthority();
const proxy_password = actionsUtil.getOptionalInput("proxy_password");
let proxy_auth: BasicAuthCredentials | undefined = undefined;
if (proxy_password) {
core.setSecret(proxy_password);
proxy_auth = {
username: PROXY_USER,
password: proxy_password,
};
}
const proxyConfig: ProxyConfig = {
all_credentials: credentials,
ca,
proxy_auth,
};
const host = "127.0.0.1";
const proxyBin = path.resolve(__dirname, "..", "bin", "update-job-proxy");
let port = 49152;
try {
let subprocess: ChildProcess | undefined = undefined;
let tries = 5;
let subprocessError: Error | undefined = undefined;
while (tries-- > 0 && !subprocess && !subprocessError) {
subprocess = spawn(
proxyBin,
["-addr", `${host}:${port}`, "-config", "-", "-logfile", logFilePath],
{
detached: true,
stdio: ["pipe", "ignore", "ignore"],
},
);
subprocess.unref();
if (subprocess.pid) {
core.saveState("proxy-process-pid", `${subprocess.pid}`);
}
subprocess.on("error", (error) => {
subprocessError = error;
});
subprocess.on("exit", (code) => {
if (code !== 0) {
port = Math.floor(Math.random() * (65535 - 49152) + 49152);
subprocess = undefined;
}
});
subprocess.stdin?.write(JSON.stringify(proxyConfig));
subprocess.stdin?.end();
// Wait a little to allow the proxy to start
await util.delay(1000);
}
if (subprocessError) {
throw subprocessError;
}
core.info(`Proxy started on ${host}:${port}`);
core.setOutput("proxy_host", host);
core.setOutput("proxy_port", port.toString());
core.setOutput("proxy_ca_certificate", ca.cert);
} catch (error) {
core.setFailed(
`start-proxy action failed: ${util.wrapError(error).message}`,
);
}
}

void runWrapper();
22 changes: 22 additions & 0 deletions start-proxy/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: "CodeQL: Start proxy"
description: "Start HTTP proxy server"
author: "GitHub"
inputs:
registry_secrets:
description: The URLs and credentials of package registries
required: false
default: "[]"
proxy_password:
required: false
description: The password of the proxy
outputs:
proxy_host:
description: The IP address of the proxy
proxy_port:
description: The port of the proxy
proxy_ca_certificate:
description: The proxy's internal CA certificate in PEM format
runs:
using: node20
main: "../lib/start-proxy-action.js"
post: "../lib/start-proxy-action-post.js"

0 comments on commit 7b43b7c

Please sign in to comment.