certificate provider

Summary: _typescript_

Reviewed By: passy

Differential Revision: D17096517

fbshipit-source-id: a6e69e8b9a82fe76bb1de51a3a93182f35f40b3f
This commit is contained in:
Daniel Büchele
2019-08-28 20:33:23 -07:00
committed by Facebook Github Bot
parent 9970c50daf
commit 5868946818
25 changed files with 81 additions and 38 deletions

View File

@@ -61,6 +61,7 @@
"@types/react-window": "^1.8.1",
"@types/redux-persist": "^4.3.1",
"@types/rsocket-core": "^0.0.2",
"@types/tmp": "^0.1.0",
"@types/uuid": "^3.4.5",
"@typescript-eslint/eslint-plugin": "^1.11.0",
"@typescript-eslint/parser": "^1.13.0",

View File

@@ -32,7 +32,7 @@ import {
ACTIVE_SHEET_SELECT_PLUGINS_TO_EXPORT,
ACTIVE_SHEET_PLUGIN_SHEET,
} from './reducers/application';
import {Logger} from './fb-interfaces/Logger.js';
import {Logger} from './fb-interfaces/Logger';
import BugReporter from './fb-stubs/BugReporter';
import BaseDevice from './devices/BaseDevice';
import {State as Store} from './reducers/index';

View File

@@ -8,7 +8,7 @@
import {FlipperPlugin, FlipperDevicePlugin} from './plugin';
import BaseDevice, {OS} from './devices/BaseDevice';
import {App} from './App.js';
import {Logger} from './fb-interfaces/Logger.js';
import {Logger} from './fb-interfaces/Logger';
import {Store} from './reducers/index';
import {setPluginState} from './reducers/pluginStates';
import {RSocketClientSocket} from 'rsocket-core/RSocketClient';

View File

@@ -18,7 +18,7 @@ import {
} from 'flipper';
import React, {Component} from 'react';
import {setExportStatusComponent, unsetShare} from '../reducers/application';
import {Logger} from '../fb-interfaces/Logger.js';
import {Logger} from '../fb-interfaces/Logger';
import {Idler} from '../utils/Idler';
import {shareFlipperData, DataExportResult} from '../fb-stubs/user';
import {exportStore, EXPORT_FLIPPER_TRACE_EVENT} from '../utils/exportData';

View File

