mirror of https://github.com/MISP/MISP
Add support for sync server SSL client certificates
parent
1b73e38621
commit
81a5838131
|
@ -363,6 +363,7 @@ CREATE TABLE IF NOT EXISTS `servers` (
|
|||
`pull_rules` text COLLATE utf8_bin NOT NULL,
|
||||
`push_rules` text COLLATE utf8_bin NOT NULL,
|
||||
`cert_file` varchar(255) COLLATE utf8_bin DEFAULT NULL,
|
||||
`client_cert_file` varchar(255) COLLATE utf8_bin DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
INDEX `org_id` (`org_id`),
|
||||
INDEX `remote_org_id` (`remote_org_id`)
|
||||
|
|
|
@ -44,6 +44,7 @@ call AddColumnUnlessExists(Database(), 'servers', 'push_rules', 'TEXT( 11 ) COLL
|
|||
call AddColumnUnlessExists(Database(), 'servers', 'org_id', 'INT( 11 ) NOT NULL DEFAULT 0');
|
||||
call AddColumnUnlessExists(Database(), 'servers', 'remote_org_id', 'INT( 11 ) NOT NULL DEFAULT 0');
|
||||
call AddColumnUnlessExists(Database(), 'servers', 'name', 'varchar(255) COLLATE utf8_bin NOT NULL');
|
||||
call AddColumnUnlessExists(Database(), 'servers', 'client_cert_file', 'varchar(255) COLLATE utf8_bin DEFAULT NULL');
|
||||
|
||||
call AddColumnUnlessExists(Database(), 'shadow_attributes', 'org_id', 'INT( 11 ) NOT NULL DEFAULT 0');
|
||||
call AddColumnUnlessExists(Database(), 'shadow_attributes', 'event_org_id', 'INT( 11 ) NOT NULL DEFAULT 0');
|
||||
|
|
|
@ -168,6 +168,7 @@ class AppSchema extends CakeSchema {
|
|||
'lastpushedid' => array('type' => 'integer', 'null' => false, 'default' => null),
|
||||
'self_signed' => array('type' => 'boolean', 'null' => false, 'default' => null),
|
||||
'cert_file' => array('type' => 'string', 'null' => false, 'default' => null, 'collate' => 'utf8_bin', 'charset' => 'utf8'),
|
||||
'client_cert_file' => array('type' => 'string', 'null' => false, 'default' => null, 'collate' => 'utf8_bin', 'charset' => 'utf8'),
|
||||
'indexes' => array(
|
||||
'PRIMARY' => array('column' => 'id', 'unique' => 1)
|
||||
),
|
||||
|
|
|
@ -224,7 +224,10 @@ class ServersController extends AppController {
|
|||
$this->request->data['Server']['org_id'] = $this->Auth->user('org_id');
|
||||
if ($this->Server->save($this->request->data)) {
|
||||
if (isset($this->request->data['Server']['submitted_cert']) && $this->request->data['Server']['submitted_cert']['size'] != 0) {
|
||||
$this->__saveCert($this->request->data, $this->Server->id);
|
||||
$this->__saveCert($this->request->data, $this->Server->id, false);
|
||||
}
|
||||
if (isset($this->request->data['Server']['submitted_client_cert']) && $this->request->data['Server']['submitted_client_cert']['size'] != 0) {
|
||||
$this->__saveCert($this->request->data, $this->Server->id, true);
|
||||
}
|
||||
$this->Session->setFlash(__('The server has been saved'));
|
||||
$this->redirect(array('action' => 'index'));
|
||||
|
@ -300,7 +303,7 @@ class ServersController extends AppController {
|
|||
}
|
||||
if (!$fail) {
|
||||
// say what fields are to be updated
|
||||
$fieldList = array('id', 'url', 'push', 'pull', 'remote_org_id', 'name' ,'self_signed', 'cert_file', 'push_rules', 'pull_rules');
|
||||
$fieldList = array('id', 'url', 'push', 'pull', 'remote_org_id', 'name' ,'self_signed', 'cert_file', 'client_cert_file', 'push_rules', 'pull_rules');
|
||||
$this->request->data['Server']['id'] = $id;
|
||||
if ("" != $this->request->data['Server']['authkey']) $fieldList[] = 'authkey';
|
||||
if ($this->request->data['Server']['organisation_type'] < 2) $this->request->data['Server']['remote_org_id'] = $json['id'];
|
||||
|
@ -340,9 +343,14 @@ class ServersController extends AppController {
|
|||
// Save the data
|
||||
if ($this->Server->save($this->request->data, true, $fieldList)) {
|
||||
if (isset($this->request->data['Server']['submitted_cert']) && $this->request->data['Server']['submitted_cert']['size'] != 0 && !$this->request->data['Server']['delete_cert']) {
|
||||
$this->__saveCert($this->request->data, $this->Server->id);
|
||||
$this->__saveCert($this->request->data, $this->Server->id, false);
|
||||
} else {
|
||||
if ($this->request->data['Server']['delete_cert']) $this->__saveCert($this->request->data, $this->Server->id, true);
|
||||
if ($this->request->data['Server']['delete_cert']) $this->__saveCert($this->request->data, $this->Server->id, false, true);
|
||||
}
|
||||
if (isset($this->request->data['Server']['submitted_client_cert']) && $this->request->data['Server']['submitted_client_cert']['size'] != 0 && !$this->request->data['Server']['delete_client_cert']) {
|
||||
$this->__saveCert($this->request->data, $this->Server->id, true);
|
||||
} else {
|
||||
if ($this->request->data['Server']['delete_client_cert']) $this->__saveCert($this->request->data, $this->Server->id, true, true);
|
||||
}
|
||||
$this->Session->setFlash(__('The server has been saved'));
|
||||
$this->redirect(array('action' => 'index'));
|
||||
|
@ -546,33 +554,42 @@ class ServersController extends AppController {
|
|||
}
|
||||
}
|
||||
|
||||
private function __saveCert($server, $id, $delete = false) {
|
||||
private function __saveCert($server, $id, $client = false, $delete = false) {
|
||||
if ($client) {
|
||||
$subm = 'submitted_client_cert';
|
||||
$attr = 'client_cert_file';
|
||||
$ins = '_client';
|
||||
} else {
|
||||
$subm = 'submitted_cert';
|
||||
$attr = 'cert_file';
|
||||
$ins = '';
|
||||
}
|
||||
if (!$delete) {
|
||||
$ext = '';
|
||||
App::uses('File', 'Utility');
|
||||
App::uses('Folder', 'Utility');
|
||||
App::uses('FileAccess', 'Tools');
|
||||
$file = new File($server['Server']['submitted_cert']['name']);
|
||||
$file = new File($server['Server'][$subm]['name']);
|
||||
$ext = $file->ext();
|
||||
if (($ext != 'pem') || !$server['Server']['submitted_cert']['size'] > 0) {
|
||||
if (($ext != 'pem') || !$server['Server'][$subm]['size'] > 0) {
|
||||
$this->Session->setFlash('Incorrect extension or empty file.');
|
||||
$this->redirect(array('action' => 'index'));
|
||||
}
|
||||
|
||||
// read pem file data
|
||||
$pemData = FileAccess::readFromFile($server['Server']['submitted_cert']['tmp_name'], $server['Server']['submitted_cert']['size']);
|
||||
$pemData = FileAccess::readFromFile($server['Server'][$subm]['tmp_name'], $server['Server'][$subm]['size']);
|
||||
|
||||
$destpath = APP . "files" . DS . "certs" . DS;
|
||||
$dir = new Folder(APP . "files" . DS . "certs", true);
|
||||
if (!preg_match('@^[\w-,\s,\.]+\.[A-Za-z0-9_]{2,4}$@', $server['Server']['submitted_cert']['name'])) throw new Exception ('Filename not allowed');
|
||||
$pemfile = new File($destpath . $id . '.' . $ext);
|
||||
if (!preg_match('@^[\w-,\s,\.]+\.[A-Za-z0-9_]{2,4}$@', $server['Server'][$subm]['name'])) throw new Exception ('Filename not allowed');
|
||||
$pemfile = new File($destpath . $id . $ins . '.' . $ext);
|
||||
$result = $pemfile->write($pemData);
|
||||
$s = $this->Server->read(null, $id);
|
||||
$s['Server']['cert_file'] = $s['Server']['id'] . '.' . $ext;
|
||||
$s['Server'][$attr] = $s['Server']['id'] . $ins . '.' . $ext;
|
||||
if ($result) $this->Server->save($s);
|
||||
} else {
|
||||
$s = $this->Server->read(null, $id);
|
||||
$s['Server']['cert_file'] = '';
|
||||
$s['Server'][$attr] = '';
|
||||
$this->Server->save($s);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ class SyncTool {
|
|||
App::uses('HttpSocket', 'Network/Http');
|
||||
if (!empty($server)) {
|
||||
if ($server['Server']['cert_file']) $params['ssl_cafile'] = APP . "files" . DS . "certs" . DS . $server['Server']['id'] . '.pem';
|
||||
if ($server['Server']['client_cert_file']) $params['ssl_local_cert'] = APP . "files" . DS . "certs" . DS . $server['Server']['id'] . '_client.pem';
|
||||
if ($server['Server']['self_signed']) $params['ssl_allow_self_signed'] = $server['Server']['self_signed'];
|
||||
}
|
||||
$HttpSocket = new HttpSocket($params);
|
||||
|
|
|
@ -49,7 +49,7 @@ class AppModel extends Model {
|
|||
// major -> minor -> hotfix -> requires_logout
|
||||
public $db_changes = array(
|
||||
2 => array(
|
||||
4 => array(18 => false, 19 => false, 20 => false, 25 => false, 27 => false, 32 => false, 33 => true, 38 => true, 39 => true, 40 => false, 42 => false, 44 => false, 45 => false, 49 => true)
|
||||
4 => array(18 => false, 19 => false, 20 => false, 25 => false, 27 => false, 32 => false, 33 => true, 38 => true, 39 => true, 40 => false, 42 => false, 44 => false, 45 => false, 49 => true, 50 => false)
|
||||
)
|
||||
);
|
||||
|
||||
|
@ -435,6 +435,9 @@ class AppModel extends Model {
|
|||
$sqlArray[] = "ALTER TABLE `tags` ADD `org_id` int(11) NOT NULL DEFAULT 0;";
|
||||
$sqlArray[] = 'ALTER TABLE `tags` ADD INDEX `org_id` (`org_id`);';
|
||||
break;
|
||||
case '2.4.50':
|
||||
$sqlArray[] = "ALTER TABLE `servers` ADD `client_cert_file` varchar(255) COLLATE utf8_bin DEFAULT NULL;";
|
||||
break;
|
||||
case 'fixNonEmptySharingGroupID':
|
||||
$sqlArray[] = 'UPDATE `events` SET `sharing_group_id` = 0 WHERE `distribution` != 4;';
|
||||
$sqlArray[] = 'UPDATE `attributes` SET `sharing_group_id` = 0 WHERE `distribution` != 4;';
|
||||
|
|
|
@ -64,7 +64,13 @@
|
|||
));
|
||||
|
||||
echo $this->Form->input('Server.submitted_cert', array(
|
||||
'label' => '<b>Certificate file</b>',
|
||||
'label' => '<b>Server certificate file</b>',
|
||||
'type' => 'file',
|
||||
'div' => 'clear'
|
||||
));
|
||||
|
||||
echo $this->Form->input('Server.submitted_client_cert', array(
|
||||
'label' => '<b>Client certificate file</b>',
|
||||
'type' => 'file',
|
||||
'div' => 'clear'
|
||||
));
|
||||
|
|
|
@ -70,7 +70,7 @@
|
|||
?>
|
||||
<div class="clear">
|
||||
<p>
|
||||
<span class="bold">Ceritificate file: </span>
|
||||
<span class="bold">Server ceritificate file: </span>
|
||||
<span id="serverEditCertValue">
|
||||
<?php
|
||||
if (isset($server['Server']['cert_file']) && !empty($server['Server']['cert_file'])) echo h($server['Server']['cert_file']);
|
||||
|
@ -84,7 +84,29 @@
|
|||
<div style="width: 0px;height: 0px;overflow: hidden;">
|
||||
<?php
|
||||
echo $this->Form->input('Server.submitted_cert', array(
|
||||
'label' => false,
|
||||
'label' => 'submitted_cert',
|
||||
'type' => 'file',
|
||||
'div' => false
|
||||
));
|
||||
?>
|
||||
</div>
|
||||
<div class="clear">
|
||||
<p>
|
||||
<span class="bold">Client ceritificate file: </span>
|
||||
<span id="serverEditClientCertValue">
|
||||
<?php
|
||||
if (isset($server['Server']['client_cert_file']) && !empty($server['Server']['client_cert_file'])) echo h($server['Server']['client_cert_file']);
|
||||
else echo '<span class="green bold">Not set.</span>';
|
||||
?>
|
||||
</span>
|
||||
<br />
|
||||
<span id="add_client_cert_file" class="btn btn-inverse" style="line-height:10px; padding: 4px 4px;">Add certificate file</span>
|
||||
<span id="remove_client_cert_file" class="btn btn-inverse" style="line-height:10px; padding: 4px 4px;">Remove certificate file</span>
|
||||
</p>
|
||||
<div style="width: 0px;height: 0px;overflow: hidden;">
|
||||
<?php
|
||||
echo $this->Form->input('Server.submitted_client_cert', array(
|
||||
'label' => 'submitted_client_cert',
|
||||
'type' => 'file',
|
||||
'div' => false
|
||||
));
|
||||
|
@ -134,6 +156,7 @@ var formInfoValues = {
|
|||
'ServerPush' : "Allow the upload of events and their attributes.",
|
||||
'ServerPull' : "Allow the download of events and their attributes from the server.",
|
||||
'ServerSubmittedCert' : "You can also upload a certificate file if the instance you are trying to connect to has its own signing authority.",
|
||||
'ServerSubmittedClientCert' : "You can also upload a client certificate file if the instance you are trying to connect requires this.",
|
||||
'ServerSelfSigned' : "Click this, if you would like to allow a connection despite the other instance using a self-signed certificate (not recommended)."
|
||||
};
|
||||
|
||||
|
@ -151,11 +174,11 @@ $(document).ready(function() {
|
|||
serverOrgTypeChange();
|
||||
});
|
||||
|
||||
$("#ServerUrl, #ServerOrganization, #ServerName, #ServerAuthkey, #ServerPush, #ServerPull, #ServerSubmittedCert, #ServerSelfSigned").on('mouseleave', function(e) {
|
||||
$("#ServerUrl, #ServerOrganization, #ServerName, #ServerAuthkey, #ServerPush, #ServerPull, #ServerSubmittedCert, #ServerSubmittedClientCert, #ServerSelfSigned").on('mouseleave', function(e) {
|
||||
$('#'+e.currentTarget.id).popover('destroy');
|
||||
});
|
||||
|
||||
$("#ServerUrl, #ServerOrganization, #ServerName, #ServerAuthkey, #ServerPush, #ServerPull, #ServerSubmittedCert, #ServerSelfSigned").on('mouseover', function(e) {
|
||||
$("#ServerUrl, #ServerOrganization, #ServerName, #ServerAuthkey, #ServerPush, #ServerPull, #ServerSubmittedCert, #ServerSubmittedClientCert, #ServerSelfSigned").on('mouseover', function(e) {
|
||||
var $e = $(e.target);
|
||||
$('#'+e.currentTarget.id).popover('destroy');
|
||||
$('#'+e.currentTarget.id).popover({
|
||||
|
@ -176,14 +199,24 @@ $(document).ready(function() {
|
|||
$('#add_cert_file').click(function() {
|
||||
$('#ServerSubmittedCert').trigger('click');
|
||||
});
|
||||
$('input[type=file]').change(function() {
|
||||
$('#serverEditCertValue').text($('input[type=file]').val());
|
||||
$('#add_client_cert_file').click(function() {
|
||||
$('#ServerSubmittedClientCert').trigger('click');
|
||||
});
|
||||
$('input[label=submitted_cert]').change(function() {
|
||||
$('#serverEditCertValue').text($('input[label=submitted_cert]').val());
|
||||
$('#ServerDeleteCert').prop('checked', false);
|
||||
});
|
||||
|
||||
$('input[label=submitted_client_cert]').change(function() {
|
||||
$('#serverEditClientCertValue').text($('input[label=submitted_client_cert]').val());
|
||||
$('#ServerDeleteClientCert').prop('checked', false);
|
||||
});
|
||||
$('#remove_cert_file').click(function() {
|
||||
$('#serverEditCertValue').html('<span class="green bold">Not set.</span>');
|
||||
$('#ServerDeleteCert').prop('checked', true);
|
||||
});
|
||||
$('#remove_client_cert_file').click(function() {
|
||||
$('#serverEditClientCertValue').html('<span class="green bold">Not set.</span>');
|
||||
$('#ServerDeleteClientCert').prop('checked', true);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
<th><?php echo $this->Paginator->sort('url');?></th>
|
||||
<th>Remote Organisation</th>
|
||||
<th><?php echo $this->Paginator->sort('cert_file');?></th>
|
||||
<th><?php echo $this->Paginator->sort('client_cert_file');?></th>
|
||||
<th><?php echo $this->Paginator->sort('self_signed');?></th>
|
||||
<th><?php echo $this->Paginator->sort('org');?></th>
|
||||
<th>Last Pulled ID</th>
|
||||
|
@ -70,6 +71,7 @@ foreach ($servers as $server):
|
|||
<td><?php echo h($server['Server']['url']); ?> </td>
|
||||
<td><a href="/organisations/view/<?php echo h($server['RemoteOrg']['id']); ?>"><?php echo h($server['RemoteOrg']['name']); ?></a></td>
|
||||
<td class="short"><?php echo h($server['Server']['cert_file']); ?> </td>
|
||||
<td class="short"><?php echo h($server['Server']['client_cert_file']); ?> </td>
|
||||
<td class="short"><span class="<?php echo ($server['Server']['self_signed'] ? 'icon-ok' : 'icon-remove'); ?>"></span></td>
|
||||
<td class="short"><a href="/organisations/view/<?php echo h($server['Organisation']['id']); ?>"><?php echo h($server['Organisation']['name']); ?></a></td>
|
||||
<td class="short"><?php echo $server['Server']['lastpulledid']; ?></td>
|
||||
|
|
Loading…
Reference in New Issue