Improve "Add New Host" dialog (#8)
- Allow download of enroll secret, server certificate, and flagfile. - Hosts can now be added following instructions directly.
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import FileSaver from 'file-saver';
|
||||
|
||||
import Button from 'components/buttons/Button';
|
||||
import enrollSecretInterface from 'interfaces/enroll_secret';
|
||||
@@ -35,6 +36,20 @@ class EnrollSecretRow extends Component {
|
||||
return false;
|
||||
}
|
||||
|
||||
onDownloadSecret = (evt) => {
|
||||
evt.preventDefault();
|
||||
|
||||
const { secret } = this.props;
|
||||
|
||||
const filename = 'secret.txt';
|
||||
const file = new global.window.File([secret], filename);
|
||||
|
||||
FileSaver.saveAs(file);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
onToggleSecret = (evt) => {
|
||||
evt.preventDefault();
|
||||
|
||||
@@ -47,7 +62,7 @@ class EnrollSecretRow extends Component {
|
||||
renderLabel = () => {
|
||||
const { name } = this.props;
|
||||
const { showSecret, copyMessage } = this.state;
|
||||
const { onCopySecret, onToggleSecret } = this;
|
||||
const { onCopySecret, onDownloadSecret, onToggleSecret } = this;
|
||||
|
||||
return (
|
||||
<span>
|
||||
@@ -61,6 +76,16 @@ class EnrollSecretRow extends Component {
|
||||
>
|
||||
<Icon name="clipboard" />
|
||||
</Button>
|
||||
|
|
||||
<a
|
||||
href="#onDownloadSecret"
|
||||
variant="unstyled"
|
||||
className={`${baseClass}__secret-download-icon`}
|
||||
onClick={onDownloadSecret}
|
||||
>
|
||||
Download
|
||||
</a>
|
||||
|
|
||||
<a
|
||||
href="#showSecret"
|
||||
onClick={onToggleSecret}
|
||||
|
||||
@@ -1,70 +1,155 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import FileSaver from 'file-saver';
|
||||
|
||||
import Kolide from 'kolide';
|
||||
import Button from 'components/buttons/Button';
|
||||
import configInterface from 'interfaces/config';
|
||||
import enrollSecretInterface from 'interfaces/enroll_secret';
|
||||
import EnrollSecretTable from 'components/config/EnrollSecretTable';
|
||||
import Icon from 'components/icons/Icon';
|
||||
import certificate from '../../../../assets/images/osquery-certificate.svg';
|
||||
|
||||
const baseClass = 'add-host-modal';
|
||||
|
||||
|
||||
class AddHostModal extends Component {
|
||||
static propTypes = {
|
||||
onFetchCertificate: PropTypes.func,
|
||||
onReturnToApp: PropTypes.func,
|
||||
enrollSecret: enrollSecretInterface,
|
||||
config: configInterface,
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = { fetchCertificateError: undefined };
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
Kolide.config.loadCertificate()
|
||||
.then((certificate) => {
|
||||
this.setState({ certificate });
|
||||
})
|
||||
.catch(() => {
|
||||
this.setState({ fetchCertificateError: 'Failed to load certificate. Is Fleet App URL configured properly?' });
|
||||
});
|
||||
}
|
||||
|
||||
onFetchCertificate = (evt) => {
|
||||
evt.preventDefault();
|
||||
|
||||
const { certificate } = this.state;
|
||||
|
||||
const filename = 'fleet.pem';
|
||||
const file = new global.window.File([certificate], filename, { type: 'application/x-pem-file' });
|
||||
|
||||
FileSaver.saveAs(file);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
onFetchCertificate,
|
||||
config,
|
||||
onReturnToApp,
|
||||
enrollSecret,
|
||||
} = this.props;
|
||||
|
||||
const { fetchCertificateError } = this.state;
|
||||
|
||||
let tlsHostname = config.kolide_server_url;
|
||||
try {
|
||||
const serverUrl = new URL(config.kolide_server_url);
|
||||
tlsHostname = serverUrl.hostname;
|
||||
if (serverUrl.port) {
|
||||
tlsHostname += `:${serverUrl.port}`;
|
||||
}
|
||||
} catch (e) {
|
||||
if (!(e instanceof TypeError)) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
const flagfileContent = `--enroll_secret_path=secret.txt
|
||||
--tls_server_certs=fleet.pem
|
||||
--tls_hostname=${tlsHostname}
|
||||
--host_identifier=uuid
|
||||
--enroll_tls_endpoint=/api/v1/osquery/enroll
|
||||
--config_plugin=tls
|
||||
--config_tls_endpoint=/api/v1/osquery/config
|
||||
--config_refresh=10
|
||||
--disable_distributed=false
|
||||
--distributed_plugin=tls
|
||||
--distributed_interval=10
|
||||
--distributed_tls_max_attempts=3
|
||||
--distributed_tls_read_endpoint=/api/v1/osquery/distributed/read
|
||||
--distributed_tls_write_endpoint=/api/v1/osquery/distributed/write
|
||||
--logger_plugin=tls
|
||||
--logger_tls_endpoint=/api/v1/osquery/log
|
||||
--logger_tls_period=10`;
|
||||
|
||||
const onDownloadFlagfile = (evt) => {
|
||||
evt.preventDefault();
|
||||
|
||||
const filename = 'flagfile.txt';
|
||||
const file = new global.window.File([flagfileContent], filename);
|
||||
|
||||
FileSaver.saveAs(file);
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={baseClass}>
|
||||
<p>
|
||||
Follow the instructions below to add hosts to your Fleet Instance.
|
||||
</p>
|
||||
|
||||
<div className={`${baseClass}__manual-install-content`}>
|
||||
<div className={`${baseClass}__documentation-link`}>
|
||||
<h4>
|
||||
<a
|
||||
href="https://github.com/kolide/fleet/blob/master/docs/infrastructure/adding-hosts-to-fleet.md"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
Add Hosts Documentation <Icon name="external-link" />
|
||||
</a>
|
||||
</h4>
|
||||
</div>
|
||||
<ol className={`${baseClass}__install-steps`}>
|
||||
<li>
|
||||
<h4>
|
||||
<a
|
||||
href="https://github.com/kolide/fleet/blob/master/docs/infrastructure/adding-hosts-to-fleet.md"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
Fleet / Osquery - Install Docs <Icon name="external-link" />
|
||||
</a>
|
||||
</h4>
|
||||
</li>
|
||||
<li>
|
||||
<h4>Osquery Enroll Secret</h4>
|
||||
<h4>1. Enroll Secret</h4>
|
||||
<p>
|
||||
Provide osquery with one of the following active enroll secrets:
|
||||
Provide an active enroll secret to allow osquery to authenticate with the Fleet server:
|
||||
</p>
|
||||
<div className={`${baseClass}__secret-wrapper`}>
|
||||
<EnrollSecretTable secrets={enrollSecret} />
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<h4>Download Server Certificate (Optional)</h4>
|
||||
<h4>2. Server Certificate</h4>
|
||||
<p>
|
||||
If you use the native osquery TLS plugins, Osquery requires the
|
||||
same TLS certificate that Fleet is using in order to
|
||||
authenticate. You can fetch the certificate below:
|
||||
Provide the TLS certificate used by the Fleet server to enable secure connections from osquery:
|
||||
</p>
|
||||
<p className={`${baseClass}__download-cert`}>
|
||||
<Button variant="unstyled" onClick={onFetchCertificate}>
|
||||
<img src={certificate} alt="" />
|
||||
<span>Fetch Fleet Certificate</span>
|
||||
</Button>
|
||||
<p>
|
||||
{ fetchCertificateError
|
||||
? <span className={`${baseClass}__error`}>{fetchCertificateError}</span>
|
||||
: <a href="#downloadCertificate" onClick={this.onFetchCertificate}>Download Certificate</a>
|
||||
}
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<h4>3. Flagfile</h4>
|
||||
<p>
|
||||
If using the enroll secret and server certificate downloaded above, use the generated flagfile. In some configurations, modifications may need to be made:
|
||||
</p>
|
||||
<p>
|
||||
<a href="#downloadFlagfile" onClick={onDownloadFlagfile}>Download Flagfile</a>
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<h4>4. Run Osquery</h4>
|
||||
<p>
|
||||
Run osquery from the directory containing the above files (may require sudo or Run as Administrator privileges):
|
||||
</p>
|
||||
<pre>osqueryd --flagfile=flagfile.txt --verbose</pre>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -46,14 +46,14 @@
|
||||
margin-left: 10px;
|
||||
padding: 20px;
|
||||
box-sizing: border-box;
|
||||
|
||||
|
||||
h4 {
|
||||
font-size: 16px;
|
||||
font-weight: $bold;
|
||||
line-height: 1.5;
|
||||
letter-spacing: -0.5px;
|
||||
color: rgba(32, 37, 50, 0.66);
|
||||
margin: 40px 0 0;
|
||||
margin: 10px 0 0;
|
||||
|
||||
.kolidecon {
|
||||
margin-left: 5px;
|
||||
@@ -75,6 +75,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
&__documentation-link {
|
||||
h4 {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&__install-steps {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
@@ -134,4 +140,14 @@
|
||||
color: $link;
|
||||
}
|
||||
}
|
||||
|
||||
pre, code {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
|
||||
&__error {
|
||||
color: $alert;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -2,14 +2,13 @@ import React, { PureComponent } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import AceEditor from 'react-ace';
|
||||
import { connect } from 'react-redux';
|
||||
import FileSaver from 'file-saver';
|
||||
import { push } from 'react-router-redux';
|
||||
import { sortBy } from 'lodash';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import Kolide from 'kolide';
|
||||
import AddHostModal from 'components/hosts/AddHostModal';
|
||||
import Button from 'components/buttons/Button';
|
||||
import configInterface from 'interfaces/config';
|
||||
import HostContainer from 'components/hosts/HostContainer';
|
||||
import HostPagination from 'components/hosts/HostPagination';
|
||||
import HostSidePanel from 'components/side_panels/HostSidePanel';
|
||||
@@ -45,6 +44,7 @@ const baseClass = 'manage-hosts';
|
||||
|
||||
export class ManageHostsPage extends PureComponent {
|
||||
static propTypes = {
|
||||
config: configInterface,
|
||||
dispatch: PropTypes.func,
|
||||
display: PropTypes.oneOf(['Grid', 'List']),
|
||||
hosts: PropTypes.arrayOf(hostInterface),
|
||||
@@ -155,18 +155,6 @@ export class ManageHostsPage extends PureComponent {
|
||||
.catch(() => false);
|
||||
}
|
||||
|
||||
onFetchCertificate = () => {
|
||||
return Kolide.config.loadCertificate()
|
||||
.then((certificate) => {
|
||||
const filename = `${global.window.location.host}.pem`;
|
||||
const file = new global.window.File([certificate], filename, { type: 'application/x-pem-file' });
|
||||
|
||||
FileSaver.saveAs(file);
|
||||
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
onLabelClick = (selectedLabel) => {
|
||||
return (evt) => {
|
||||
evt.preventDefault();
|
||||
@@ -304,9 +292,9 @@ export class ManageHostsPage extends PureComponent {
|
||||
}
|
||||
|
||||
renderAddHostModal = () => {
|
||||
const { onFetchCertificate, toggleAddHostModal } = this;
|
||||
const { toggleAddHostModal } = this;
|
||||
const { showAddHostModal } = this.state;
|
||||
const { enrollSecret } = this.props;
|
||||
const { enrollSecret, config } = this.props;
|
||||
|
||||
if (!showAddHostModal) {
|
||||
return false;
|
||||
@@ -319,9 +307,9 @@ export class ManageHostsPage extends PureComponent {
|
||||
className={`${baseClass}__invite-modal`}
|
||||
>
|
||||
<AddHostModal
|
||||
onFetchCertificate={onFetchCertificate}
|
||||
onReturnToApp={toggleAddHostModal}
|
||||
enrollSecret={enrollSecret}
|
||||
config={config}
|
||||
/>
|
||||
</Modal>
|
||||
);
|
||||
@@ -668,6 +656,7 @@ const mapStateToProps = (state, { location, params }) => {
|
||||
const { errors: labelErrors, loading: loadingLabels } = state.entities.labels;
|
||||
const { loading: loadingHosts } = state.entities.hosts;
|
||||
const enrollSecret = state.app.enrollSecret;
|
||||
const config = state.app.config;
|
||||
|
||||
return {
|
||||
selectedFilter,
|
||||
@@ -684,6 +673,7 @@ const mapStateToProps = (state, { location, params }) => {
|
||||
selectedLabel,
|
||||
selectedOsqueryTable,
|
||||
statusLabels,
|
||||
config,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import hostActions from 'redux/nodes/entities/hosts/actions';
|
||||
import labelActions from 'redux/nodes/entities/labels/actions';
|
||||
import ConnectedManageHostsPage, { ManageHostsPage } from 'pages/hosts/ManageHostsPage/ManageHostsPage';
|
||||
import { connectedComponent, createAceSpy, reduxMockStore, stubbedOsqueryTable } from 'test/helpers';
|
||||
import { hostStub } from 'test/stubs';
|
||||
import { hostStub, configStub } from 'test/stubs';
|
||||
import * as manageHostsPageActions from 'redux/nodes/components/ManageHostsPage/actions';
|
||||
|
||||
const allHostsLabel = { id: 1, display_text: 'All Hosts', slug: 'all-hosts', type: 'all', count: 22 };
|
||||
@@ -49,6 +49,7 @@ const mockStore = reduxMockStore({
|
||||
|
||||
describe('ManageHostsPage - component', () => {
|
||||
const props = {
|
||||
config: configStub,
|
||||
dispatch: noop,
|
||||
hosts: [],
|
||||
labels: [],
|
||||
|
||||
+27
-17
@@ -1,19 +1,29 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDBjCCAe4CCQDjM7ghDw9OgDANBgkqhkiG9w0BAQsFADBFMQ4wDAYDVQQKDAVG
|
||||
bGVldDEUMBIGA1UECwwLRGV2ZWxvcG1lbnQxHTAbBgNVBAMMFGhvc3QuZG9ja2Vy
|
||||
LmludGVybmFsMB4XDTE5MDMyNjE5MTQyN1oXDTQ2MDgxMDE5MTQyN1owRTEOMAwG
|
||||
A1UECgwFRmxlZXQxFDASBgNVBAsMC0RldmVsb3BtZW50MR0wGwYDVQQDDBRob3N0
|
||||
LmRvY2tlci5pbnRlcm5hbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
|
||||
AOnDxrXtuB3VpmsExCVXboF0Llcfee4FF4Y0ifS75RjnLSXupZubQWHenBGmQ7qb
|
||||
3eTBuw59HiTBkB5CZb79FpFyYrxMpXn+7dVJt2N9NnpKkVidqFXaVqTS9P84JQtt
|
||||
LIPzyQlRFM482Y0RVfY1UnrWUTqze/wUpJP6xY+aPseIbnYvbsGtZ8PjrLMN+6z8
|
||||
f2Ef8Hr6uIR2mQe+qu43HuEkjbTnRi1ORj2fr4cSgoVd7FMhIy1yGEaUP4aerB3X
|
||||
k1h4eOJa/Vd2eE3b3vXg7awAtdPJDWz4LjQCkgzeI5tej+TooAHM0gyun7EPSy+9
|
||||
2fgkAkEvY/dco6h+D0ULuNECAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAEhGq1t5G
|
||||
ZyhXEYJrd92HHi6zyRQNlAoQ55utmE/tlNAq1e2k1uEKEeOmIFvaLpQ3ky2z1Aok
|
||||
Qrn4+TYFcNN6vB99QxNVb3+hDm+hyKj0N7VvvYIX8ms/AUKZUaUahxM4gXDNky35
|
||||
l33IYgGmdcSzBiTkTCGABmtHwJ/QAPI1v6iWGXLQ42HNfCCflFHt5AtOs7Nfv0u5
|
||||
JsgkMVu+Vj9sOcdE+UtAJ/NQyV+kWFgzUtxdX8QX/NQVFqlNPVV4cRi8KMbBM1q+
|
||||
xN2o1vC27vM+5VWTr5sddU6MVJJXIIP4wfe+qbCnD8GE5+7j8XiUrOMsauiafaW2
|
||||
cdSv0nZ/WcEovw==
|
||||
MIIE5jCCAs6gAwIBAgIJAKq0+FAVArUhMA0GCSqGSIb3DQEBCwUAMBUxEzARBgNV
|
||||
BAMMCkZsZWV0IFRlc3QwHhcNMjAxMDE1MTg1ODE5WhcNMzAwNzE1MTg1ODE5WjAV
|
||||
MRMwEQYDVQQDDApGbGVldCBUZXN0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
|
||||
CgKCAgEAttQ62lpMq48/XjQFxYg47D2fgKgTBMjDNSfCt9VpqE3xPnybmWo8VZtk
|
||||
jmrFM50IhagyYSjvl9iqdrnsl3ZV8KYbWEy6849zDYF1SudmC7/pJyH7QvpKgL7V
|
||||
4McM62jM905hyFy9KZTAlFiaeezWSWJre7kHsK2u5tsqS6ElatEZmF59sInixaRw
|
||||
RqVxOhtDm7Sl1c5xKWM6phWoJfykspFpu5J6N2jRQXCfzBYoQWN76OohGouit/BQ
|
||||
C1xvm+f7wgGZgbbfDjUoHAe9Yhd3XzZsYTgMDt/SRJRDnxFZwo8BAkY9yJm7f3dQ
|
||||
AEhgJ66KbyoxITdgma1hgmeWibZY4hVymcRxB1B3RNN2at19RNy2J+brMxlG0KZk
|
||||
nD77EqidrwLAlYcdeU3yLjt0vYPxT+RW7l1jiZlVi/oaykAmVfOhWnTnTwbsYs7O
|
||||
UMyMyYHQECEs98ex7wrjThIBJScqhsSN1ipAxr5RgaDr+U5IR+tLhMewBy8So+nf
|
||||
2YuMhLfkCgoY80ELhz5F8avts5hksB0hqnNYr+Nlwm6eXqEPZSzFJmdc1IbmWzq2
|
||||
7UH1OQmBFF2qr2j/8dcM+oPNgjrEEQjtyW0S4j2PhjSEbINgcwu0AaABssLI80Vm
|
||||
Gp1TjUGA92rMwIjlAtcUUB5FOKSS8vAXb1VcDWMkybh9sHj4Z0ECAwEAAaM5MDcw
|
||||
NQYDVR0RBC4wLIIJbG9jYWxob3N0ghRob3N0LmRvY2tlci5pbnRlcm5hbIIJMTI3
|
||||
LjAuMC4xMA0GCSqGSIb3DQEBCwUAA4ICAQBZOY++LNRTVG8XlQGVlOloEKA2WY3P
|
||||
gXKJLSM7xWSxj2co0v+noyhoInHT7ysub8en59Et+vN53/0OobxNIdEKDUdqs38R
|
||||
F++Oy6s/MhFHSo87F06t+W91/60ub4iFRHfev1qeNFV6Yzv9sFJ5LpXLFk+qVDb8
|
||||
pPyFFE1bXjctDPjD5gUj+Y34XikVKzMb7xddWCNs34v1KCaCBW7kkfefxiZiDR6g
|
||||
lCEkDzp6xaLS898oCbfFakjr4bvOgBP1IqXLIDLPMhivaxNAooHTtu/3ezp7puix
|
||||
TSDkjlkStDtEFw/wjyaMcEkk51Gs1ponBbADLRxQ50AHDWk/4vy8GcIVc6CdVEOA
|
||||
Zw12FN06C4Jviiiv6uCXZ6iZ+V+pjGiGmSNYF+kruUs8BfrJIB89lqxpdQ4Kx01j
|
||||
AuSFvjRRvIPmvApSdKEjLcY3AYRivXsB/hASMBbjh/p1f/JzSJdxoqSvONhNQJuh
|
||||
+wcdNVQhGAv3kkLn/HMHTBl2Ur+9tQaJrnR1tWl1IzwLRJIi0Soyp/q5ZjQyFglj
|
||||
32xW83DZhtpQ2SI1QGy4AvWIPnGHZhMfav02KnKRhZdOMW4oekXRMrwiyXCqIazc
|
||||
xXzAlCq8dHdP2Y9uvfFxVFyE+uSfkcPxX+DG/ZnpgCS27oKA/qLCybJamlqtveNs
|
||||
RSjNe5qwGi0ifA==
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
+50
-26
@@ -1,28 +1,52 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDpw8a17bgd1aZr
|
||||
BMQlV26BdC5XH3nuBReGNIn0u+UY5y0l7qWbm0Fh3pwRpkO6m93kwbsOfR4kwZAe
|
||||
QmW+/RaRcmK8TKV5/u3VSbdjfTZ6SpFYnahV2lak0vT/OCULbSyD88kJURTOPNmN
|
||||
EVX2NVJ61lE6s3v8FKST+sWPmj7HiG52L27BrWfD46yzDfus/H9hH/B6+riEdpkH
|
||||
vqruNx7hJI2050YtTkY9n6+HEoKFXexTISMtchhGlD+Gnqwd15NYeHjiWv1XdnhN
|
||||
29714O2sALXTyQ1s+C40ApIM3iObXo/k6KABzNIMrp+xD0svvdn4JAJBL2P3XKOo
|
||||
fg9FC7jRAgMBAAECggEAPPViohqFgrIuHYY2qA4usO9dDjcVEq6dPdABkaJV0bKn
|
||||
IVckNHm+CQmF5UxYKRdwO7ERWGvkKm2XaWyjH7Tb573OZZAPLsr9tjrs6bLDPAyp
|
||||
7lPei9TN91lTriIz9tDXZOlzqUxNgqJ3kMPOiM/K3GF6+TXIxSmU6UnhrtroOBuq
|
||||
K+o/qC5K8CnqpBhBQt6qtn/YdfbcABogRbwojnHRl068nMV9kJLp7/I5hgI8Vr+v
|
||||
xMXI87wbL7kglcBZweG2EL//C31eSEVG2cW+0cIefQil0ZIPWgX0z5Oex2OD+cLL
|
||||
E+FIp/waZ7plCiikNNMo+gm/4uy9iupxg+z5W71NyQKBgQD2OSTe8w2Ns9zzLIXC
|
||||
5ZrFTa5LmTJ8bIv7/5kCS7fSGnoDPZvaRfnqzVEoCUp5D2N09NOJIsoNGrIGnMCc
|
||||
q6HwGEzGwmOgtzYu1r2jC+6jlcJW4tMr8k52CRO3y3LvsYkmt6tYIBgMVoxIupce
|
||||
QyBm5zVccyIvdhYhapgcSTJrtwKBgQDzC/30lTlBWsLiqLtfHAwM3YJgdVczJrbe
|
||||
WDieUd8ywTVupDOhBSGwVGmXGLQE5G/eNfwlsBq2iij7H/WdkX6mD1YmnQJUit3x
|
||||
0cPmDwWMo3vGLUUUI34WJ/2WSxdTtfaIcaFlV6S9Bp9B5K208kG/cZliqBWG1mtS
|
||||
a/AdsdcPtwKBgFHan2pKzNet0qc4xuMK54/uCiJxtHnur/6/cwNzXpHHYYaQRa6j
|
||||
kri/NtqjdBGYzwyDk4tEeH0wwbw3AkVTPYuO2H8/AlXccnPRyctZXSUe1TODRoaW
|
||||
kATncZmpVfVfROQNLTYnvTbk0tAez7wsvqnW9UNdtyCmFidXw2er4cozAoGADuPK
|
||||
MCTAODfGPrqVmBMQzez4Is6tg+24QFDpTxG2+dYKXvfiTdgRo0rYmTAjPzV7gQKP
|
||||
qwNp74rxTck8c+XI+4VvAriVvvYu+LSgKsT60w3k9FQrqjsua08R4xZAnJlGPD+x
|
||||
4pKG/imcsh2/YpmA26iq+/dOMk+KjacdM8SEZ2sCgYB/qypw7LpskkGA5ITODv5A
|
||||
cAHVCCDMGNJiR4XpdOwHNAcd6EWjB/366/MwKfV24KnZH0RZe+pU2e4dP8miHNN0
|
||||
dFOpAokCD3Eh7LGDVM6bYkQabG3XTmN8g9a4V2e63n5Bl2HZx0Qp1bHEtqsOujpj
|
||||
5G5maHPlTRoNlvk4BiEZDA==
|
||||
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
|
||||
mWZen+G8ANnds10V7TmcpoaPSSoJMF0=
|
||||
-----END PRIVATE KEY-----
|
||||
|
||||
Reference in New Issue
Block a user