@@ -19,7 +19,7 @@ import {setExportStatusComponent, unsetShare} from '../reducers/application';
import {reportPlatformFailures} from '../utils/metrics';
import CancellableExportStatus from './CancellableExportStatus';
import {performance} from 'perf_hooks';
import {Logger} from '../fb-interfaces/Logger.js';
import {Logger} from '../fb-interfaces/Logger';
import {Idler} from '../utils/Idler';
import {
exportStoreToFile,

View File

@@ -9,7 +9,7 @@ import AndroidDevice from '../devices/AndroidDevice';
import child_process from 'child_process';
import {Store} from '../reducers/index';
import BaseDevice from '../devices/BaseDevice';
import {Logger} from '../fb-interfaces/Logger.js';
import {Logger} from '../fb-interfaces/Logger';
import {registerDeviceCallbackOnPlugins} from '../utils/onRegisterDevice';
import {getAdbClient} from '../utils/adbClient';
import {default as which} from 'which';

View File

@@ -8,7 +8,7 @@
import {remote, ipcRenderer} from 'electron';
import {toggleAction} from '../reducers/application';
import {Store} from '../reducers/index.js';
import {Logger} from '../fb-interfaces/Logger.js';
import {Logger} from '../fb-interfaces/Logger';
import {parseFlipperPorts} from '../utils/environmentVariables';
import {
importDataToStore,

View File

@@ -6,7 +6,7 @@
*/
import {Store} from '../reducers/index';
import {Logger} from '../fb-interfaces/Logger.js';
import {Logger} from '../fb-interfaces/Logger';
import MacDevice from '../devices/MacDevice';
import WindowsDevice from '../devices/WindowsDevice';

View File

@@ -7,7 +7,7 @@
import {ChildProcess} from 'child_process';
import {Store} from '../reducers/index';
import {Logger} from '../fb-interfaces/Logger.js';
import {Logger} from '../fb-interfaces/Logger';
import {DeviceType} from '../devices/BaseDevice';
import {promisify} from 'util';
import path from 'path';

View File

@@ -15,7 +15,7 @@ import notifications from './notifications';
import plugins from './plugins';
import user from './user';
import {Logger} from '../fb-interfaces/Logger.js';
import {Logger} from '../fb-interfaces/Logger';
import {Store} from '../reducers/index';
import {Dispatcher} from './types';

View File

@@ -6,7 +6,7 @@
*/
import {Store} from '../reducers/index';
import {Logger} from '../fb-interfaces/Logger.js';
import {Logger} from '../fb-interfaces/Logger';
import {PluginNotification} from '../reducers/notifications';
import {FlipperPlugin, FlipperDevicePlugin} from '../plugin';
import isHeadless from '../utils/isHeadless';

View File

@@ -6,7 +6,7 @@
*/
import {Store} from '../reducers/index';
import {Logger} from '../fb-interfaces/Logger.js';
import {Logger} from '../fb-interfaces/Logger';
import {FlipperPlugin, FlipperDevicePlugin} from '../plugin';
import {State} from '../reducers/plugins';
import React from 'react';

View File

@@ -8,7 +8,7 @@
import Server from '../server';
import {Store} from '../reducers/index';
import {Logger} from '../fb-interfaces/Logger.js';
import {Logger} from '../fb-interfaces/Logger';
import Client from '../Client.js';
import {UninitializedClient} from '../UninitializedClient';

View File

@@ -10,7 +10,7 @@ import {ipcRenderer} from 'electron';
import {performance} from 'perf_hooks';
import {Store} from '../reducers/index';
import {Logger} from '../fb-interfaces/Logger.js';
import {Logger} from '../fb-interfaces/Logger';
import Client from '../Client';
export default (store: Store, logger: Logger) => {

View File

@@ -6,7 +6,7 @@
*/
import {Store} from '../reducers/index';
import {Logger} from '../fb-interfaces/Logger.js';
import {Logger} from '../fb-interfaces/Logger';
import {login} from '../reducers/user';
import {getUser, logoutUser} from '../fb-stubs/user';

View File

@@ -14,9 +14,9 @@ export type TrackType =
| 'operation-cancelled';
export interface Logger {
track(type: TrackType, event: string, data: ?any, plugin?: string): void;
track(type: TrackType, event: string, data?: any, plugin?: string): void;
trackTimeSince(mark: string, eventName: ?string): void;
trackTimeSince(mark: string, eventName?: string | null | undefined): void;
info(data: any, category: string): void;

View File

@@ -10,7 +10,7 @@ export type ScribeMessage = {
message: string;
};
import {Logger} from '../fb-interfaces/Logger.js';
import {Logger} from '../fb-interfaces/Logger';
export default class ScribeLogger {
constructor(logger: Logger) {}

View File

@@ -7,7 +7,7 @@
import {KeyboardActions} from './MenuBar';
import {App} from './App';
import {Logger} from './fb-interfaces/Logger.js';
import {Logger} from './fb-interfaces/Logger';
import Client from './Client';
import {Store, MiddlewareAPI} from './reducers/index';
import {MetricType} from './utils/exportMetrics';

View File

@@ -8,7 +8,7 @@
import type {Element} from 'flipper';
import type {PluginClient} from 'flipper';
import type Client from '../../Client.tsx';
import type {Logger} from '../../fb-interfaces/Logger.js';
import type {Logger} from '../../fb-interfaces/Logger.tsx';
import {
ManagedDataInspector,

View File

@@ -8,7 +8,7 @@
import {Element} from './ElementsInspector';
import {PluginClient} from '../../../plugin';
import Client from '../../../Client';
import {Logger} from '../../../fb-interfaces/Logger.js';
import {Logger} from '../../../fb-interfaces/Logger';
import Panel from '../Panel';
import ManagedDataInspector from '../data-inspector/ManagedDataInspector';
import {Component} from 'react';

View File

@@ -14,16 +14,19 @@ import {
isInstalled as opensslInstalled,
} from './openssl-wrapper-with-promises';
import path from 'path';
import tmp from 'tmp';
const tmpFile = promisify(tmp.file);
const tmpDir = promisify(tmp.dir);
import tmp, {DirOptions, FileOptions} from 'tmp';
import iosUtil from '../fb-stubs/iOSContainerUtility';
import {reportPlatformFailures} from './metrics';
import {getAdbClient} from './adbClient';
import * as androidUtil from './androidContainerUtility';
import os from 'os';
const tmpFile = promisify(tmp.file) as (
options?: FileOptions,
) => Promise<string>;
const tmpDir = promisify(tmp.dir) as (options?: DirOptions) => Promise<string>;
// Desktop file paths
const os = require('os');
const caKey = getFilePath('ca.key');
const caCert = getFilePath('ca.crt');
const serverKey = getFilePath('server.key');
@@ -398,7 +401,7 @@ export default class CertificateProvider {
}),
)
.then(([path, subject]) => {
return new Promise(function(resolve, reject) {
return new Promise<string>(function(resolve, reject) {
fs.unlink(path, err => {
if (err) {
reject(err);
@@ -408,7 +411,7 @@ export default class CertificateProvider {
});
});
})
.then((subject: string) => {
.then(subject => {
const matches = subject.trim().match(x509SubjectCNRegex);
if (!matches || matches.length < 2) {
throw new Error(`Cannot extract CN from ${subject}`);
@@ -441,14 +444,14 @@ export default class CertificateProvider {
if (!fs.existsSync(caKey)) {
return this.generateCertificateAuthority();
}
return this.checkCertIsValid(caCert).catch(e =>
return this.checkCertIsValid(caCert).catch(() =>
this.generateCertificateAuthority(),
);
}
checkCertIsValid(filename: string): Promise<void> {
if (!fs.existsSync(filename)) {
return Promise.reject();
return Promise.reject(new Error(`${filename} does not exist`));
}
// openssl checkend is a nice feature but it only checks for certificates
// expiring in the future, not those that have already expired.
@@ -459,7 +462,7 @@ export default class CertificateProvider {
checkend: minCertExpiryWindowSeconds,
in: filename,
})
.then(output => undefined)
.then(() => undefined)
.catch(e => {
console.warn(`Certificate will expire soon: ${filename}`, logTag);
throw e;
@@ -492,7 +495,9 @@ export default class CertificateProvider {
}
verifyServerCertWasIssuedByCA() {
const options = {CAfile: caCert};
const options: {
[key: string]: any;
} = {CAfile: caCert};
options[serverCert] = false;
return openssl('verify', options).then(output => {
const verified = output.match(/[^:]+: OK/);
@@ -534,8 +539,8 @@ export default class CertificateProvider {
}
return this.checkCertIsValid(serverCert)
.then(_ => this.verifyServerCertWasIssuedByCA())
.catch(e => this.generateServerCertificate());
.then(() => this.verifyServerCertWasIssuedByCA())
.catch(() => this.generateServerCertificate());
}
generateServerCertificate(): Promise<void> {
@@ -567,7 +572,7 @@ export default class CertificateProvider {
}
writeToTempFile(content: string): Promise<string> {
return tmpFile().then((path, fd, cleanupCallback) =>
return tmpFile().then(path =>
promisify(fs.writeFile)(path, content).then(_ => path),
);
}

View File

@@ -10,12 +10,16 @@ import {promisify} from 'util';
import {crashReporter, remote} from 'electron';
import isProduction from '../utils/isProduction';
import constants from '../fb-stubs/constants';
import {tmpName} from 'tmp';
import {tmpName as tmpNameCallback, TmpNameOptions} from 'tmp';
import {resolve} from 'path';
const tmpName = promisify(tmpNameCallback) as (
options?: TmpNameOptions,
) => Promise<string>;
// Cross platform way to find the /tmp directory or equivalent.
// The tempPath set should be persistent across app restarts.
const tempPathPromise: Promise<string> = promisify(tmpName)({
const tempPathPromise: Promise<string> = tmpName({
template: '/tmp/tmp-XXXXXX',
}).then(name => resolve(name, '..', 'flipper'));

View File

@@ -5,16 +5,17 @@
* @format
*/
import {exec as opensslWithCallback} from 'openssl-wrapper';
import {exec as opensslWithCallback, Action} from 'openssl-wrapper';
import child_process from 'child_process';
export function openssl(action: string, options: {}): Promise<string> {
export function openssl(action: Action, options: {}): Promise<string> {
return new Promise((resolve, reject) => {
opensslWithCallback(action, options, (err, buffer) => {
if (err) {
reject(err);
}
} else if (buffer) {
resolve(buffer.toString());
}
});
});
}

View File

@@ -0,0 +1,27 @@
/**
* Copyright 2018-present Facebook.
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
* @format
*/
declare module 'openssl-wrapper' {
export type Action =
| 'cms.verify'
| 'genrsa'
| 'pkcs12'
| 'req'
| 'req.new'
| 'req.verify'
| 'verify'
| 'rsa'
| 'smime.verify'
| 'x509.req'
| 'x509';
export function exec(
action: Action,
options: {[key: string]: string},
cb: (error: Error | undefined, buffer: Buffer | undefined) => any,
): void;
}

View File

@@ -1279,6 +1279,11 @@
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e"
integrity sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==
"@types/tmp@^0.1.0":
version "0.1.0"
resolved "https://registry.yarnpkg.com/@types/tmp/-/tmp-0.1.0.tgz#19cf73a7bcf641965485119726397a096f0049bd"
integrity sha512-6IwZ9HzWbCq6XoQWhxLpDjuADodH/MKXRUIDFudvgjcVdjFknvmR+DNsoUeer4XPrEnrZs04Jj+kfV9pFsrhmA==
"@types/uuid@^3.4.5":
version "3.4.5"
resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-3.4.5.tgz#d4dc10785b497a1474eae0ba7f0cb09c0ddfd6eb"