2013-05-22 10:52:03 +02:00
< ? php
App :: uses ( 'AppController' , 'Controller' );
App :: uses ( 'Xml' , 'Utility' );
2020-05-05 15:23:26 +02:00
App :: uses ( 'AttachmentTool' , 'Tools' );
2013-05-22 10:52:03 +02:00
2020-09-23 17:28:01 +02:00
/**
* @ property Server $Server
*/
2018-07-19 11:48:22 +02:00
class ServersController extends AppController
{
2019-02-10 13:08:12 +01:00
public $components = array ( 'Security' , 'RequestHandler' ); // XXX ACL component
2018-07-19 11:48:22 +02:00
public $paginate = array (
'limit' => 60 ,
'recursive' => - 1 ,
'contain' => array (
'User' => array (
'fields' => array ( 'User.id' , 'User.org_id' , 'User.email' ),
),
'Organisation' => array (
'fields' => array ( 'Organisation.name' , 'Organisation.id' ),
),
'RemoteOrg' => array (
'fields' => array ( 'RemoteOrg.name' , 'RemoteOrg.id' ),
),
),
'maxLimit' => 9999 , // LATER we will bump here on a problem once we have more than 9999 events
'order' => array (
2019-09-13 11:49:12 +02:00
'Server.priority' => 'ASC'
2018-07-19 11:48:22 +02:00
),
);
public $uses = array ( 'Server' , 'Event' );
public function beforeFilter ()
{
parent :: beforeFilter ();
2018-11-23 14:11:33 +01:00
$this -> Security -> unlockedActions [] = 'getApiInfo' ;
2018-07-19 11:48:22 +02:00
// permit reuse of CSRF tokens on some pages.
switch ( $this -> request -> params [ 'action' ]) {
case 'push' :
case 'pull' :
case 'getVersion' :
case 'testConnection' :
$this -> Security -> csrfUseOnce = false ;
}
}
public function index ()
{
2018-08-22 17:00:13 +02:00
if ( $this -> _isRest ()) {
2018-11-23 14:11:33 +01:00
$params = array (
'recursive' => - 1 ,
'contain' => array (
2019-01-20 10:19:05 +01:00
'User' => array (
'fields' => array ( 'User.id' , 'User.org_id' , 'User.email' ),
),
'Organisation' => array (
'fields' => array ( 'Organisation.id' , 'Organisation.name' , 'Organisation.uuid' , 'Organisation.nationality' , 'Organisation.sector' , 'Organisation.type' ),
),
'RemoteOrg' => array (
'fields' => array ( 'RemoteOrg.id' , 'RemoteOrg.name' , 'RemoteOrg.uuid' , 'RemoteOrg.nationality' , 'RemoteOrg.sector' , 'RemoteOrg.type' ),
),
),
2018-11-23 14:11:33 +01:00
);
$servers = $this -> Server -> find ( 'all' , $params );
2019-01-20 10:19:05 +01:00
$servers = $this -> Server -> attachServerCacheTimestamps ( $servers );
2018-11-23 14:11:33 +01:00
return $this -> RestResponse -> viewData ( $servers , $this -> response -> type ());
} else {
2019-01-20 10:19:05 +01:00
$servers = $this -> paginate ();
$servers = $this -> Server -> attachServerCacheTimestamps ( $servers );
$this -> set ( 'servers' , $servers );
2018-11-23 14:11:33 +01:00
$collection = array ();
$collection [ 'orgs' ] = $this -> Server -> Organisation -> find ( 'list' , array (
'fields' => array ( 'id' , 'name' ),
));
$this -> loadModel ( 'Tag' );
$collection [ 'tags' ] = $this -> Tag -> find ( 'list' , array (
'fields' => array ( 'id' , 'name' ),
));
$this -> set ( 'collection' , $collection );
}
2018-07-19 11:48:22 +02:00
}
public function previewIndex ( $id )
{
$urlparams = '' ;
$passedArgs = array ();
2021-01-18 10:04:53 +01:00
$server = $this -> Server -> find ( 'first' , array ( 'conditions' => array ( 'Server.id' => $id ), 'recursive' => - 1 ));
2018-07-19 11:48:22 +02:00
if ( empty ( $server )) {
throw new NotFoundException ( 'Invalid server ID.' );
}
$validFilters = $this -> Server -> validEventIndexFilters ;
foreach ( $validFilters as $k => $filter ) {
if ( isset ( $this -> passedArgs [ $filter ])) {
$passedArgs [ $filter ] = $this -> passedArgs [ $filter ];
if ( $k != 0 ) {
$urlparams .= '/' ;
}
$urlparams .= $filter . ':' . $this -> passedArgs [ $filter ];
}
}
$combinedArgs = array_merge ( $this -> passedArgs , $passedArgs );
if ( ! isset ( $combinedArgs [ 'sort' ])) {
$combinedArgs [ 'sort' ] = 'timestamp' ;
$combinedArgs [ 'direction' ] = 'desc' ;
}
2019-08-02 14:42:23 +02:00
if ( empty ( $combinedArgs [ 'page' ])) {
$combinedArgs [ 'page' ] = 1 ;
}
if ( empty ( $combinedArgs [ 'limit' ])) {
$combinedArgs [ 'limit' ] = 60 ;
}
2019-10-10 19:10:52 +02:00
try {
2021-01-18 10:04:53 +01:00
list ( $events , $total_count ) = $this -> Server -> previewIndex ( $server , $this -> Auth -> user (), $combinedArgs );
2019-10-10 19:10:52 +02:00
} catch ( Exception $e ) {
$this -> Flash -> error ( __ ( 'Download failed.' ) . ' ' . $e -> getMessage ());
$this -> redirect ( array ( 'action' => 'index' ));
}
2018-07-19 11:48:22 +02:00
$this -> loadModel ( 'Event' );
2021-01-18 10:04:53 +01:00
$threat_levels = $this -> Event -> ThreatLevel -> find ( 'list' , [ 'fields' => [ 'id' , 'name' ]]);
$this -> set ( 'threatLevels' , $threat_levels );
2018-07-19 11:48:22 +02:00
App :: uses ( 'CustomPaginationTool' , 'Tools' );
$customPagination = new CustomPaginationTool ();
$params = $customPagination -> createPaginationRules ( $events , $this -> passedArgs , $this -> alias );
2019-08-02 14:42:23 +02:00
if ( ! empty ( $total_count )) {
$params [ 'pageCount' ] = ceil ( $total_count / $params [ 'limit' ]);
}
2018-07-19 11:48:22 +02:00
$this -> params -> params [ 'paging' ] = array ( $this -> modelClass => $params );
2019-10-10 19:10:52 +02:00
if ( count ( $events ) > 60 ) {
$customPagination -> truncateByPagination ( $events , $params );
}
2018-07-19 11:48:22 +02:00
$this -> set ( 'events' , $events );
$this -> set ( 'eventDescriptions' , $this -> Event -> fieldDescriptions );
$this -> set ( 'analysisLevels' , $this -> Event -> analysisLevels );
$this -> set ( 'distributionLevels' , $this -> Event -> distributionLevels );
$shortDist = array ( 0 => 'Organisation' , 1 => 'Community' , 2 => 'Connected' , 3 => 'All' , 4 => ' sharing Group' );
$this -> set ( 'shortDist' , $shortDist );
$this -> set ( 'id' , $id );
$this -> set ( 'urlparams' , $urlparams );
$this -> set ( 'passedArgs' , json_encode ( $passedArgs ));
$this -> set ( 'passedArgsArray' , $passedArgs );
$this -> set ( 'server' , $server );
}
public function previewEvent ( $serverId , $eventId , $all = false )
{
2020-10-01 12:11:45 +02:00
$server = $this -> Server -> find ( 'first' , array (
'conditions' => array ( 'Server.id' => $serverId ),
'recursive' => - 1 ,
2021-01-18 10:04:53 +01:00
));
2018-07-19 11:48:22 +02:00
if ( empty ( $server )) {
throw new NotFoundException ( 'Invalid server ID.' );
}
2019-10-10 19:10:52 +02:00
try {
2021-01-18 10:04:53 +01:00
$event = $this -> Server -> previewEvent ( $server , $eventId );
2019-10-10 19:10:52 +02:00
} catch ( NotFoundException $e ) {
2020-10-01 12:11:45 +02:00
throw new NotFoundException ( __ ( " Event '%s' not found. " , $eventId ));
2019-10-10 19:10:52 +02:00
} catch ( Exception $e ) {
2020-10-01 12:11:45 +02:00
$this -> Flash -> error ( __ ( 'Download failed. %s' , $e -> getMessage ()));
2019-10-10 19:10:52 +02:00
$this -> redirect ( array ( 'action' => 'previewIndex' , $serverId ));
2018-07-19 11:48:22 +02:00
}
2019-10-10 19:10:52 +02:00
2021-01-18 10:13:11 +01:00
if ( $this -> _isRest ()) {
return $this -> RestResponse -> viewData ( $event , $this -> response -> type ());
}
2020-10-01 12:11:45 +02:00
$this -> loadModel ( 'Warninglist' );
if ( isset ( $event [ 'Event' ][ 'Attribute' ])) {
$this -> Warninglist -> attachWarninglistToAttributes ( $event [ 'Event' ][ 'Attribute' ]);
}
if ( isset ( $event [ 'Event' ][ 'ShadowAttribute' ])) {
$this -> Warninglist -> attachWarninglistToAttributes ( $event [ 'Event' ][ 'ShadowAttribute' ]);
}
2018-07-19 11:48:22 +02:00
$this -> loadModel ( 'Event' );
$params = $this -> Event -> rearrangeEventForView ( $event , $this -> passedArgs , $all );
$this -> params -> params [ 'paging' ] = array ( 'Server' => $params );
$this -> set ( 'event' , $event );
$this -> set ( 'server' , $server );
$dataForView = array (
'Attribute' => array ( 'attrDescriptions' => 'fieldDescriptions' , 'distributionDescriptions' => 'distributionDescriptions' , 'distributionLevels' => 'distributionLevels' ),
'Event' => array ( 'eventDescriptions' => 'fieldDescriptions' , 'analysisLevels' => 'analysisLevels' ),
'Object' => array ()
);
foreach ( $dataForView as $m => $variables ) {
if ( $m === 'Event' ) {
$currentModel = $this -> Event ;
} elseif ( $m === 'Attribute' ) {
$currentModel = $this -> Event -> Attribute ;
} elseif ( $m === 'Object' ) {
$currentModel = $this -> Event -> Object ;
}
foreach ( $variables as $alias => $variable ) {
$this -> set ( $alias , $currentModel -> { $variable });
}
}
2021-01-18 10:04:53 +01:00
$threat_levels = $this -> Event -> ThreatLevel -> find ( 'list' , [ 'fields' => [ 'id' , 'name' ]]);
$this -> set ( 'threatLevels' , $threat_levels );
2021-01-12 10:46:05 +01:00
$this -> set ( 'title_for_layout' , __ ( 'Remote event preview' ));
2018-07-19 11:48:22 +02:00
}
2021-01-18 11:23:26 +01:00
public function compareServers ()
{
list ( $servers , $overlap ) = $this -> Server -> serverEventsOverlap ();
$this -> set ( 'servers' , $servers );
$this -> set ( 'overlap' , $overlap );
$this -> set ( 'title_for_layout' , __ ( 'Server overlap analysis matrix' ));
}
2018-07-19 11:48:22 +02:00
public function filterEventIndex ( $id )
{
if ( ! $this -> _isSiteAdmin ()) {
throw new MethodNotAllowedException ( 'You are not authorised to do that.' );
}
$validFilters = $this -> Server -> validEventIndexFilters ;
$validatedFilterString = '' ;
foreach ( $this -> passedArgs as $k => $v ) {
if ( in_array ( '' . $k , $validFilters )) {
if ( $validatedFilterString != '' ) {
$validatedFilterString .= '/' ;
}
$validatedFilterString .= $k . ':' . $v ;
}
}
$this -> set ( 'id' , $id );
$this -> set ( 'validFilters' , $validFilters );
$this -> set ( 'filter' , $validatedFilterString );
}
public function add ()
{
if ( ! $this -> _isSiteAdmin ()) {
$this -> redirect ( array ( 'controller' => 'servers' , 'action' => 'index' ));
}
if ( $this -> request -> is ( 'post' )) {
if ( $this -> _isRest ()) {
if ( ! isset ( $this -> request -> data [ 'Server' ])) {
$this -> request -> data = array ( 'Server' => $this -> request -> data );
}
}
if ( ! empty ( $this -> request -> data [ 'Server' ][ 'json' ])) {
$json = json_decode ( $this -> request -> data [ 'Server' ][ 'json' ], true );
} elseif ( $this -> _isRest ()) {
if ( empty ( $this -> request -> data [ 'Server' ][ 'remote_org_id' ])) {
throw new MethodNotAllowedException ( 'No remote org ID set. Please pass it as remote_org_id' );
}
}
$fail = false ;
if ( empty ( Configure :: read ( 'MISP.host_org_id' ))) {
$this -> request -> data [ 'Server' ][ 'internal' ] = 0 ;
}
// test the filter fields
if ( ! empty ( $this -> request -> data [ 'Server' ][ 'pull_rules' ]) && ! $this -> Server -> isJson ( $this -> request -> data [ 'Server' ][ 'pull_rules' ])) {
$fail = true ;
$error_msg = __ ( 'The pull filter rules must be in valid JSON format.' );
if ( $this -> _isRest ()) {
return $this -> RestResponse -> saveFailResponse ( 'Servers' , 'add' , false , array ( 'pull_rules' => $error_msg ), $this -> response -> type ());
} else {
$this -> Flash -> error ( $error_msg );
}
}
if ( ! $fail && ! empty ( $this -> request -> data [ 'Server' ][ 'push_rules' ]) && ! $this -> Server -> isJson ( $this -> request -> data [ 'Server' ][ 'push_rules' ])) {
$fail = true ;
$error_msg = __ ( 'The push filter rules must be in valid JSON format.' );
if ( $this -> _isRest ()) {
return $this -> RestResponse -> saveFailResponse ( 'Servers' , 'add' , false , array ( 'push_rules' => $error_msg ), $this -> response -> type ());
} else {
$this -> Flash -> error ( $error_msg );
}
}
if ( ! $fail ) {
if ( $this -> _isRest ()) {
$defaults = array (
'push' => 0 ,
'pull' => 0 ,
2019-11-22 21:53:51 +01:00
'push_sightings' => 0 ,
2020-05-26 15:08:24 +02:00
'push_galaxy_clusters' => 0 ,
2020-06-10 09:36:34 +02:00
'pull_galaxy_clusters' => 0 ,
2019-01-18 09:06:23 +01:00
'caching_enabled' => 0 ,
2018-07-19 11:48:22 +02:00
'json' => '[]' ,
'push_rules' => '[]' ,
'pull_rules' => '[]' ,
'self_signed' => 0
);
foreach ( $defaults as $default => $dvalue ) {
if ( ! isset ( $this -> request -> data [ 'Server' ][ $default ])) {
$this -> request -> data [ 'Server' ][ $default ] = $dvalue ;
}
}
}
// force check userid and orgname to be from yourself
$this -> request -> data [ 'Server' ][ 'org_id' ] = $this -> Auth -> user ( 'org_id' );
if ( $this -> _isRest ()) {
if ( empty ( $this -> request -> data [ 'Server' ][ 'remote_org_id' ])) {
return $this -> RestResponse -> saveFailResponse ( 'Servers' , 'add' , false , array ( 'Organisation' => 'Remote Organisation\'s id/uuid not given (remote_org_id)' ), $this -> response -> type ());
}
if ( Validation :: uuid ( $this -> request -> data [ 'Server' ][ 'remote_org_id' ])) {
$orgCondition = array ( 'uuid' => $this -> request -> data [ 'Server' ][ 'remote_org_id' ]);
} else {
$orgCondition = array ( 'id' => $this -> request -> data [ 'Server' ][ 'remote_org_id' ]);
}
$existingOrgs = $this -> Server -> Organisation -> find ( 'first' , array (
'conditions' => $orgCondition ,
'recursive' => - 1 ,
'fields' => array ( 'id' , 'uuid' )
));
if ( empty ( $existingOrgs )) {
return $this -> RestResponse -> saveFailResponse ( 'Servers' , 'add' , false , array ( 'Organisation' => 'Invalid Remote Organisation' ), $this -> response -> type ());
}
} else {
if ( $this -> request -> data [ 'Server' ][ 'organisation_type' ] < 2 ) {
$this -> request -> data [ 'Server' ][ 'remote_org_id' ] = $json [ 'id' ];
} else {
$existingOrgs = $this -> Server -> Organisation -> find ( 'first' , array (
'conditions' => array ( 'uuid' => $json [ 'uuid' ]),
'recursive' => - 1 ,
'fields' => array ( 'id' , 'uuid' )
));
if ( ! empty ( $existingOrgs )) {
$fail = true ;
$this -> Flash -> error ( __ ( 'That organisation could not be created as the uuid is in use already.' ));
}
if ( ! $fail ) {
$this -> Server -> Organisation -> create ();
$orgSave = $this -> Server -> Organisation -> save ( array (
'name' => $json [ 'name' ],
'uuid' => $json [ 'uuid' ],
'local' => 0 ,
'created_by' => $this -> Auth -> user ( 'id' )
));
if ( ! $orgSave ) {
$this -> Flash -> error ( __ ( 'Couldn\'t save the new organisation, are you sure that the uuid is in the correct format? Also, make sure the organisation\'s name doesn\'t clash with an existing one.' ));
$fail = true ;
$this -> request -> data [ 'Server' ][ 'external_name' ] = $json [ 'name' ];
$this -> request -> data [ 'Server' ][ 'external_uuid' ] = $json [ 'uuid' ];
} else {
$this -> request -> data [ 'Server' ][ 'remote_org_id' ] = $this -> Server -> Organisation -> id ;
2019-09-18 14:37:42 +02:00
$this -> request -> data [ 'Server' ][ 'organisation_type' ] = 1 ;
2018-07-19 11:48:22 +02:00
}
}
}
}
if ( ! $fail ) {
if ( Configure :: read ( 'MISP.host_org_id' ) == 0 || $this -> request -> data [ 'Server' ][ 'remote_org_id' ] != Configure :: read ( 'MISP.host_org_id' )) {
$this -> request -> data [ 'Server' ][ 'internal' ] = 0 ;
}
$this -> request -> data [ 'Server' ][ 'org_id' ] = $this -> Auth -> user ( 'org_id' );
2019-03-25 17:35:02 +01:00
if ( empty ( $this -> request -> data [ 'Server' ][ 'push_rules' ])) {
$this -> request -> data [ 'Server' ][ 'push_rules' ] = '[]' ;
}
if ( empty ( $this -> request -> data [ 'Server' ][ 'pull_rules' ])) {
$this -> request -> data [ 'Server' ][ 'pull_rules' ] = '[]' ;
}
2018-07-19 11:48:22 +02:00
if ( $this -> Server -> save ( $this -> request -> data )) {
if ( isset ( $this -> request -> data [ 'Server' ][ 'submitted_cert' ])) {
$this -> __saveCert ( $this -> request -> data , $this -> Server -> id , false );
}
if ( isset ( $this -> request -> data [ 'Server' ][ 'submitted_client_cert' ])) {
$this -> __saveCert ( $this -> request -> data , $this -> Server -> id , true );
}
if ( $this -> _isRest ()) {
$server = $this -> Server -> find ( 'first' , array (
'conditions' => array ( 'Server.id' => $this -> Server -> id ),
'recursive' => - 1
));
return $this -> RestResponse -> viewData ( $server , $this -> response -> type ());
} else {
$this -> Flash -> success ( __ ( 'The server has been saved' ));
$this -> redirect ( array ( 'action' => 'index' ));
}
} else {
if ( $this -> _isRest ()) {
2019-03-13 12:24:53 +01:00
return $this -> RestResponse -> saveFailResponse ( 'Servers' , 'add' , false , $this -> Server -> validationErrors , $this -> response -> type ());
2018-07-19 11:48:22 +02:00
} else {
$this -> Flash -> error ( __ ( 'The server could not be saved. Please, try again.' ));
}
}
}
}
}
if ( $this -> _isRest ()) {
return $this -> RestResponse -> describe ( 'Servers' , 'add' , false , $this -> response -> type ());
} else {
$organisationOptions = array ( 0 => 'Local organisation' , 1 => 'External organisation' , 2 => 'New external organisation' );
$temp = $this -> Server -> Organisation -> find ( 'all' , array (
'conditions' => array ( 'local' => true ),
'fields' => array ( 'id' , 'name' ),
'order' => array ( 'lower(Organisation.name) ASC' )
));
$localOrganisations = array ();
$allOrgs = array ();
foreach ( $temp as $o ) {
$localOrganisations [ $o [ 'Organisation' ][ 'id' ]] = $o [ 'Organisation' ][ 'name' ];
$allOrgs [] = array ( 'id' => $o [ 'Organisation' ][ 'id' ], 'name' => $o [ 'Organisation' ][ 'name' ]);
}
$temp = $this -> Server -> Organisation -> find ( 'all' , array (
'conditions' => array ( 'local' => false ),
'fields' => array ( 'id' , 'name' ),
'order' => array ( 'lower(Organisation.name) ASC' )
));
$externalOrganisations = array ();
foreach ( $temp as $o ) {
$externalOrganisations [ $o [ 'Organisation' ][ 'id' ]] = $o [ 'Organisation' ][ 'name' ];
$allOrgs [] = array ( 'id' => $o [ 'Organisation' ][ 'id' ], 'name' => $o [ 'Organisation' ][ 'name' ]);
}
$this -> set ( 'host_org_id' , Configure :: read ( 'MISP.host_org_id' ));
$this -> set ( 'organisationOptions' , $organisationOptions );
$this -> set ( 'localOrganisations' , $localOrganisations );
$this -> set ( 'externalOrganisations' , $externalOrganisations );
$this -> set ( 'allOrganisations' , $allOrgs );
2020-06-22 16:14:16 +02:00
$this -> set ( 'allTags' , $this -> __getTags ());
2018-07-19 11:48:22 +02:00
$this -> set ( 'host_org_id' , Configure :: read ( 'MISP.host_org_id' ));
2020-01-23 09:42:16 +01:00
$this -> render ( 'edit' );
2018-07-19 11:48:22 +02:00
}
}
2019-04-02 11:29:10 +02:00
2018-07-19 11:48:22 +02:00
public function edit ( $id = null )
{
$this -> Server -> id = $id ;
if ( ! $this -> Server -> exists ()) {
throw new NotFoundException ( __ ( 'Invalid server' ));
}
$s = $this -> Server -> read ( null , $id );
if ( ! $this -> _isSiteAdmin ()) {
$this -> redirect ( array ( 'controller' => 'servers' , 'action' => 'index' ));
}
if ( $this -> request -> is ( 'post' ) || $this -> request -> is ( 'put' )) {
if ( empty ( Configure :: read ( 'MISP.host_org_id' ))) {
$this -> request -> data [ 'Server' ][ 'internal' ] = 0 ;
}
if ( $this -> _isRest ()) {
if ( ! isset ( $this -> request -> data [ 'Server' ])) {
$this -> request -> data = array ( 'Server' => $this -> request -> data );
}
}
if ( isset ( $this -> request -> data [ 'Server' ][ 'json' ])) {
$json = json_decode ( $this -> request -> data [ 'Server' ][ 'json' ], true );
} else {
$json = null ;
}
$fail = false ;
// test the filter fields
if ( ! empty ( $this -> request -> data [ 'Server' ][ 'pull_rules' ]) && ! $this -> Server -> isJson ( $this -> request -> data [ 'Server' ][ 'pull_rules' ])) {
$fail = true ;
$error_msg = __ ( 'The pull filter rules must be in valid JSON format.' );
if ( $this -> _isRest ()) {
return $this -> RestResponse -> saveFailResponse ( 'Servers' , 'edit' , false , array ( 'pull_rules' => $error_msg ), $this -> response -> type ());
} else {
$this -> Flash -> error ( $error_msg );
}
}
if ( ! $fail && ! empty ( $this -> request -> data [ 'Server' ][ 'push_rules' ]) && ! $this -> Server -> isJson ( $this -> request -> data [ 'Server' ][ 'push_rules' ])) {
$fail = true ;
$error_msg = __ ( 'The push filter rules must be in valid JSON format.' );
if ( $this -> _isRest ()) {
return $this -> RestResponse -> saveFailResponse ( 'Servers' , 'edit' , false , array ( 'push_rules' => $error_msg ), $this -> response -> type ());
} else {
$this -> Flash -> error ( $error_msg );
}
}
if ( ! $fail ) {
// say what fields are to be updated
2020-06-10 09:36:34 +02:00
$fieldList = array ( 'id' , 'url' , 'push' , 'pull' , 'push_sightings' , 'push_galaxy_clusters' , 'pull_galaxy_clusters' , 'caching_enabled' , 'unpublish_event' , 'publish_without_email' , 'remote_org_id' , 'name' , 'self_signed' , 'cert_file' , 'client_cert_file' , 'push_rules' , 'pull_rules' , 'internal' , 'skip_proxy' );
2018-07-19 11:48:22 +02:00
$this -> request -> data [ 'Server' ][ 'id' ] = $id ;
if ( isset ( $this -> request -> data [ 'Server' ][ 'authkey' ]) && " " != $this -> request -> data [ 'Server' ][ 'authkey' ]) {
$fieldList [] = 'authkey' ;
}
if ( isset ( $this -> request -> data [ 'Server' ][ 'organisation_type' ]) && isset ( $json )) {
// adds 'remote_org_id' in the fields to update
$fieldList [] = 'remote_org_id' ;
if ( $this -> request -> data [ 'Server' ][ 'organisation_type' ] < 2 ) {
$this -> request -> data [ 'Server' ][ 'remote_org_id' ] = $json [ 'id' ];
} else {
$existingOrgs = $this -> Server -> Organisation -> find ( 'first' , array (
'conditions' => array ( 'uuid' => $json [ 'uuid' ]),
'recursive' => - 1 ,
'fields' => array ( 'id' , 'uuid' )
));
if ( ! empty ( $existingOrgs )) {
$fail = true ;
if ( $this -> _isRest ()) {
return $this -> RestResponse -> saveFailResponse ( 'Servers' , 'edit' , false , array ( 'Organisation' => 'Remote Organisation\'s uuid already used' ), $this -> response -> type ());
} else {
$this -> Flash -> error ( __ ( 'That organisation could not be created as the uuid is in use already.' ));
}
}
if ( ! $fail ) {
$this -> Server -> Organisation -> create ();
$orgSave = $this -> Server -> Organisation -> save ( array (
'name' => $json [ 'name' ],
'uuid' => $json [ 'uuid' ],
'local' => 0 ,
'created_by' => $this -> Auth -> user ( 'id' )
));
if ( ! $orgSave ) {
if ( $this -> _isRest ()) {
return $this -> RestResponse -> saveFailResponse ( 'Servers' , 'edit' , false , $this -> Server -> Organisation -> validationError , $this -> response -> type ());
} else {
$this -> Flash -> error ( __ ( 'Couldn\'t save the new organisation, are you sure that the uuid is in the correct format?.' ));
}
$fail = true ;
$this -> request -> data [ 'Server' ][ 'external_name' ] = $json [ 'name' ];
$this -> request -> data [ 'Server' ][ 'external_uuid' ] = $json [ 'uuid' ];
} else {
$this -> request -> data [ 'Server' ][ 'remote_org_id' ] = $this -> Server -> Organisation -> id ;
}
}
}
if ( empty ( Configure :: read ( 'MISP.host_org_id' )) || $this -> request -> data [ 'Server' ][ 'remote_org_id' ] != Configure :: read ( 'MISP.host_org_id' )) {
$this -> request -> data [ 'Server' ][ 'internal' ] = 0 ;
}
}
}
if ( ! $fail ) {
// Save the data
if ( $this -> Server -> save ( $this -> request -> data , true , $fieldList )) {
if ( isset ( $this -> request -> data [ 'Server' ][ 'submitted_cert' ]) && ( ! isset ( $this -> request -> data [ 'Server' ][ 'delete_cert' ]) || ! $this -> request -> data [ 'Server' ][ 'delete_cert' ])) {
$this -> __saveCert ( $this -> request -> data , $this -> Server -> id , false );
} else {
if ( isset ( $this -> request -> data [ 'Server' ][ 'delete_cert' ]) && $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' ]) && ( ! isset ( $this -> request -> data [ 'Server' ][ 'delete_client_cert' ]) || ! $this -> request -> data [ 'Server' ][ 'delete_client_cert' ])) {
$this -> __saveCert ( $this -> request -> data , $this -> Server -> id , true );
} else {
if ( isset ( $this -> request -> data [ 'Server' ][ 'delete_client_cert' ]) && $this -> request -> data [ 'Server' ][ 'delete_client_cert' ]) {
$this -> __saveCert ( $this -> request -> data , $this -> Server -> id , true , true );
}
}
if ( $this -> _isRest ()) {
$server = $this -> Server -> find ( 'first' , array (
'conditions' => array ( 'Server.id' => $this -> Server -> id ),
'recursive' => - 1
));
return $this -> RestResponse -> viewData ( $server , $this -> response -> type ());
} else {
$this -> Flash -> success ( __ ( 'The server has been saved' ));
$this -> redirect ( array ( 'action' => 'index' ));
}
} else {
if ( $this -> _isRest ()) {
return $this -> RestResponse -> saveFailResponse ( 'Servers' , 'edit' , false , $this -> Server -> validationError , $this -> response -> type ());
} else {
$this -> Flash -> error ( __ ( 'The server could not be saved. Please, try again.' ));
}
}
}
} else {
$this -> Server -> read ( null , $id );
$this -> Server -> set ( 'authkey' , '' );
$this -> request -> data = $this -> Server -> data ;
}
if ( $this -> _isRest ()) {
return $this -> RestResponse -> describe ( 'Servers' , 'edit' , false , $this -> response -> type ());
} else {
$organisationOptions = array ( 0 => 'Local organisation' , 1 => 'External organisation' , 2 => 'New external organisation' );
$temp = $this -> Server -> Organisation -> find ( 'all' , array (
'conditions' => array ( 'local' => true ),
'fields' => array ( 'id' , 'name' ),
'order' => array ( 'lower(Organisation.name) ASC' )
));
$localOrganisations = array ();
$allOrgs = array ();
foreach ( $temp as $o ) {
$localOrganisations [ $o [ 'Organisation' ][ 'id' ]] = $o [ 'Organisation' ][ 'name' ];
$allOrgs [] = array ( 'id' => $o [ 'Organisation' ][ 'id' ], 'name' => $o [ 'Organisation' ][ 'name' ]);
}
$temp = $this -> Server -> Organisation -> find ( 'all' , array (
'conditions' => array ( 'local' => false ),
'fields' => array ( 'id' , 'name' ),
'order' => array ( 'lower(Organisation.name) ASC' )
));
$externalOrganisations = array ();
foreach ( $temp as $o ) {
$externalOrganisations [ $o [ 'Organisation' ][ 'id' ]] = $o [ 'Organisation' ][ 'name' ];
$allOrgs [] = array ( 'id' => $o [ 'Organisation' ][ 'id' ], 'name' => $o [ 'Organisation' ][ 'name' ]);
}
$oldRemoteSetting = 0 ;
if ( ! $this -> Server -> data [ 'RemoteOrg' ][ 'local' ]) {
$oldRemoteSetting = 1 ;
}
$this -> set ( 'host_org_id' , Configure :: read ( 'MISP.host_org_id' ));
$this -> set ( 'oldRemoteSetting' , $oldRemoteSetting );
$this -> set ( 'oldRemoteOrg' , $this -> Server -> data [ 'RemoteOrg' ][ 'id' ]);
$this -> set ( 'organisationOptions' , $organisationOptions );
$this -> set ( 'localOrganisations' , $localOrganisations );
$this -> set ( 'externalOrganisations' , $externalOrganisations );
$this -> set ( 'allOrganisations' , $allOrgs );
2020-06-22 16:14:16 +02:00
$this -> set ( 'allTags' , $this -> __getTags ());
2018-07-19 11:48:22 +02:00
$this -> set ( 'server' , $s );
2019-02-23 12:54:54 +01:00
$this -> set ( 'id' , $id );
2018-07-19 11:48:22 +02:00
$this -> set ( 'host_org_id' , Configure :: read ( 'MISP.host_org_id' ));
}
}
public function delete ( $id = null )
{
if ( ! $this -> request -> is ( 'post' )) {
2019-07-29 10:23:00 +02:00
throw new MethodNotAllowedException ( __ ( 'This endpoint expects POST requests.' ));
2018-07-19 11:48:22 +02:00
}
$this -> Server -> id = $id ;
if ( ! $this -> Server -> exists ()) {
throw new NotFoundException ( __ ( 'Invalid server' ));
}
$s = $this -> Server -> read ( null , $id );
if ( ! $this -> _isSiteAdmin ()) {
2019-07-29 10:23:00 +02:00
$message = __ ( 'You don\'t have the privileges to do that.' );
if ( $this -> _isRest ()) {
throw new MethodNotAllowedException ( $message );
} else {
$this -> Flash -> error ( $message );
$this -> redirect ( array ( 'controller' => 'servers' , 'action' => 'index' ));
}
2018-07-19 11:48:22 +02:00
}
if ( $this -> Server -> delete ()) {
2019-07-29 10:23:00 +02:00
$message = __ ( 'Server deleted' );
if ( $this -> _isRest ()) {
return $this -> RestResponse -> saveSuccessResponse ( 'Servers' , 'delete' , $message , $this -> response -> type ());
} else {
$this -> Flash -> success ( $message );
$this -> redirect ( array ( 'controller' => 'servers' , 'action' => 'index' ));
}
}
$message = __ ( 'Server was not deleted' );
if ( $this -> _isRest ()) {
return $this -> RestResponse -> saveFailResponse ( 'Servers' , 'delete' , $id , $message , $this -> response -> type ());
} else {
$this -> Flash -> error ( $message );
2018-07-19 11:48:22 +02:00
$this -> redirect ( array ( 'action' => 'index' ));
}
}
2020-06-30 10:45:36 +02:00
public function eventBlockRule ()
{
$this -> AdminSetting = ClassRegistry :: init ( 'AdminSetting' );
$setting = $this -> AdminSetting -> find ( 'first' , [
'conditions' => [ 'setting' => 'eventBlockRule' ],
'recursive' => - 1
]);
if ( empty ( $setting )) {
$setting = [ 'setting' => 'eventBlockRule' ];
if ( $this -> request -> is ( 'post' )) {
$this -> AdminSetting -> create ();
}
}
if ( $this -> request -> is ( 'post' )) {
if ( ! empty ( $this -> request -> data [ 'Server' ])) {
$this -> request -> data = $this -> request -> data [ 'Server' ];
}
$setting [ 'AdminSetting' ][ 'setting' ] = 'eventBlockRule' ;
$setting [ 'AdminSetting' ][ 'value' ] = $this -> request -> data [ 'value' ];
$result = $this -> AdminSetting -> save ( $setting );
if ( $result ) {
$message = __ ( 'Settings saved' );
} else {
$message = __ ( 'Could not save the settings. Invalid input.' );
}
if ( $this -> _isRest ()) {
if ( $result ) {
return $this -> RestResponse -> saveFailResponse ( 'Servers' , 'eventBlockRule' , false , $message , $this -> response -> type ());
} else {
return $this -> RestResponse -> saveSuccessResponse ( 'Servers' , 'eventBlockRule' , $message , $this -> response -> type ());
}
} else {
if ( $result ) {
$this -> Flash -> success ( $message );
$this -> redirect ( '/' );
} else {
$this -> Flash -> error ( $message );
}
}
}
$this -> set ( 'setting' , $setting );
}
2018-07-19 11:48:22 +02:00
/**
* Pull one or more events with attributes from a remote instance .
* Set $technique to
2019-02-10 13:08:12 +01:00
* full - download everything
* incremental - only new events
* < int > - specific id of the event to pull
2018-07-19 11:48:22 +02:00
*/
2018-08-22 17:00:13 +02:00
public function pull ( $id = null , $technique = 'full' )
2018-07-19 11:48:22 +02:00
{
2019-07-29 10:14:49 +02:00
if ( ! empty ( $id )) {
$this -> Server -> id = $id ;
} else if ( ! empty ( $this -> request -> data [ 'id' ])) {
$this -> Server -> id = $this -> request -> data [ 'id' ];
} else {
throw new NotFoundException ( __ ( 'Invalid server' ));
}
2018-07-19 11:48:22 +02:00
if ( ! $this -> Server -> exists ()) {
throw new NotFoundException ( __ ( 'Invalid server' ));
}
$s = $this -> Server -> read ( null , $id );
2018-11-23 14:11:33 +01:00
$error = false ;
2018-07-19 11:48:22 +02:00
if ( ! $this -> _isSiteAdmin () && ! ( $s [ 'Server' ][ 'org_id' ] == $this -> Auth -> user ( 'org_id' ) && $this -> _isAdmin ())) {
2018-11-23 14:11:33 +01:00
throw new MethodNotAllowedException ( __ ( 'You are not authorised to do that.' ));
2018-07-19 11:48:22 +02:00
}
$this -> Server -> id = $id ;
if ( ! $this -> Server -> exists ()) {
throw new NotFoundException ( __ ( 'Invalid server' ));
}
if ( false == $this -> Server -> data [ 'Server' ][ 'pull' ] && ( $technique == 'full' || $technique == 'incremental' )) {
2018-11-23 14:11:33 +01:00
$error = __ ( 'Pull setting not enabled for this server.' );
}
2020-06-30 08:49:47 +02:00
if ( false == $this -> Server -> data [ 'Server' ][ 'pull_galaxy_clusters' ] && ( $technique == 'pull_relevant_clusters' )) {
2020-06-25 15:01:54 +02:00
$error = __ ( 'Pull setting not enabled for this server.' );
}
2018-11-23 14:11:33 +01:00
if ( empty ( $error )) {
if ( ! Configure :: read ( 'MISP.background_jobs' )) {
$result = $this -> Server -> pull ( $this -> Auth -> user (), $id , $technique , $s );
if ( is_array ( $result )) {
2020-06-10 09:36:34 +02:00
$success = sprintf ( __ ( 'Pull completed. %s events pulled, %s events could not be pulled, %s proposals pulled, %s sightings pulled, %s clusters pulled.' , count ( $result [ 0 ]), count ( $result [ 1 ]), $result [ 2 ], $result [ 3 ], $result [ 4 ]));
2018-11-23 14:11:33 +01:00
} else {
$error = $result ;
}
$this -> set ( 'successes' , $result [ 0 ]);
$this -> set ( 'fails' , $result [ 1 ]);
$this -> set ( 'pulledProposals' , $result [ 2 ]);
2019-11-22 21:53:51 +01:00
$this -> set ( 'pulledSightings' , $result [ 3 ]);
2018-11-23 14:11:33 +01:00
} else {
$this -> loadModel ( 'Job' );
$this -> Job -> create ();
$data = array (
'worker' => 'default' ,
'job_type' => 'pull' ,
'job_input' => 'Server: ' . $id ,
'status' => 0 ,
'retries' => 0 ,
'org' => $this -> Auth -> user ( 'Organisation' )[ 'name' ],
2019-03-26 15:02:05 +01:00
'message' => __ ( 'Pulling.' ),
2018-11-23 14:11:33 +01:00
);
$this -> Job -> save ( $data );
$jobId = $this -> Job -> id ;
$process_id = CakeResque :: enqueue (
'default' ,
'ServerShell' ,
array ( 'pull' , $this -> Auth -> user ( 'id' ), $id , $technique , $jobId )
);
$this -> Job -> saveField ( 'process_id' , $process_id );
$success = sprintf ( __ ( 'Pull queued for background execution. Job ID: %s' ), $jobId );
}
}
if ( $this -> _isRest ()) {
if ( ! empty ( $error )) {
return $this -> RestResponse -> saveFailResponse ( 'Servers' , 'pull' , false , $error , $this -> response -> type ());
} else {
return $this -> RestResponse -> saveSuccessResponse ( 'Servers' , 'pull' , $success , $this -> response -> type ());
}
} else {
if ( ! empty ( $error )) {
$this -> Flash -> error ( $error );
$this -> redirect ( array ( 'action' => 'index' ));
} else {
$this -> Flash -> success ( $success );
$this -> redirect ( $this -> referer ());
}
}
2018-07-19 11:48:22 +02:00
}
public function push ( $id = null , $technique = false )
{
2019-07-29 10:14:49 +02:00
if ( ! empty ( $id )) {
$this -> Server -> id = $id ;
} else if ( ! empty ( $this -> request -> data [ 'id' ])) {
$this -> Server -> id = $this -> request -> data [ 'id' ];
} else {
throw new NotFoundException ( __ ( 'Invalid server' ));
}
if ( ! empty ( $this -> request -> data [ 'technique' ])) {
$technique = $this -> request -> data [ 'technique' ];
}
2018-07-19 11:48:22 +02:00
if ( ! $this -> Server -> exists ()) {
throw new NotFoundException ( __ ( 'Invalid server' ));
}
$s = $this -> Server -> read ( null , $id );
if ( ! $this -> _isSiteAdmin () && ! ( $s [ 'Server' ][ 'org_id' ] == $this -> Auth -> user ( 'org_id' ) && $this -> _isAdmin ())) {
2018-08-22 17:00:13 +02:00
throw new MethodNotAllowedException ( __ ( 'You are not authorised to do that.' ));
2018-07-19 11:48:22 +02:00
}
if ( ! Configure :: read ( 'MISP.background_jobs' )) {
$server = $this -> Server -> read ( null , $id );
App :: uses ( 'SyncTool' , 'Tools' );
$syncTool = new SyncTool ();
$HttpSocket = $syncTool -> setupHttpSocket ( $server );
$result = $this -> Server -> push ( $id , $technique , false , $HttpSocket , $this -> Auth -> user ());
if ( $result === false ) {
2018-11-23 14:11:33 +01:00
$error = __ ( 'The remote server is too outdated to initiate a push towards it. Please notify the hosting organisation of the remote instance.' );
} elseif ( ! is_array ( $result )) {
$error = $result ;
}
if ( ! empty ( $error )) {
if ( $this -> _isRest ()) {
return $this -> RestResponse -> saveFailResponse ( 'Servers' , 'push' , false , $error , $this -> response -> type ());
} else {
$this -> Flash -> info ( $error );
$this -> redirect ( array ( 'action' => 'index' ));
}
}
if ( $this -> _isRest ()) {
2020-10-05 10:11:09 +02:00
return $this -> RestResponse -> saveSuccessResponse ( 'Servers' , 'push' , __ ( 'Push complete. %s events pushed, %s events could not be pushed.' , count ( $result [ 0 ]), count ( $result [ 1 ])), $this -> response -> type ());
2018-11-23 14:11:33 +01:00
} else {
$this -> set ( 'successes' , $result [ 0 ]);
$this -> set ( 'fails' , $result [ 1 ]);
}
2018-07-19 11:48:22 +02:00
} else {
$this -> loadModel ( 'Job' );
$this -> Job -> create ();
$data = array (
'worker' => 'default' ,
'job_type' => 'push' ,
'job_input' => 'Server: ' . $id ,
'status' => 0 ,
'retries' => 0 ,
'org' => $this -> Auth -> user ( 'Organisation' )[ 'name' ],
2019-03-26 15:02:05 +01:00
'message' => __ ( 'Pushing.' ),
2018-07-19 11:48:22 +02:00
);
$this -> Job -> save ( $data );
$jobId = $this -> Job -> id ;
$process_id = CakeResque :: enqueue (
'default' ,
'ServerShell' ,
array ( 'push' , $this -> Auth -> user ( 'id' ), $id , $jobId )
);
$this -> Job -> saveField ( 'process_id' , $process_id );
2018-11-23 14:11:33 +01:00
$message = sprintf ( __ ( 'Push queued for background execution. Job ID: %s' ), $jobId );
if ( $this -> _isRest ()) {
return $this -> RestResponse -> saveSuccessResponse ( 'Servers' , 'push' , $message , $this -> response -> type ());
}
2018-08-22 17:00:13 +02:00
$this -> Flash -> success ( $message );
2018-07-19 11:48:22 +02:00
$this -> redirect ( array ( 'action' => 'index' ));
}
}
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 ( 'FileAccessTool' , 'Tools' );
if ( isset ( $server [ 'Server' ][ $subm ][ 'name' ])) {
if ( $this -> request -> data [ 'Server' ][ $subm ][ 'size' ] != 0 ) {
if ( ! $this -> Server -> checkFilename ( $server [ 'Server' ][ $subm ][ 'name' ])) {
2019-03-26 15:02:05 +01:00
throw new Exception ( __ ( 'Filename not allowed' ));
2018-07-19 11:48:22 +02:00
}
$file = new File ( $server [ 'Server' ][ $subm ][ 'name' ]);
$ext = $file -> ext ();
2018-10-26 21:13:59 +02:00
if ( ! $server [ 'Server' ][ $subm ][ 'size' ] > 0 ) {
2019-03-26 15:02:05 +01:00
$this -> Flash -> error ( __ ( 'Incorrect extension or empty file.' ));
2018-07-19 11:48:22 +02:00
$this -> redirect ( array ( 'action' => 'index' ));
}
// read pem file data
$pemData = ( new FileAccessTool ()) -> readFromFile ( $server [ 'Server' ][ $subm ][ 'tmp_name' ], $server [ 'Server' ][ $subm ][ 'size' ]);
} else {
return true ;
}
} else {
$pemData = base64_decode ( $server [ 'Server' ][ $subm ]);
}
$destpath = APP . " files " . DS . " certs " . DS ;
$dir = new Folder ( APP . " files " . DS . " certs " , true );
$pemfile = new File ( $destpath . $id . $ins . '.' . $ext );
$result = $pemfile -> write ( $pemData );
$s = $this -> Server -> read ( null , $id );
$s [ 'Server' ][ $attr ] = $s [ 'Server' ][ 'id' ] . $ins . '.' . $ext ;
if ( $result ) {
$this -> Server -> save ( $s );
}
} else {
$s = $this -> Server -> read ( null , $id );
$s [ 'Server' ][ $attr ] = '' ;
$this -> Server -> save ( $s );
}
return true ;
}
public function serverSettingsReloadSetting ( $setting , $id )
{
if ( ! $this -> _isSiteAdmin ()) {
throw new MethodNotAllowedException ();
}
$pathToSetting = explode ( '.' , $setting );
if ( strpos ( $setting , 'Plugin.Enrichment' ) !== false || strpos ( $setting , 'Plugin.Import' ) !== false || strpos ( $setting , 'Plugin.Export' ) !== false || strpos ( $setting , 'Plugin.Cortex' ) !== false ) {
$settingObject = $this -> Server -> getCurrentServerSettings ();
} else {
$settingObject = $this -> Server -> serverSettings ;
}
foreach ( $pathToSetting as $key ) {
if ( ! isset ( $settingObject [ $key ])) {
throw new MethodNotAllowedException ();
}
$settingObject = $settingObject [ $key ];
}
$result = $this -> Server -> serverSettingReadSingle ( $settingObject , $setting , $key );
$this -> set ( 'setting' , $result );
$priorityErrorColours = array ( 0 => 'red' , 1 => 'yellow' , 2 => 'green' );
$this -> set ( 'priorityErrorColours' , $priorityErrorColours );
$priorities = array ( 0 => 'Critical' , 1 => 'Recommended' , 2 => 'Optional' , 3 => 'Deprecated' );
$this -> set ( 'priorities' , $priorities );
$this -> set ( 'k' , $id );
$this -> layout = false ;
$subGroup = 'general' ;
if ( $pathToSetting [ 0 ] === 'Plugin' ) {
$subGroup = explode ( '_' , $pathToSetting [ 1 ])[ 0 ];
}
$this -> set ( 'subGroup' , $subGroup );
$this -> render ( '/Elements/healthElements/settings_row' );
}
public function serverSettings ( $tab = false )
{
if ( ! $this -> _isSiteAdmin ()) {
throw new MethodNotAllowedException ();
}
if ( $this -> request -> is ( 'Get' )) {
$tabs = array (
'MISP' => array ( 'count' => 0 , 'errors' => 0 , 'severity' => 5 ),
'Encryption' => array ( 'count' => 0 , 'errors' => 0 , 'severity' => 5 ),
'Proxy' => array ( 'count' => 0 , 'errors' => 0 , 'severity' => 5 ),
'Security' => array ( 'count' => 0 , 'errors' => 0 , 'severity' => 5 ),
'Plugin' => array ( 'count' => 0 , 'errors' => 0 , 'severity' => 5 )
);
2019-03-26 15:02:05 +01:00
$writeableErrors = array ( 0 => __ ( 'OK' ), 1 => __ ( 'not found' ), 2 => __ ( 'is not writeable' ));
$readableErrors = array ( 0 => __ ( 'OK' ), 1 => __ ( 'not readable' ));
2019-09-23 09:38:15 +02:00
$gpgErrors = array ( 0 => __ ( 'OK' ), 1 => __ ( 'FAIL: settings not set' ), 2 => __ ( 'FAIL: Failed to load GnuPG' ), 3 => __ ( 'FAIL: Issues with the key/passphrase' ), 4 => __ ( 'FAIL: sign failed' ));
2019-03-26 15:02:05 +01:00
$proxyErrors = array ( 0 => __ ( 'OK' ), 1 => __ ( 'not configured (so not tested)' ), 2 => __ ( 'Getting URL via proxy failed' ));
$zmqErrors = array ( 0 => __ ( 'OK' ), 1 => __ ( 'not enabled (so not tested)' ), 2 => __ ( 'Python ZeroMQ library not installed correctly.' ), 3 => __ ( 'ZeroMQ script not running.' ));
$stixOperational = array ( 0 => __ ( 'Some of the libraries related to STIX are not installed. Make sure that all libraries listed below are correctly installed.' ), 1 => __ ( 'OK' ));
$stixVersion = array ( 0 => __ ( 'Incorrect STIX version installed, found $current, expecting $expected' ), 1 => __ ( 'OK' ));
$stix2Version = array ( 0 => __ ( 'Incorrect STIX2 version installed, found $current, expecting $expected' ), 1 => __ ( 'OK' ));
$cyboxVersion = array ( 0 => __ ( 'Incorrect CyBox version installed, found $current, expecting $expected' ), 1 => __ ( 'OK' ));
$mixboxVersion = array ( 0 => __ ( 'Incorrect mixbox version installed, found $current, expecting $expected' ), 1 => __ ( 'OK' ));
$maecVersion = array ( 0 => __ ( 'Incorrect maec version installed, found $current, expecting $expected' ), 1 => __ ( 'OK' ));
$pymispVersion = array ( 0 => __ ( 'Incorrect PyMISP version installed, found $current, expecting $expected' ), 1 => __ ( 'OK' ));
$sessionErrors = array ( 0 => __ ( 'OK' ), 1 => __ ( 'High' ), 2 => __ ( 'Alternative setting used' ), 3 => __ ( 'Test failed' ));
$moduleErrors = array ( 0 => __ ( 'OK' ), 1 => __ ( 'System not enabled' ), 2 => __ ( 'No modules found' ));
2018-07-19 11:48:22 +02:00
$finalSettings = $this -> Server -> serverSettingsRead ();
$issues = array (
'errors' => array (
0 => array (
'value' => 0 ,
2019-03-26 15:02:05 +01:00
'description' => __ ( 'MISP will not operate correctly or will be unsecure until these issues are resolved.' )
2018-07-19 11:48:22 +02:00
),
1 => array (
'value' => 0 ,
2019-03-26 15:02:05 +01:00
'description' => __ ( 'Some of the features of MISP cannot be utilised until these issues are resolved.' )
2018-07-19 11:48:22 +02:00
),
2 => array (
'value' => 0 ,
2019-03-26 15:02:05 +01:00
'description' => __ ( 'There are some optional tweaks that could be done to improve the looks of your MISP instance.' )
2018-07-19 11:48:22 +02:00
),
),
'deprecated' => array (),
'overallHealth' => 3 ,
);
$dumpResults = array ();
$tempArray = array ();
foreach ( $finalSettings as $k => $result ) {
if ( $result [ 'level' ] == 3 ) {
$issues [ 'deprecated' ] ++ ;
}
$tabs [ $result [ 'tab' ]][ 'count' ] ++ ;
if ( isset ( $result [ 'error' ]) && $result [ 'level' ] < 3 ) {
$issues [ 'errors' ][ $result [ 'level' ]][ 'value' ] ++ ;
if ( $result [ 'level' ] < $issues [ 'overallHealth' ]) {
$issues [ 'overallHealth' ] = $result [ 'level' ];
}
$tabs [ $result [ 'tab' ]][ 'errors' ] ++ ;
if ( $result [ 'level' ] < $tabs [ $result [ 'tab' ]][ 'severity' ]) {
$tabs [ $result [ 'tab' ]][ 'severity' ] = $result [ 'level' ];
}
}
2021-01-13 14:10:13 +01:00
if ( isset ( $result [ 'optionsSource' ]) && is_callable ( $result [ 'optionsSource' ])) {
$result [ 'options' ] = $result [ 'optionsSource' ]();
2018-07-19 11:48:22 +02:00
}
$dumpResults [] = $result ;
if ( $result [ 'tab' ] == $tab ) {
if ( isset ( $result [ 'subGroup' ])) {
$tempArray [ $result [ 'subGroup' ]][] = $result ;
} else {
$tempArray [ 'general' ][] = $result ;
}
}
}
$finalSettings = $tempArray ;
// Diagnostics portion
$diagnostic_errors = 0 ;
App :: uses ( 'File' , 'Utility' );
App :: uses ( 'Folder' , 'Utility' );
2021-01-13 14:10:13 +01:00
if ( $tab === 'files' ) {
2018-07-19 11:48:22 +02:00
$files = $this -> __manageFiles ();
$this -> set ( 'files' , $files );
}
// Only run this check on the diagnostics tab
2021-01-13 14:10:13 +01:00
if ( $tab === 'diagnostics' || $tab === 'download' || $this -> _isRest ()) {
2018-07-19 11:48:22 +02:00
$php_ini = php_ini_loaded_file ();
$this -> set ( 'php_ini' , $php_ini );
2018-09-28 14:59:26 +02:00
2020-05-05 15:23:26 +02:00
$attachmentTool = new AttachmentTool ();
2018-07-19 11:48:22 +02:00
try {
2020-05-05 15:23:26 +02:00
$advanced_attachments = $attachmentTool -> checkAdvancedExtractionStatus ( $this -> Server -> getPythonVersion ());
2018-07-19 11:48:22 +02:00
} catch ( Exception $e ) {
2019-10-05 15:40:34 +02:00
$this -> log ( $e -> getMessage (), LOG_NOTICE );
2018-07-19 11:48:22 +02:00
$advanced_attachments = false ;
}
2019-10-05 15:40:34 +02:00
2018-07-19 11:48:22 +02:00
$this -> set ( 'advanced_attachments' , $advanced_attachments );
// check if the current version of MISP is outdated or not
$version = $this -> __checkVersion ();
$this -> set ( 'version' , $version );
$gitStatus = $this -> Server -> getCurrentGitStatus ();
$this -> set ( 'branch' , $gitStatus [ 'branch' ]);
$this -> set ( 'commit' , $gitStatus [ 'commit' ]);
$this -> set ( 'latestCommit' , $gitStatus [ 'latestCommit' ]);
$phpSettings = array (
2021-01-13 14:10:13 +01:00
'max_execution_time' => array (
'explanation' => 'The maximum duration that a script can run (does not affect the background workers). A too low number will break long running scripts like comprehensive API exports' ,
'recommended' => 300 ,
'unit' => false
),
'memory_limit' => array (
'explanation' => 'The maximum memory that PHP can consume. It is recommended to raise this number since certain exports can generate a fair bit of memory usage' ,
'recommended' => 2048 ,
'unit' => 'M'
),
'upload_max_filesize' => array (
'explanation' => 'The maximum size that an uploaded file can be. It is recommended to raise this number to allow for the upload of larger samples' ,
'recommended' => 50 ,
'unit' => 'M'
),
'post_max_size' => array (
'explanation' => 'The maximum size of a POSTed message, this has to be at least the same size as the upload_max_filesize setting' ,
'recommended' => 50 ,
'unit' => 'M'
)
2018-07-19 11:48:22 +02:00
);
foreach ( $phpSettings as $setting => $settingArray ) {
$phpSettings [ $setting ][ 'value' ] = ini_get ( $setting );
if ( $settingArray [ 'unit' ]) {
$phpSettings [ $setting ][ 'value' ] = intval ( rtrim ( $phpSettings [ $setting ][ 'value' ], $phpSettings [ $setting ][ 'unit' ]));
} else {
$phpSettings [ $setting ][ 'value' ] = intval ( $phpSettings [ $setting ][ 'value' ]);
}
}
$this -> set ( 'phpSettings' , $phpSettings );
if ( $version && ( ! $version [ 'upToDate' ] || $version [ 'upToDate' ] == 'older' )) {
$diagnostic_errors ++ ;
}
// check if the STIX and Cybox libraries are working and the correct version using the test script stixtest.py
2019-02-08 11:26:42 +01:00
$stix = $this -> Server -> stixDiagnostics ( $diagnostic_errors , $stixVersion , $cyboxVersion , $mixboxVersion , $maecVersion , $stix2Version , $pymispVersion );
2018-07-19 11:48:22 +02:00
2019-04-30 15:36:13 +02:00
$yaraStatus = $this -> Server -> yaraDiagnostics ( $diagnostic_errors );
2018-07-19 11:48:22 +02:00
// if GnuPG is set up in the settings, try to encrypt a test message
$gpgStatus = $this -> Server -> gpgDiagnostics ( $diagnostic_errors );
// if the message queue pub/sub is enabled, check whether the extension works
$zmqStatus = $this -> Server -> zmqDiagnostics ( $diagnostic_errors );
// if Proxy is set up in the settings, try to connect to a test URL
$proxyStatus = $this -> Server -> proxyDiagnostics ( $diagnostic_errors );
2019-08-21 17:01:52 +02:00
// get the DB diagnostics
$dbDiagnostics = $this -> Server -> dbSpaceUsage ();
2019-09-10 15:13:06 +02:00
$dbSchemaDiagnostics = $this -> Server -> dbSchemaDiagnostic ();
2019-08-21 17:01:52 +02:00
2019-09-20 22:15:15 +02:00
$redisInfo = $this -> Server -> redisInfo ();
2018-07-19 11:48:22 +02:00
$moduleTypes = array ( 'Enrichment' , 'Import' , 'Export' , 'Cortex' );
foreach ( $moduleTypes as $type ) {
$moduleStatus [ $type ] = $this -> Server -> moduleDiagnostics ( $diagnostic_errors , $type );
}
// check the size of the session table
$sessionCount = 0 ;
$sessionStatus = $this -> Server -> sessionDiagnostics ( $diagnostic_errors , $sessionCount );
$this -> set ( 'sessionCount' , $sessionCount );
2020-10-22 23:59:49 +02:00
$this -> loadModel ( 'AttachmentScan' );
try {
$attachmentScan = [ 'status' => true , 'software' => $this -> AttachmentScan -> diagnostic ()];
} catch ( Exception $e ) {
$attachmentScan = [ 'status' => false , 'error' => $e -> getMessage ()];
}
2021-01-13 14:10:13 +01:00
$view = compact ( 'gpgStatus' , 'sessionErrors' , 'proxyStatus' , 'sessionStatus' , 'zmqStatus' , 'stixVersion' , 'cyboxVersion' , 'mixboxVersion' , 'maecVersion' , 'stix2Version' , 'pymispVersion' , 'moduleStatus' , 'yaraStatus' , 'gpgErrors' , 'proxyErrors' , 'zmqErrors' , 'stixOperational' , 'stix' , 'moduleErrors' , 'moduleTypes' , 'dbDiagnostics' , 'dbSchemaDiagnostics' , 'redisInfo' , 'attachmentScan' );
} else {
$view = [];
2018-07-19 11:48:22 +02:00
}
// check whether the files are writeable
$writeableDirs = $this -> Server -> writeableDirsDiagnostics ( $diagnostic_errors );
$writeableFiles = $this -> Server -> writeableFilesDiagnostics ( $diagnostic_errors );
$readableFiles = $this -> Server -> readableFilesDiagnostics ( $diagnostic_errors );
$extensions = $this -> Server -> extensionDiagnostics ();
// check if the encoding is not set to utf8
$dbEncodingStatus = $this -> Server -> databaseEncodingDiagnostics ( $diagnostic_errors );
2021-01-13 14:10:13 +01:00
$view = array_merge ( $view , compact ( 'diagnostic_errors' , 'tabs' , 'tab' , 'issues' , 'finalSettings' , 'writeableErrors' , 'readableErrors' , 'writeableDirs' , 'writeableFiles' , 'readableFiles' , 'extensions' , 'dbEncodingStatus' ));
$this -> set ( $view );
2018-07-19 11:48:22 +02:00
2018-10-15 18:18:47 +02:00
$workerIssueCount = 4 ;
$worker_array = array ();
2018-07-19 11:48:22 +02:00
if ( Configure :: read ( 'MISP.background_jobs' )) {
2018-10-15 18:18:47 +02:00
$workerIssueCount = 0 ;
$worker_array = $this -> Server -> workerDiagnostics ( $workerIssueCount );
2018-07-19 11:48:22 +02:00
}
2018-10-15 19:17:46 +02:00
$this -> set ( 'worker_array' , $worker_array );
2018-10-21 22:47:22 +02:00
if ( $tab == 'download' || $this -> _isRest ()) {
2018-07-19 11:48:22 +02:00
foreach ( $dumpResults as $key => $dr ) {
unset ( $dumpResults [ $key ][ 'description' ]);
}
$dump = array (
'version' => $version ,
'phpSettings' => $phpSettings ,
2020-11-16 23:48:01 +01:00
'gpgStatus' => $gpgErrors [ $gpgStatus [ 'status' ]],
2018-07-19 11:48:22 +02:00
'proxyStatus' => $proxyErrors [ $proxyStatus ],
'zmqStatus' => $zmqStatus ,
'stix' => $stix ,
'moduleStatus' => $moduleStatus ,
'writeableDirs' => $writeableDirs ,
'writeableFiles' => $writeableFiles ,
'readableFiles' => $readableFiles ,
2019-10-01 16:55:01 +02:00
'dbDiagnostics' => $dbDiagnostics ,
'dbSchemaDiagnostics' => $dbSchemaDiagnostics ,
'redisInfo' => $redisInfo ,
2018-07-19 11:48:22 +02:00
'finalSettings' => $dumpResults ,
2018-10-15 18:18:47 +02:00
'extensions' => $extensions ,
'workers' => $worker_array
2018-07-19 11:48:22 +02:00
);
foreach ( $dump [ 'finalSettings' ] as $k => $v ) {
if ( ! empty ( $v [ 'redacted' ])) {
$dump [ 'finalSettings' ][ $k ][ 'value' ] = '*****' ;
}
}
$this -> response -> body ( json_encode ( $dump , JSON_PRETTY_PRINT ));
$this -> response -> type ( 'json' );
$this -> response -> download ( 'MISP.report.json' );
return $this -> response ;
}
$priorities = array ( 0 => 'Critical' , 1 => 'Recommended' , 2 => 'Optional' , 3 => 'Deprecated' );
$this -> set ( 'priorities' , $priorities );
$this -> set ( 'workerIssueCount' , $workerIssueCount );
$priorityErrorColours = array ( 0 => 'red' , 1 => 'yellow' , 2 => 'green' );
$this -> set ( 'priorityErrorColours' , $priorityErrorColours );
$this -> set ( 'phpversion' , phpversion ());
$this -> set ( 'phpmin' , $this -> phpmin );
$this -> set ( 'phprec' , $this -> phprec );
2020-01-17 15:14:53 +01:00
$this -> set ( 'pythonmin' , $this -> pythonmin );
$this -> set ( 'pythonrec' , $this -> pythonrec );
$this -> set ( 'pymisp' , $this -> pymisp );
2018-07-19 11:48:22 +02:00
}
}
public function startWorker ( $type )
{
if ( ! $this -> _isSiteAdmin () || ! $this -> request -> is ( 'post' )) {
throw new MethodNotAllowedException ();
}
2019-10-01 13:36:37 +02:00
$validTypes = array ( 'default' , 'email' , 'scheduler' , 'cache' , 'prio' , 'update' );
2018-07-19 11:48:22 +02:00
if ( ! in_array ( $type , $validTypes )) {
throw new MethodNotAllowedException ( 'Invalid worker type.' );
}
$prepend = '' ;
if ( $type != 'scheduler' ) {
2019-10-01 13:36:37 +02:00
$workerIssueCount = 0 ;
$workerDiagnostic = $this -> Server -> workerDiagnostics ( $workerIssueCount );
2019-10-01 13:38:27 +02:00
if ( $type == 'update' && isset ( $workerDiagnostic [ 'update' ][ 'ok' ]) && $workerDiagnostic [ 'update' ][ 'ok' ]) {
2019-10-01 13:36:37 +02:00
$message = __ ( 'Only one `update` worker can run at a time' );
if ( $this -> _isRest ()) {
return $this -> RestResponse -> saveFailResponse ( 'Servers' , 'startWorker' , false , $message , $this -> response -> type ());
} else {
$this -> Flash -> error ( $message );
$this -> redirect ( '/servers/serverSettings/workers' );
}
}
2018-07-19 11:48:22 +02:00
shell_exec ( $prepend . APP . 'Console' . DS . 'cake CakeResque.CakeResque start --interval 5 --queue ' . $type . ' > /dev/null 2>&1 &' );
} else {
shell_exec ( $prepend . APP . 'Console' . DS . 'cake CakeResque.CakeResque startscheduler -i 5 > /dev/null 2>&1 &' );
}
2019-06-19 14:08:06 +02:00
$message = __ ( 'Worker start signal sent' );
if ( $this -> _isRest ()) {
return $this -> RestResponse -> saveSuccessResponse ( 'Servers' , 'startWorker' , $type , $this -> response -> type (), $message );
} else {
$this -> Flash -> info ( $message );
$this -> redirect ( '/servers/serverSettings/workers' );
}
2018-07-19 11:48:22 +02:00
}
public function stopWorker ( $pid )
{
if ( ! $this -> _isSiteAdmin () || ! $this -> request -> is ( 'post' )) {
throw new MethodNotAllowedException ();
}
$this -> Server -> killWorker ( $pid , $this -> Auth -> user ());
2019-06-19 14:08:06 +02:00
$message = __ ( 'Worker stop signal sent' );
if ( $this -> _isRest ()) {
return $this -> RestResponse -> saveSuccessResponse ( 'Servers' , 'stopWorker' , $pid , $this -> response -> type (), $message );
} else {
$this -> Flash -> info ( $message );
$this -> redirect ( '/servers/serverSettings/workers' );
}
}
public function getWorkers ()
{
2020-10-01 09:28:02 +02:00
if ( Configure :: read ( 'MISP.background_jobs' )) {
$workerIssueCount = 0 ;
$worker_array = $this -> Server -> workerDiagnostics ( $workerIssueCount );
} else {
$worker_array = [ __ ( 'Background jobs not enabled' )];
}
2019-06-19 14:08:06 +02:00
return $this -> RestResponse -> viewData ( $worker_array );
2018-07-19 11:48:22 +02:00
}
private function __checkVersion ()
{
if ( ! $this -> _isSiteAdmin ()) {
throw new MethodNotAllowedException ();
}
App :: uses ( 'SyncTool' , 'Tools' );
$syncTool = new SyncTool ();
try {
$HttpSocket = $syncTool -> setupHttpSocket ();
$response = $HttpSocket -> get ( 'https://api.github.com/repos/MISP/MISP/tags' );
$tags = $response -> body ;
} catch ( Exception $e ) {
return false ;
}
if ( $response -> isOK () && ! empty ( $tags )) {
$json_decoded_tags = json_decode ( $tags );
// find the latest version tag in the v[major].[minor].[hotfix] format
for ( $i = 0 ; $i < count ( $json_decoded_tags ); $i ++ ) {
if ( preg_match ( '/^v[0-9]+\.[0-9]+\.[0-9]+$/' , $json_decoded_tags [ $i ] -> name )) {
break ;
}
}
return $this -> Server -> checkVersion ( $json_decoded_tags [ $i ] -> name );
} else {
return false ;
}
}
2021-01-07 20:39:49 +01:00
public function idTranslator ( $localId = null )
2021-01-07 20:31:21 +01:00
{
// We retrieve the list of remote servers that we can query
$servers = $this -> Server -> find ( 'all' , [
'conditions' => [ 'OR' => [ 'pull' => true , 'push' => true ]],
'recursive' => - 1 ,
'order' => [ 'Server.priority ASC' ],
]);
2020-08-26 10:01:14 +02:00
// We generate the list of servers for the dropdown
$displayServers = array ();
2021-01-07 20:31:21 +01:00
foreach ( $servers as $s ) {
$displayServers [] = [
'name' => $s [ 'Server' ][ 'name' ],
'value' => $s [ 'Server' ][ 'id' ],
];
2020-08-26 10:01:14 +02:00
}
$this -> set ( 'servers' , $displayServers );
2021-01-07 20:39:49 +01:00
if ( $localId || $this -> request -> is ( 'post' )) {
if ( $localId && $this -> request -> is ( 'get' )) {
$this -> request -> data [ 'Event' ][ 'local' ] = 'local' ;
$this -> request -> data [ 'Event' ][ 'uuid' ] = $localId ;
}
2020-08-26 10:01:14 +02:00
$remote_events = array ();
2021-01-07 20:39:49 +01:00
if ( ! empty ( $this -> request -> data [ 'Event' ][ 'uuid' ]) && $this -> request -> data [ 'Event' ][ 'local' ] === " local " ) {
2020-08-26 10:01:14 +02:00
$local_event = $this -> Event -> fetchSimpleEvent ( $this -> Auth -> user (), $this -> request -> data [ 'Event' ][ 'uuid' ]);
2021-01-07 20:31:21 +01:00
} else if ( ! empty ( $this -> request -> data [ 'Event' ][ 'uuid' ]) && $this -> request -> data [ 'Event' ][ 'local' ] === " remote " && ! empty ( $this -> request -> data [ 'Server' ][ 'id' ])) {
2020-08-26 10:01:14 +02:00
//We check on the remote server for any event with this id and try to find a match locally
$conditions = array ( 'AND' => array ( 'Server.id' => $this -> request -> data [ 'Server' ][ 'id' ], 'Server.pull' => true ));
$remote_server = $this -> Server -> find ( 'first' , array ( 'conditions' => $conditions ));
2021-01-07 20:31:21 +01:00
if ( ! empty ( $remote_server )) {
2020-08-26 10:01:14 +02:00
try {
$remote_event = $this -> Event -> downloadEventFromServer ( $this -> request -> data [ 'Event' ][ 'uuid' ], $remote_server , null , true );
} catch ( Exception $e ) {
2021-01-12 10:46:05 +01:00
$this -> Flash -> error ( __ ( " Issue while contacting the remote server to retrieve event information " ));
2020-08-26 10:01:14 +02:00
return ;
}
$local_event = $this -> Event -> fetchSimpleEvent ( $this -> Auth -> user (), $remote_event [ 0 ][ 'uuid' ]);
2021-01-12 10:46:05 +01:00
// we record it to avoid re-querying the same server in the 2nd phase
2021-01-07 20:31:21 +01:00
if ( ! empty ( $local_event )) {
2020-08-26 10:01:14 +02:00
$remote_events [] = array (
" server_id " => $remote_server [ 'Server' ][ 'id' ],
" server_name " => $remote_server [ 'Server' ][ 'name' ],
" url " => $remote_server [ 'Server' ][ 'url' ] . " /events/view/ " . $remote_event [ 0 ][ 'id' ],
" remote_id " => $remote_event [ 0 ][ 'id' ]
);
}
}
}
2021-01-07 20:39:49 +01:00
if ( empty ( $local_event )) {
2021-01-12 10:46:05 +01:00
$this -> Flash -> error ( __ ( " This event could not be found or you don't have permissions to see it. " ));
2020-08-26 10:01:14 +02:00
return ;
} else {
$this -> Flash -> success ( __ ( 'The event has been found.' ));
}
// In the second phase, we query all configured sync servers to get their info on the event
2021-01-07 20:31:21 +01:00
foreach ( $servers as $server ) {
2020-08-26 10:01:14 +02:00
// We check if the server was not already contacted in phase 1
2021-01-07 20:39:49 +01:00
if ( count ( $remote_events ) > 0 && $remote_events [ 0 ][ 'server_id' ] == $server [ 'Server' ][ 'id' ]) {
2020-08-26 10:01:14 +02:00
continue ;
}
try {
2021-01-07 20:31:21 +01:00
$remote_event = $this -> Event -> downloadEventFromServer ( $local_event [ 'Event' ][ 'uuid' ], $server , null , true );
2020-08-26 10:01:14 +02:00
$remote_event_id = $remote_event [ 0 ][ 'id' ];
} catch ( Exception $e ) {
$remote_event_id = null ;
}
$remote_events [] = array (
2021-01-07 20:31:21 +01:00
" server_id " => $server [ 'Server' ][ 'id' ],
" server_name " => $server [ 'Server' ][ 'name' ],
" url " => isset ( $remote_event_id ) ? $server [ 'Server' ][ 'url' ] . " /events/view/ " . $remote_event_id : $server [ 'Server' ][ 'url' ],
2020-08-26 10:01:14 +02:00
" remote_id " => isset ( $remote_event_id ) ? $remote_event_id : false
);
}
$this -> set ( 'local_event' , $local_event );
$this -> set ( 'remote_events' , $remote_events );
}
2021-01-12 10:46:05 +01:00
$this -> set ( 'title_for_layout' , __ ( 'Event ID translator' ));
2020-08-26 10:01:14 +02:00
}
2019-03-18 16:17:10 +01:00
public function getSubmodulesStatus () {
if ( ! $this -> _isSiteAdmin ()) {
throw new MethodNotAllowedException ();
}
$this -> set ( 'submodules' , $this -> Server -> getSubmodulesGitStatus ());
$this -> render ( 'ajax/submoduleStatus' );
}
2019-08-15 20:01:36 +02:00
public function getSetting ( $setting_name )
{
$setting = $this -> Server -> getSettingData ( $setting_name );
if ( ! empty ( $setting [ " redacted " ])) {
throw new MethodNotAllowedException ( __ ( 'This setting is redacted.' ));
}
if ( Configure :: check ( $setting_name )) {
$setting [ 'value' ] = Configure :: read ( $setting_name );
}
return $this -> RestResponse -> viewData ( $setting );
}
2019-02-01 14:44:52 +01:00
public function serverSettingsEdit ( $setting_name , $id = false , $forceSave = false )
2018-07-19 11:48:22 +02:00
{
if ( ! $this -> _isSiteAdmin ()) {
throw new MethodNotAllowedException ();
}
2019-03-13 12:24:53 +01:00
if ( ! isset ( $setting_name )) {
2018-07-19 11:48:22 +02:00
throw new MethodNotAllowedException ();
}
2019-03-13 12:24:53 +01:00
if ( ! $this -> _isRest ()) {
if ( ! isset ( $id )) {
throw new MethodNotAllowedException ();
}
$this -> set ( 'id' , $id );
}
2019-02-01 14:44:52 +01:00
$setting = $this -> Server -> getSettingData ( $setting_name );
2020-11-19 19:08:14 +01:00
if ( $setting === false ) {
throw new NotFoundException ( __ ( 'Setting %s is invalid.' , $setting_name ));
}
2019-06-18 09:57:27 +02:00
if ( ! empty ( $setting [ 'cli_only' ])) {
throw new MethodNotAllowedException ( __ ( 'This setting can only be edited via the CLI.' ));
}
2018-07-19 11:48:22 +02:00
if ( $this -> request -> is ( 'get' )) {
2020-11-17 21:31:59 +01:00
$value = Configure :: read ( $setting [ 'name' ]);
if ( isset ( $value )) {
$setting [ 'value' ] = $value ;
2018-07-19 11:48:22 +02:00
}
2020-11-17 21:31:59 +01:00
$setting [ 'setting' ] = $setting [ 'name' ];
2021-01-13 14:10:13 +01:00
if ( isset ( $setting [ 'optionsSource' ]) && is_callable ( $setting [ 'optionsSource' ])) {
$setting [ 'options' ] = $setting [ 'optionsSource' ]();
2018-07-19 11:48:22 +02:00
}
2019-02-01 14:44:52 +01:00
$subGroup = explode ( '.' , $setting [ 'name' ]);
2018-07-19 11:48:22 +02:00
if ( $subGroup [ 0 ] === 'Plugin' ) {
$subGroup = explode ( '_' , $subGroup [ 1 ])[ 0 ];
} else {
$subGroup = 'general' ;
}
if ( $this -> _isRest ()) {
2019-02-01 14:44:52 +01:00
return $this -> RestResponse -> viewData ( array ( $setting [ 'name' ] => $setting [ 'value' ]));
2018-07-19 11:48:22 +02:00
} else {
$this -> set ( 'subGroup' , $subGroup );
2019-02-01 14:44:52 +01:00
$this -> set ( 'setting' , $setting );
2018-07-19 11:48:22 +02:00
$this -> render ( 'ajax/server_settings_edit' );
}
2020-11-17 21:31:59 +01:00
} else if ( $this -> request -> is ( 'post' )) {
2018-07-19 11:48:22 +02:00
if ( ! isset ( $this -> request -> data [ 'Server' ])) {
$this -> request -> data = array ( 'Server' => $this -> request -> data );
}
2020-12-04 09:23:12 +01:00
if ( ! isset ( $this -> request -> data [ 'Server' ][ 'value' ]) || ! is_scalar ( $this -> request -> data [ 'Server' ][ 'value' ])) {
2018-07-19 11:48:22 +02:00
if ( $this -> _isRest ()) {
return $this -> RestResponse -> saveFailResponse ( 'Servers' , 'serverSettingsEdit' , false , 'Invalid input. Expected: {"value": "new_setting"}' , $this -> response -> type ());
}
}
2019-08-07 15:03:32 +02:00
if ( ! empty ( $this -> request -> data [ 'Server' ][ 'force' ])) {
$forceSave = $this -> request -> data [ 'Server' ][ 'force' ];
}
2018-07-19 11:48:22 +02:00
if ( trim ( $this -> request -> data [ 'Server' ][ 'value' ]) === '*****' ) {
if ( $this -> _isRest ()) {
return $this -> RestResponse -> saveFailResponse ( 'Servers' , 'serverSettingsEdit' , false , 'No change.' , $this -> response -> type ());
} else {
return new CakeResponse ( array ( 'body' => json_encode ( array ( 'saved' => false , 'errors' => 'No change.' )), 'status' => 200 , 'type' => 'json' ));
}
}
$this -> autoRender = false ;
$this -> loadModel ( 'Log' );
if ( ! is_writeable ( APP . 'Config/config.php' )) {
$this -> Log -> create ();
2020-11-17 21:31:59 +01:00
$this -> Log -> save ( array (
2018-07-19 11:48:22 +02:00
'org' => $this -> Auth -> user ( 'Organisation' )[ 'name' ],
'model' => 'Server' ,
'model_id' => 0 ,
'email' => $this -> Auth -> user ( 'email' ),
'action' => 'serverSettingsEdit' ,
'user_id' => $this -> Auth -> user ( 'id' ),
'title' => 'Server setting issue' ,
2019-02-01 14:44:52 +01:00
'change' => 'There was an issue witch changing ' . $setting [ 'name' ] . ' to ' . $this -> request -> data [ 'Server' ][ 'value' ] . '. The error message returned is: app/Config.config.php is not writeable to the apache user. No changes were made.' ,
2018-07-19 11:48:22 +02:00
));
if ( $this -> _isRest ()) {
return $this -> RestResponse -> saveFailResponse ( 'Servers' , 'serverSettingsEdit' , false , 'app/Config.config.php is not writeable to the apache user.' , $this -> response -> type ());
} else {
return new CakeResponse ( array ( 'body' => json_encode ( array ( 'saved' => false , 'errors' => 'app/Config.config.php is not writeable to the apache user.' )), 'status' => 200 , 'type' => 'json' ));
}
}
2019-02-01 14:44:52 +01:00
$result = $this -> Server -> serverSettingsEditValue ( $this -> Auth -> user (), $setting , $this -> request -> data [ 'Server' ][ 'value' ], $forceSave );
if ( $result === true ) {
if ( $this -> _isRest ()) {
return $this -> RestResponse -> saveSuccessResponse ( 'Servers' , 'serverSettingsEdit' , false , $this -> response -> type (), 'Field updated' );
2018-07-19 11:48:22 +02:00
} else {
2019-02-01 14:44:52 +01:00
return new CakeResponse ( array ( 'body' => json_encode ( array ( 'saved' => true , 'success' => 'Field updated.' )), 'status' => 200 , 'type' => 'json' ));
2018-07-19 11:48:22 +02:00
}
2019-02-01 14:44:52 +01:00
} else {
2020-12-04 09:23:12 +01:00
if ( $this -> _isRest ()) {
2019-02-01 14:44:52 +01:00
return $this -> RestResponse -> saveFailResponse ( 'Servers' , 'serverSettingsEdit' , false , $result , $this -> response -> type ());
2018-07-19 11:48:22 +02:00
} else {
2019-02-01 14:44:52 +01:00
return new CakeResponse ( array ( 'body' => json_encode ( array ( 'saved' => false , 'errors' => $result )), 'status' => 200 , 'type' => 'json' ));
2018-07-19 11:48:22 +02:00
}
}
}
}
2020-09-22 09:15:03 +02:00
public function killAllWorkers ( $force = false )
{
2020-09-23 17:28:01 +02:00
if ( ! $this -> request -> is ( 'post' )) {
2020-09-22 09:15:03 +02:00
throw new MethodNotAllowedException ();
}
$this -> Server -> killAllWorkers ( $this -> Auth -> user (), $force );
if ( $this -> _isRest ()) {
return $this -> RestResponse -> saveSuccessResponse ( 'Server' , 'killAllWorkers' , false , $this -> response -> type (), __ ( 'Killing workers.' ));
}
$this -> redirect ( array ( 'controller' => 'servers' , 'action' => 'serverSettings' , 'workers' ));
}
2018-07-19 11:48:22 +02:00
public function restartWorkers ()
{
if ( ! $this -> _isSiteAdmin () || ! $this -> request -> is ( 'post' )) {
throw new MethodNotAllowedException ();
}
$this -> Server -> restartWorkers ( $this -> Auth -> user ());
2019-08-08 11:19:21 +02:00
if ( $this -> _isRest ()) {
return $this -> RestResponse -> saveSuccessResponse ( 'Server' , 'restartWorkers' , false , $this -> response -> type (), __ ( 'Restarting workers.' ));
}
2018-07-19 11:48:22 +02:00
$this -> redirect ( array ( 'controller' => 'servers' , 'action' => 'serverSettings' , 'workers' ));
}
2020-03-06 14:56:35 +01:00
public function restartDeadWorkers ()
{
if ( ! $this -> _isSiteAdmin () || ! $this -> request -> is ( 'post' )) {
throw new MethodNotAllowedException ();
}
$this -> Server -> restartDeadWorkers ( $this -> Auth -> user ());
if ( $this -> _isRest ()) {
return $this -> RestResponse -> saveSuccessResponse ( 'Server' , 'restartDeadWorkers' , false , $this -> response -> type (), __ ( 'Restarting workers.' ));
}
$this -> redirect ( array ( 'controller' => 'servers' , 'action' => 'serverSettings' , 'workers' ));
}
2018-07-19 11:48:22 +02:00
private function __manageFiles ()
{
if ( ! $this -> _isSiteAdmin ()) {
throw new MethodNotAllowedException ();
}
$files = $this -> Server -> grabFiles ();
return $files ;
}
public function deleteFile ( $type , $filename )
{
if ( ! $this -> _isSiteAdmin ()) {
throw new MethodNotAllowedException ();
}
if ( $this -> request -> is ( 'post' )) {
$validItems = $this -> Server -> getFileRules ();
App :: uses ( 'File' , 'Utility' );
$existingFile = new File ( $validItems [ $type ][ 'path' ] . DS . $filename );
if ( ! $existingFile -> exists ()) {
$this -> Flash -> error ( __ ( 'File not found.' , true ), 'default' , array (), 'error' );
$this -> redirect ( array ( 'controller' => 'servers' , 'action' => 'serverSettings' , 'files' ));
}
if ( $existingFile -> delete ()) {
$this -> Flash -> success ( 'File deleted.' );
} else {
$this -> Flash -> error ( __ ( 'File could not be deleted.' , true ), 'default' , array (), 'error' );
}
$this -> redirect ( array ( 'controller' => 'servers' , 'action' => 'serverSettings' , 'files' ));
} else {
throw new MethodNotAllowedException ( 'This action expects a POST request.' );
}
}
public function uploadFile ( $type )
{
if ( ! $this -> _isSiteAdmin () || ! $this -> request -> is ( 'post' )) {
throw new MethodNotAllowedException ();
}
$validItems = $this -> Server -> getFileRules ();
// Check if there were problems with the file upload
// only keep the last part of the filename, this should prevent directory attacks
$filename = basename ( $this -> request -> data [ 'Server' ][ 'file' ][ 'name' ]);
if ( ! preg_match ( " / " . $validItems [ $type ][ 'regex' ] . " / " , $filename )) {
$this -> Flash -> error ( $validItems [ $type ][ 'regex_error' ], 'default' , array (), 'error' );
$this -> redirect ( array ( 'controller' => 'servers' , 'action' => 'serverSettings' , 'files' ));
}
if ( empty ( $this -> request -> data [ 'Server' ][ 'file' ][ 'tmp_name' ]) || ! is_uploaded_file ( $this -> request -> data [ 'Server' ][ 'file' ][ 'tmp_name' ])) {
$this -> Flash -> error ( __ ( 'Upload failed.' , true ), 'default' , array (), 'error' );
$this -> redirect ( array ( 'controller' => 'servers' , 'action' => 'serverSettings' , 'files' ));
}
// check if the file already exists
App :: uses ( 'File' , 'Utility' );
$existingFile = new File ( $validItems [ $type ][ 'path' ] . DS . $filename );
if ( $existingFile -> exists ()) {
$this -> Flash -> info ( __ ( 'File already exists. If you would like to replace it, remove the old one first.' , true ), 'default' , array (), 'error' );
$this -> redirect ( array ( 'controller' => 'servers' , 'action' => 'serverSettings' , 'files' ));
}
$result = move_uploaded_file ( $this -> request -> data [ 'Server' ][ 'file' ][ 'tmp_name' ], $validItems [ $type ][ 'path' ] . DS . $filename );
if ( $result ) {
$this -> Flash -> success ( 'File uploaded.' );
} else {
$this -> Flash -> error ( __ ( 'Upload failed.' , true ), 'default' , array (), 'error' );
}
$this -> redirect ( array ( 'controller' => 'servers' , 'action' => 'serverSettings' , 'files' ));
}
public function fetchServersForSG ( $idList = '{}' )
{
$id_exclusion_list = json_decode ( $idList , true );
$temp = $this -> Server -> find ( 'all' , array (
'conditions' => array (
'id !=' => $id_exclusion_list ,
),
'recursive' => - 1 ,
'fields' => array ( 'id' , 'name' , 'url' )
));
$servers = array ();
foreach ( $temp as $server ) {
$servers [] = array ( 'id' => $server [ 'Server' ][ 'id' ], 'name' => $server [ 'Server' ][ 'name' ], 'url' => $server [ 'Server' ][ 'url' ]);
}
$this -> layout = false ;
$this -> autoRender = false ;
$this -> set ( 'servers' , $servers );
$this -> render ( 'ajax/fetch_servers_for_sg' );
}
public function postTest ()
{
2021-01-06 23:38:51 +01:00
if ( ! $this -> request -> is ( 'post' )) {
2018-07-19 11:48:22 +02:00
throw new MethodNotAllowedException ( 'Invalid request, expecting a POST request.' );
}
2021-01-06 23:38:51 +01:00
// Fix for PHP-FPM / Nginx / etc
// Fix via https://www.popmartian.com/tipsntricks/2015/07/14/howto-use-php-getallheaders-under-fastcgi-php-fpm-nginx-etc/
if ( ! function_exists ( 'getallheaders' )) {
$headers = [];
foreach ( $_SERVER as $name => $value ) {
if ( substr ( $name , 0 , 5 ) === 'HTTP_' ) {
$headers [ strtolower ( str_replace ( '_' , '-' , substr ( $name , 5 )))] = $value ;
}
}
} else {
$headers = getallheaders ();
$headers = array_change_key_case ( $headers , CASE_LOWER );
}
$result = [
'body' => $this -> request -> data ,
'headers' => [
'Content-type' => isset ( $headers [ 'content-type' ]) ? $headers [ 'content-type' ] : 0 ,
'Accept' => isset ( $headers [ 'accept' ]) ? $headers [ 'accept' ] : 0 ,
'Authorization' => isset ( $headers [ 'authorization' ]) ? 'OK' : 0 ,
],
];
return new CakeResponse ( array ( 'body' => json_encode ( $result ), 'type' => 'json' ));
2018-07-19 11:48:22 +02:00
}
2019-11-13 19:09:37 +01:00
public function getRemoteUser ( $id )
{
$this -> Server -> id = $id ;
if ( ! $this -> Server -> exists ()) {
throw new NotFoundException ( __ ( 'Invalid server' ));
}
$user = $this -> Server -> getRemoteUser ( $id );
if ( empty ( $user )) {
throw new NotFoundException ( __ ( 'Invalid user or user not found.' ));
} else {
return $this -> RestResponse -> viewData ( $user );
}
}
2018-07-19 11:48:22 +02:00
public function testConnection ( $id = false )
{
if ( ! $this -> Auth -> user ( 'Role' )[ 'perm_sync' ] && ! $this -> Auth -> user ( 'Role' )[ 'perm_site_admin' ]) {
throw new MethodNotAllowedException ( 'You don\'t have permission to do that.' );
}
2020-10-16 17:34:55 +02:00
2020-11-12 08:21:24 +01:00
$server = $this -> Server -> find ( 'first' , [ 'conditions' => [ 'Server.id' => $id ]]);
2020-10-16 17:34:55 +02:00
if ( ! $server ) {
2018-07-19 11:48:22 +02:00
throw new NotFoundException ( __ ( 'Invalid server' ));
}
2020-10-16 17:34:55 +02:00
$result = $this -> Server -> runConnectionTest ( $server );
2018-07-19 11:48:22 +02:00
if ( $result [ 'status' ] == 1 ) {
2020-10-16 17:34:55 +02:00
if ( isset ( $result [ 'info' ][ 'version' ]) && preg_match ( '/^[0-9]+\.+[0-9]+\.[0-9]+$/' , $result [ 'info' ][ 'version' ])) {
2018-08-03 19:20:00 +02:00
$perm_sync = false ;
2020-10-16 17:34:55 +02:00
if ( isset ( $result [ 'info' ][ 'perm_sync' ])) {
$perm_sync = $result [ 'info' ][ 'perm_sync' ];
2018-08-03 19:20:00 +02:00
}
2019-11-26 19:40:49 +01:00
$perm_sighting = false ;
2020-10-16 17:34:55 +02:00
if ( isset ( $result [ 'info' ][ 'perm_sighting' ])) {
$perm_sighting = $result [ 'info' ][ 'perm_sighting' ];
2019-11-26 19:40:49 +01:00
}
2018-07-19 11:48:22 +02:00
App :: uses ( 'Folder' , 'Utility' );
$file = new File ( ROOT . DS . 'VERSION.json' , true );
$local_version = json_decode ( $file -> read (), true );
$file -> close ();
2020-10-16 17:34:55 +02:00
$version = explode ( '.' , $result [ 'info' ][ 'version' ]);
2018-07-19 11:48:22 +02:00
$mismatch = false ;
$newer = false ;
$parts = array ( 'major' , 'minor' , 'hotfix' );
if ( $version [ 0 ] == 2 && $version [ 1 ] == 4 && $version [ 2 ] > 68 ) {
2020-10-16 17:34:55 +02:00
$post = $this -> Server -> runPOSTTest ( $server );
2018-07-19 11:48:22 +02:00
}
foreach ( $parts as $k => $v ) {
if ( ! $mismatch ) {
if ( $version [ $k ] > $local_version [ $v ]) {
$mismatch = $v ;
$newer = 'remote' ;
} elseif ( $version [ $k ] < $local_version [ $v ]) {
$mismatch = $v ;
$newer = 'local' ;
}
}
}
2019-07-12 16:03:08 +02:00
if ( ! $mismatch && $version [ 2 ] < 111 ) {
$mismatch = 'proposal' ;
}
2019-11-26 19:40:49 +01:00
if ( ! $perm_sync && ! $perm_sighting ) {
2018-08-03 19:20:00 +02:00
$result [ 'status' ] = 7 ;
return new CakeResponse ( array ( 'body' => json_encode ( $result ), 'type' => 'json' ));
2018-07-19 11:48:22 +02:00
}
2019-11-26 19:40:49 +01:00
if ( ! $perm_sync && $perm_sighting ) {
$result [ 'status' ] = 8 ;
return new CakeResponse ( array ( 'body' => json_encode ( $result ), 'type' => 'json' ));
}
2018-07-19 11:48:22 +02:00
return new CakeResponse (
array (
'body' => json_encode (
array (
'status' => 1 ,
'local_version' => implode ( '.' , $local_version ),
'version' => implode ( '.' , $version ),
'mismatch' => $mismatch ,
'newer' => $newer ,
2021-01-06 23:38:51 +01:00
'post' => isset ( $post ) ? $post [ 'status' ] : 'too old' ,
'response_encoding' => isset ( $post [ 'content-encoding' ]) ? $post [ 'content-encoding' ] : null ,
2020-10-16 17:34:55 +02:00
'client_certificate' => $result [ 'client_certificate' ],
2018-07-19 11:48:22 +02:00
)
),
'type' => 'json'
)
);
} else {
$result [ 'status' ] = 3 ;
}
}
return new CakeResponse ( array ( 'body' => json_encode ( $result ), 'type' => 'json' ));
}
public function startZeroMQServer ()
{
if ( ! $this -> _isSiteAdmin ()) {
throw new MethodNotAllowedException ();
}
$pubSubTool = $this -> Server -> getPubSubTool ();
$result = $pubSubTool -> restartServer ();
if ( $result === true ) {
return new CakeResponse ( array ( 'body' => json_encode ( array ( 'saved' => true , 'success' => 'ZeroMQ server successfully started.' )), 'status' => 200 , 'type' => 'json' ));
} else {
return new CakeResponse ( array ( 'body' => json_encode ( array ( 'saved' => false , 'errors' => $result )), 'status' => 200 , 'type' => 'json' ));
}
}
public function stopZeroMQServer ()
{
if ( ! $this -> _isSiteAdmin ()) {
throw new MethodNotAllowedException ();
}
$pubSubTool = $this -> Server -> getPubSubTool ();
$result = $pubSubTool -> killService ();
if ( $result === true ) {
return new CakeResponse ( array ( 'body' => json_encode ( array ( 'saved' => true , 'success' => 'ZeroMQ server successfully killed.' )), 'status' => 200 , 'type' => 'json' ));
} else {
return new CakeResponse ( array ( 'body' => json_encode ( array ( 'saved' => false , 'errors' => 'Could not kill the previous instance of the ZeroMQ script.' )), 'status' => 200 , 'type' => 'json' ));
}
}
public function statusZeroMQServer ()
{
if ( ! $this -> _isSiteAdmin ()) {
throw new MethodNotAllowedException ();
}
$pubSubTool = $this -> Server -> getPubSubTool ();
$result = $pubSubTool -> statusCheck ();
if ( ! empty ( $result )) {
$this -> set ( 'events' , $result [ 'publishCount' ]);
2020-05-07 15:56:59 +02:00
$this -> set ( 'messages' , $result [ 'messageCount' ]);
2018-07-19 11:48:22 +02:00
$this -> set ( 'time' , date ( 'Y/m/d H:i:s' , $result [ 'timestamp' ]));
$this -> set ( 'time2' , date ( 'Y/m/d H:i:s' , $result [ 'timestampSettings' ]));
}
$this -> render ( 'ajax/zeromqstatus' );
}
public function purgeSessions ()
{
if ( ! $this -> _isSiteAdmin ()) {
throw new MethodNotAllowedException ();
}
if ( $this -> Server -> updateDatabase ( 'cleanSessionTable' ) == false ) {
$this -> Flash -> error ( 'Could not purge the session table.' );
}
$this -> redirect ( '/servers/serverSettings/diagnostics' );
}
public function clearWorkerQueue ( $worker )
{
if ( ! $this -> _isSiteAdmin () || ! $this -> request -> is ( 'Post' ) || $this -> request -> is ( 'ajax' )) {
throw new MethodNotAllowedException ();
}
$worker_array = array ( 'cache' , 'default' , 'email' , 'prio' );
if ( ! in_array ( $worker , $worker_array )) {
throw new MethodNotAllowedException ( 'Invalid worker' );
}
$redis = Resque :: redis ();
$redis -> del ( 'queue:' . $worker );
$this -> Flash -> success ( 'Queue cleared.' );
$this -> redirect ( $this -> referer ());
}
public function getVersion ()
{
if ( ! $this -> userRole [ 'perm_auth' ]) {
throw new MethodNotAllowedException ( 'This action requires API access.' );
}
$versionArray = $this -> Server -> checkMISPVersion ();
2020-06-16 08:59:45 +02:00
$this -> set ( 'response' , array (
'version' => $versionArray [ 'major' ] . '.' . $versionArray [ 'minor' ] . '.' . $versionArray [ 'hotfix' ],
'perm_sync' => $this -> userRole [ 'perm_sync' ],
'perm_sighting' => $this -> userRole [ 'perm_sighting' ],
'perm_galaxy_editor' => $this -> userRole [ 'perm_galaxy_editor' ],
));
2018-07-19 11:48:22 +02:00
$this -> set ( '_serialize' , 'response' );
}
public function getPyMISPVersion ()
{
$this -> set ( 'response' , array ( 'version' => $this -> pyMispVersion ));
$this -> set ( '_serialize' , 'response' );
}
public function checkout ()
{
$result = $this -> Server -> checkoutMain ();
}
2021-01-20 14:21:31 +01:00
public function update ( $branch = false )
2018-07-19 11:48:22 +02:00
{
if ( $this -> request -> is ( 'post' )) {
2021-01-20 14:21:31 +01:00
$branch = false ;
$filterData = array (
'request' => $this -> request ,
'named_params' => $this -> params [ 'named' ],
'paramArray' => [ 'branch' ],
'ordered_url_params' => @ compact ( $paramArray ),
'additional_delimiters' => PHP_EOL
);
$exception = false ;
$settings = $this -> _harvestParameters ( $filterData , $exception );
2018-07-19 11:48:22 +02:00
$status = $this -> Server -> getCurrentGitStatus ();
2019-09-11 16:52:14 +02:00
$raw = array ();
2020-11-17 11:15:43 +01:00
if ( empty ( $status [ 'branch' ])) { // do not try to update if you are not on branch
$msg = 'Update failed, you are not on branch' ;
$raw [] = $msg ;
$update = $msg ;
} else {
2021-01-20 14:21:31 +01:00
$update = $this -> Server -> update ( $status , $raw , $settings );
2020-11-17 11:15:43 +01:00
}
2019-09-11 16:52:14 +02:00
if ( $this -> _isRest ()) {
return $this -> RestResponse -> viewData ( array ( 'results' => $raw ), $this -> response -> type ());
} else {
2020-11-17 11:15:43 +01:00
return new CakeResponse ( array ( 'body' => $update , 'type' => 'txt' ));
2019-09-11 16:52:14 +02:00
}
2018-07-19 11:48:22 +02:00
} else {
$branch = $this -> Server -> getCurrentBranch ();
$this -> set ( 'branch' , $branch );
$this -> render ( 'ajax/update' );
}
}
2019-04-26 09:45:03 +02:00
public function ondemandAction ()
{
if ( ! $this -> _isSiteAdmin ()) {
throw new MethodNotAllowedException ( 'You are not authorised to do that.' );
}
$this -> AdminSetting = ClassRegistry :: init ( 'AdminSetting' );
$actions = $this -> Server -> actions_description ;
$default_fields = array (
'title' => '' ,
'description' => '' ,
'liveOff' => false ,
'recommendBackup' => false ,
'exitOnError' => false ,
'requirements' => '' ,
2020-08-17 17:28:04 +02:00
'url' => $this -> baseurl . '/'
2019-04-26 09:45:03 +02:00
);
foreach ( $actions as $id => $action ) {
foreach ( $default_fields as $field => $value ) {
if ( ! isset ( $action [ $field ])) {
$actions [ $id ][ $field ] = $value ;
}
}
$done = $this -> AdminSetting -> getSetting ( $id );
2019-04-29 11:09:04 +02:00
$actions [ $id ][ 'done' ] = ( $done == '1' );
2019-04-26 09:45:03 +02:00
}
$this -> set ( 'actions' , $actions );
$this -> set ( 'updateLocked' , $this -> Server -> isUpdateLocked ());
}
2019-10-03 13:50:55 +02:00
public function updateProgress ( $ajaxHtml = false )
2019-04-26 09:45:03 +02:00
{
if ( ! $this -> _isSiteAdmin ()) {
throw new MethodNotAllowedException ( 'You are not authorised to do that.' );
}
2019-10-29 09:57:25 +01:00
2019-10-03 13:50:55 +02:00
$this -> AdminSetting = ClassRegistry :: init ( 'AdminSetting' );
2019-10-29 09:57:25 +01:00
$dbVersion = $this -> AdminSetting -> getSetting ( 'db_version' );
$updateProgress = $this -> Server -> getUpdateProgress ();
$updateProgress [ 'db_version' ] = $dbVersion ;
$maxUpdateNumber = max ( array_keys ( $this -> Server -> db_changes ));
$updateProgress [ 'complete_update_remaining' ] = max ( $maxUpdateNumber - $dbVersion , 0 );
$updateProgress [ 'update_locked' ] = $this -> Server -> isUpdateLocked ();
$updateProgress [ 'lock_remaining_time' ] = $this -> Server -> getLockRemainingTime ();
$updateProgress [ 'update_fail_number_reached' ] = $this -> Server -> UpdateFailNumberReached ();
$currentIndex = $updateProgress [ 'current' ];
$currentCommand = ! isset ( $updateProgress [ 'commands' ][ $currentIndex ]) ? '' : $updateProgress [ 'commands' ][ $currentIndex ];
$lookupString = preg_replace ( '/\s{2,}/' , '' , substr ( $currentCommand , 0 , - 1 ));
$sqlInfo = $this -> Server -> query ( " SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST; " );
if ( empty ( $sqlInfo )) {
$updateProgress [ 'process_list' ] = array ();
2019-04-26 09:45:03 +02:00
} else {
2019-10-04 13:02:59 +02:00
// retrieve current update process
2019-10-29 09:57:25 +01:00
foreach ( $sqlInfo as $row ) {
if ( preg_replace ( '/\s{2,}/' , '' , $row [ 'PROCESSLIST' ][ 'INFO' ]) == $lookupString ) {
$sqlInfo = $row [ 'PROCESSLIST' ];
2019-04-26 09:45:03 +02:00
break ;
}
}
2019-10-29 09:57:25 +01:00
$updateProgress [ 'process_list' ] = array ();
$updateProgress [ 'process_list' ][ 'STATE' ] = isset ( $sqlInfo [ 'STATE' ]) ? $sqlInfo [ 'STATE' ] : '' ;
$updateProgress [ 'process_list' ][ 'PROGRESS' ] = isset ( $sqlInfo [ 'PROGRESS' ]) ? $sqlInfo [ 'PROGRESS' ] : 0 ;
$updateProgress [ 'process_list' ][ 'STAGE' ] = isset ( $sqlInfo [ 'STAGE' ]) ? $sqlInfo [ 'STAGE' ] : 0 ;
$updateProgress [ 'process_list' ][ 'MAX_STAGE' ] = isset ( $sqlInfo [ 'MAX_STAGE' ]) ? $sqlInfo [ 'MAX_STAGE' ] : 0 ;
2019-04-26 09:45:03 +02:00
}
2019-10-03 13:50:55 +02:00
$this -> set ( 'ajaxHtml' , $ajaxHtml );
if ( $this -> request -> is ( 'ajax' ) && $ajaxHtml ) {
2019-10-29 09:57:25 +01:00
$this -> set ( 'updateProgress' , $updateProgress );
2019-10-03 13:50:55 +02:00
$this -> layout = false ;
2019-10-14 10:49:41 +02:00
} elseif ( $this -> request -> is ( 'ajax' ) || $this -> _isRest ()) {
2019-10-29 09:57:25 +01:00
return $this -> RestResponse -> viewData ( h ( $updateProgress ), $this -> response -> type ());
2019-04-26 09:45:03 +02:00
} else {
2019-10-29 09:57:25 +01:00
$this -> set ( 'updateProgress' , $updateProgress );
2019-04-26 09:45:03 +02:00
}
}
2019-04-05 10:46:49 +02:00
public function getSubmoduleQuickUpdateForm ( $submodule_path = false ) {
$this -> set ( 'submodule' , base64_decode ( $submodule_path ));
$this -> render ( 'ajax/submodule_quick_update_form' );
}
2019-04-02 11:29:10 +02:00
public function updateSubmodule ()
{
if ( ! $this -> _isSiteAdmin ()) {
throw new MethodNotAllowedException ();
}
if ( $this -> request -> is ( 'post' )) {
$request = $this -> request -> data ;
$submodule = $request [ 'Server' ][ 'submodule' ];
2019-04-05 14:28:19 +02:00
$res = $this -> Server -> updateSubmodule ( $this -> Auth -> user (), $submodule );
2019-04-02 11:29:10 +02:00
return new CakeResponse ( array ( 'body' => json_encode ( $res ), 'type' => 'json' ));
} else {
throw new MethodNotAllowedException ();
}
}
2018-07-19 11:48:22 +02:00
public function getInstanceUUID ()
{
return $this -> RestResponse -> viewData ( array ( 'uuid' => Configure :: read ( 'MISP.uuid' )), $this -> response -> type ());
}
2018-08-08 11:29:38 +02:00
2018-08-20 10:50:09 +02:00
public function rest ()
{
2018-12-31 08:02:00 +01:00
$allValidApis = $this -> RestResponse -> getAllApis ( $this -> Auth -> user ());
$allValidApisFieldsContraint = $this -> RestResponse -> getAllApisFieldsConstraint ( $this -> Auth -> user ());
2018-08-08 11:29:38 +02:00
if ( $this -> request -> is ( 'post' )) {
$request = $this -> request -> data ;
if ( ! empty ( $request [ 'Server' ])) {
$request = $this -> request -> data [ 'Server' ];
}
2018-11-23 14:11:33 +01:00
$curl = '' ;
$python = '' ;
2020-11-07 10:59:02 +01:00
try {
$result = $this -> __doRestQuery ( $request , $curl , $python );
$this -> set ( 'curl' , $curl );
$this -> set ( 'python' , $python );
if ( ! $result ) {
$this -> Flash -> error ( 'Something went wrong. Make sure you set the http method, body (when sending POST requests) and URL correctly.' );
} else {
$this -> set ( 'data' , $result );
}
} catch ( Exception $e ) {
$this -> Flash -> error ( __ ( 'Something went wrong. %s' , $e -> getMessage ()));
2018-08-08 11:29:38 +02:00
}
}
2020-11-11 10:47:10 +01:00
$header = sprintf (
" Authorization: %s \n Accept: application/json \n Content-type: application/json " ,
empty ( Configure :: read ( 'Security.advanced_authkeys' )) ? $this -> Auth -> user ( 'authkey' ) : __ ( 'YOUR_API_KEY' )
);
2018-08-08 11:29:38 +02:00
$this -> set ( 'header' , $header );
2018-11-23 14:11:33 +01:00
$this -> set ( 'allValidApis' , $allValidApis );
2018-11-09 08:58:58 +01:00
// formating for optgroup
$allValidApisFormated = array ();
2018-12-17 16:36:27 +01:00
foreach ( $allValidApis as $endpoint_url => $endpoint_data ) {
2018-11-09 08:58:58 +01:00
$allValidApisFormated [ $endpoint_data [ 'controller' ]][] = array ( 'url' => $endpoint_url , 'action' => $endpoint_data [ 'action' ]);
2018-12-17 16:36:27 +01:00
}
2018-11-09 08:58:58 +01:00
$this -> set ( 'allValidApisFormated' , $allValidApisFormated );
2018-12-17 16:36:27 +01:00
$this -> set ( 'allValidApisFieldsContraint' , $allValidApisFieldsContraint );
2018-08-08 11:29:38 +02:00
}
2020-11-07 10:59:02 +01:00
/**
* @ param array $request
* @ param string $curl
* @ param string $python
* @ return array | false
*/
private function __doRestQuery ( array $request , & $curl = false , & $python = false )
2018-08-20 10:50:09 +02:00
{
2018-08-08 11:29:38 +02:00
App :: uses ( 'SyncTool' , 'Tools' );
2018-08-31 13:19:02 +02:00
$params = array ();
2019-03-19 10:55:27 +01:00
$this -> loadModel ( 'RestClientHistory' );
$this -> RestClientHistory -> create ();
$date = new DateTime ();
2020-11-13 12:49:14 +01:00
$logHeaders = $request [ 'header' ];
2020-11-11 10:47:10 +01:00
if ( ! empty ( Configure :: read ( 'Security.advanced_authkeys' ))) {
2020-11-13 12:49:14 +01:00
$logHeaders = explode ( " \n " , $request [ 'header' ]);
foreach ( $logHeaders as $k => $header ) {
2020-11-11 10:47:10 +01:00
if ( strpos ( $header , 'Authorization' ) !== false ) {
2020-11-13 12:49:14 +01:00
$logHeaders [ $k ] = 'Authorization: ' . __ ( 'YOUR_API_KEY' );
2020-11-11 10:47:10 +01:00
}
}
2020-11-13 12:49:14 +01:00
$logHeaders = implode ( " \n " , $logHeaders );
2020-11-11 10:47:10 +01:00
}
2019-03-19 10:55:27 +01:00
$rest_history_item = array (
'org_id' => $this -> Auth -> user ( 'org_id' ),
'user_id' => $this -> Auth -> user ( 'id' ),
2020-11-13 12:49:14 +01:00
'headers' => $logHeaders ,
2019-03-19 10:55:27 +01:00
'body' => empty ( $request [ 'body' ]) ? '' : $request [ 'body' ],
'url' => $request [ 'url' ],
'http_method' => $request [ 'method' ],
2020-10-31 00:22:27 +01:00
'use_full_path' => empty ( $request [ 'use_full_path' ]) ? false : $request [ 'use_full_path' ],
2019-03-19 10:55:27 +01:00
'show_result' => $request [ 'show_result' ],
'skip_ssl' => $request [ 'skip_ssl_validation' ],
'bookmark' => $request [ 'bookmark' ],
'bookmark_name' => $request [ 'name' ],
'timestamp' => $date -> getTimestamp ()
);
2018-08-08 11:29:38 +02:00
if ( ! empty ( $request [ 'url' ])) {
2020-10-31 00:22:27 +01:00
if ( empty ( $request [ 'use_full_path' ]) || empty ( Configure :: read ( 'Security.rest_client_enable_arbitrary_urls' ))) {
2018-11-23 14:11:33 +01:00
$path = preg_replace ( '#^(://|[^/?])+#' , '' , $request [ 'url' ]);
2020-10-31 00:22:27 +01:00
$url = empty ( Configure :: read ( 'Security.rest_client_baseurl' )) ? ( Configure :: read ( 'MISP.baseurl' ) . $path ) : ( Configure :: read ( 'Security.rest_client_baseurl' ) . $path );
2018-11-23 14:11:33 +01:00
unset ( $request [ 'url' ]);
} else {
$url = $request [ 'url' ];
}
2018-08-08 11:29:38 +02:00
} else {
2020-11-07 10:59:02 +01:00
throw new InvalidArgumentException ( 'URL not set.' );
2018-08-08 11:29:38 +02:00
}
2018-11-23 14:11:33 +01:00
if ( ! empty ( $request [ 'skip_ssl_validation' ])) {
$params [ 'ssl_verify_peer' ] = false ;
2019-03-14 18:14:01 +01:00
$params [ 'ssl_verify_host' ] = false ;
2019-07-31 14:10:19 +02:00
$params [ 'ssl_verify_peer_name' ] = false ;
2019-03-14 18:14:01 +01:00
$params [ 'ssl_allow_self_signed' ] = true ;
2018-11-23 14:11:33 +01:00
}
$params [ 'timeout' ] = 300 ;
2018-08-08 11:29:38 +02:00
App :: uses ( 'HttpSocket' , 'Network/Http' );
2019-07-31 14:03:22 +02:00
$HttpSocket = new HttpSocket ( $params );
2018-08-08 11:29:38 +02:00
$view_data = array ();
$temp_headers = explode ( " \n " , $request [ 'header' ]);
$request [ 'header' ] = array (
'Authorization' => $this -> Auth -> user ( 'authkey' ),
'Accept' => 'application/json' ,
'Content-Type' => 'application/json'
);
foreach ( $temp_headers as $header ) {
$header = explode ( ':' , $header );
$header [ 0 ] = trim ( $header [ 0 ]);
$header [ 1 ] = trim ( $header [ 1 ]);
$request [ 'header' ][ $header [ 0 ]] = $header [ 1 ];
}
$start = microtime ( true );
if (
! empty ( $request [ 'method' ]) &&
$request [ 'method' ] === 'GET'
) {
2018-11-23 14:11:33 +01:00
if ( $curl !== false ) {
$curl = $this -> __generateCurlQuery ( 'get' , $request , $url );
}
if ( $python !== false ) {
$python = $this -> __generatePythonScript ( $request , $url );
}
2019-07-31 14:03:22 +02:00
$response = $HttpSocket -> get ( $url , false , array ( 'header' => $request [ 'header' ]));
2018-08-20 10:50:09 +02:00
} elseif (
2018-08-08 11:29:38 +02:00
! empty ( $request [ 'method' ]) &&
$request [ 'method' ] === 'POST' &&
! empty ( $request [ 'body' ])
) {
2018-11-23 14:11:33 +01:00
if ( $curl !== false ) {
$curl = $this -> __generateCurlQuery ( 'post' , $request , $url );
}
if ( $python !== false ) {
$python = $this -> __generatePythonScript ( $request , $url );
}
2019-07-31 14:03:22 +02:00
$response = $HttpSocket -> post ( $url , $request [ 'body' ], array ( 'header' => $request [ 'header' ]));
2019-09-20 11:53:28 +02:00
} elseif (
! empty ( $request [ 'method' ]) &&
$request [ 'method' ] === 'DELETE'
) {
if ( $curl !== false ) {
$curl = $this -> __generateCurlQuery ( 'delete' , $request , $url );
}
if ( $python !== false ) {
$python = $this -> __generatePythonScript ( $request , $url );
}
$response = $HttpSocket -> delete ( $url , false , array ( 'header' => $request [ 'header' ]));
2018-08-08 11:29:38 +02:00
} else {
return false ;
}
$view_data [ 'duration' ] = microtime ( true ) - $start ;
2020-11-07 10:59:02 +01:00
$view_data [ 'duration' ] = round ( $view_data [ 'duration' ] * 1000 , 2 ) . ' ms' ;
2020-10-31 00:22:27 +01:00
$view_data [ 'url' ] = $url ;
2018-08-08 11:29:38 +02:00
$view_data [ 'code' ] = $response -> code ;
$view_data [ 'headers' ] = $response -> headers ;
if ( ! empty ( $request [ 'show_result' ])) {
$view_data [ 'data' ] = $response -> body ;
} else {
if ( $response -> isOk ()) {
$view_data [ 'data' ] = 'Success.' ;
} else {
$view_data [ 'data' ] = 'Something went wrong.' ;
}
}
2019-03-19 10:55:27 +01:00
$rest_history_item [ 'outcome' ] = $response -> code ;
$this -> RestClientHistory -> save ( $rest_history_item );
$this -> RestClientHistory -> cleanup ( $this -> Auth -> user ( 'id' ));
2018-08-08 11:29:38 +02:00
return $view_data ;
}
2018-09-01 23:53:03 +02:00
2018-11-23 14:11:33 +01:00
private function __generatePythonScript ( $request , $url )
{
$slashCounter = 0 ;
$baseurl = '' ;
$relative = '' ;
$verifyCert = ( $url [ 4 ] === 's' ) ? 'True' : 'False' ;
for ( $i = 0 ; $i < strlen ( $url ); $i ++ ) {
//foreach ($url as $url[$i]) {
if ( $url [ $i ] === '/' ) {
$slashCounter += 1 ;
if ( $slashCounter == 3 ) {
continue ;
}
}
if ( $slashCounter < 3 ) {
$baseurl .= $url [ $i ];
} else {
$relative .= $url [ $i ];
}
}
$python_script =
sprintf (
2018-10-09 15:56:09 +02:00
' misp_url = \ ' % s\ '
misp_key = \ ' % s\ '
misp_verifycert = % s
relative_path = \ ' % s\ '
body = % s
2019-11-15 02:13:49 +01:00
from pymisp import ExpandedPyMISP
2018-10-09 15:56:09 +02:00
2019-11-15 02:13:49 +01:00
misp = ExpandedPyMISP ( misp_url , misp_key , misp_verifycert )
2018-10-09 15:56:09 +02:00
misp . direct_call ( relative_path , body )
' ,
2018-11-23 14:11:33 +01:00
$baseurl ,
$request [ 'header' ][ 'Authorization' ],
$verifyCert ,
$relative ,
2019-11-15 01:50:50 +01:00
( empty ( $request [ 'body' ]) ? 'None' : $request [ 'body' ])
2018-11-23 14:11:33 +01:00
);
return $python_script ;
}
2018-10-21 22:47:22 +02:00
2018-11-23 14:11:33 +01:00
private function __generateCurlQuery ( $type , $request , $url )
{
if ( $type === 'get' ) {
$curl = sprintf (
'curl \%s -H "Authorization: %s" \%s -H "Accept: %s" \%s -H "Content-type: %s" \%s %s' ,
PHP_EOL ,
$request [ 'header' ][ 'Authorization' ],
PHP_EOL ,
$request [ 'header' ][ 'Accept' ],
PHP_EOL ,
$request [ 'header' ][ 'Content-Type' ],
PHP_EOL ,
$url
);
} else {
$curl = sprintf (
'curl \%s -d \'%s\' \%s -H "Authorization: %s" \%s -H "Accept: %s" \%s -H "Content-type: %s" \%s -X POST %s' ,
PHP_EOL ,
2020-11-07 11:06:56 +01:00
json_encode ( json_decode ( $request [ 'body' ])),
2018-11-23 14:11:33 +01:00
PHP_EOL ,
$request [ 'header' ][ 'Authorization' ],
PHP_EOL ,
$request [ 'header' ][ 'Accept' ],
PHP_EOL ,
$request [ 'header' ][ 'Content-Type' ],
PHP_EOL ,
$url
);
}
return $curl ;
}
2018-10-21 22:47:22 +02:00
2018-11-23 14:11:33 +01:00
public function getApiInfo ()
{
$relative_path = $this -> request -> data [ 'url' ];
$result = $this -> RestResponse -> getApiInfo ( $relative_path );
if ( $this -> _isRest ()) {
2020-11-07 11:06:56 +01:00
if ( ! empty ( $result )) {
$result [ 'api_info' ] = $result ;
}
return $this -> RestResponse -> viewData ( $result , $this -> response -> type ());
2018-11-23 14:11:33 +01:00
} else {
if ( empty ( $result )) {
return $this -> RestResponse -> viewData ( ' ' , $this -> response -> type ());
}
$this -> layout = false ;
$this -> autoRender = false ;
$this -> set ( 'api_info' , $result );
$this -> render ( 'ajax/get_api_info' );
}
}
2018-10-21 22:47:22 +02:00
2019-01-18 09:06:23 +01:00
public function cache ( $id = 'all' )
{
if ( Configure :: read ( 'MISP.background_jobs' )) {
$this -> loadModel ( 'Job' );
$this -> Job -> create ();
$data = array (
'worker' => 'default' ,
'job_type' => 'cache_servers' ,
'job_input' => intval ( $id ) ? $id : 'all' ,
'status' => 0 ,
'retries' => 0 ,
'org' => $this -> Auth -> user ( 'Organisation' )[ 'name' ],
'message' => __ ( 'Starting server caching.' ),
);
$this -> Job -> save ( $data );
$jobId = $this -> Job -> id ;
$process_id = CakeResque :: enqueue (
'default' ,
'ServerShell' ,
array ( 'cacheServer' , $this -> Auth -> user ( 'id' ), $id , $jobId ),
true
);
$this -> Job -> saveField ( 'process_id' , $process_id );
$message = 'Server caching job initiated.' ;
} else {
$result = $this -> Server -> cacheServerInitiator ( $this -> Auth -> user (), $id );
if ( ! $result ) {
$this -> Flash -> error ( __ ( 'Caching the servers has failed.' ));
$this -> redirect ( array ( 'action' => 'index' ));
}
$message = __ ( 'Caching the servers has successfully completed.' );
}
if ( $this -> _isRest ()) {
return $this -> RestResponse -> saveSuccessResponse ( 'Server' , 'cache' , false , $this -> response -> type (), $message );
} else {
2019-01-18 16:15:22 +01:00
$this -> Flash -> info ( $message );
2019-01-18 09:06:23 +01:00
$this -> redirect ( array ( 'action' => 'index' ));
}
}
2019-04-10 10:09:25 +02:00
public function updateJSON ()
{
$results = $this -> Server -> updateJSON ();
return $this -> RestResponse -> viewData ( $results , $this -> response -> type ());
}
2019-05-30 14:42:29 +02:00
public function createSync ()
{
if ( $this -> _isSiteAdmin ()) {
throw new MethodNotAllowedException ( 'Site admin accounts cannot be used to create server sync configurations.' );
}
$baseurl = Configure :: read ( 'MISP.external_baseurl' );
if ( empty ( $baseurl )) {
$baseurl = Configure :: read ( 'MISP.baseurl' );
if ( empty ( $baseurl )) {
$baseurl = Router :: url ( '/' , true );
}
}
2019-08-12 11:51:37 +02:00
$host_org_id = Configure :: read ( 'MISP.host_org_id' );
if ( empty ( $host_org_id )) {
throw new MethodNotAllowedException ( __ ( 'Cannot create sync config - no host org ID configured for the instance.' ));
}
$this -> loadModel ( 'Organisation' );
$host_org = $this -> Organisation -> find ( 'first' , array (
'conditions' => array ( 'Organisation.id' => $host_org_id ),
'recursive' => - 1 ,
'fields' => array ( 'name' , 'uuid' )
));
if ( empty ( $host_org )) {
throw new MethodNotAllowedException ( __ ( 'Configured host org not found. Please make sure that the setting is current on the instance.' ));
}
2019-05-30 14:42:29 +02:00
$server = array (
'Server' => array (
'url' => $baseurl ,
'uuid' => Configure :: read ( 'MISP.uuid' ),
'authkey' => $this -> Auth -> user ( 'authkey' ),
'Organisation' => array (
2019-08-12 11:51:37 +02:00
'name' => $host_org [ 'Organisation' ][ 'name' ],
'uuid' => $host_org [ 'Organisation' ][ 'uuid' ],
2019-05-30 14:42:29 +02:00
)
)
);
if ( $this -> _isRest ()) {
return $this -> RestResponse -> viewData ( $server , $this -> response -> type ());
} else {
$this -> set ( 'server' , $server );
}
}
public function import ()
{
if ( $this -> request -> is ( 'post' )) {
$server = $this -> request -> data ;
if ( isset ( $server [ 'Server' ])) {
$server = $server [ 'Server' ];
}
if ( isset ( $server [ 'json' ])) {
$server = json_decode ( $server [ 'json' ], true )[ 'Server' ];
}
$this -> loadModel ( 'Organisation' );
$org_id = $this -> Organisation -> captureOrg ( $server [ 'Organisation' ], $this -> Auth -> user ());
2019-05-30 14:50:51 +02:00
$toSave = array (
2019-05-30 14:42:29 +02:00
'push' => 0 ,
'pull' => 0 ,
'caching_enabled' => 0 ,
'json' => '[]' ,
'push_rules' => '[]' ,
'pull_rules' => '[]' ,
'self_signed' => 0 ,
'org_id' => $this -> Auth -> user ( 'org_id' ),
2019-05-30 15:06:51 +02:00
'remote_org_id' => $org_id ,
2019-05-30 14:50:51 +02:00
'name' => empty ( $server [ 'name' ]) ? $server [ 'url' ] : $server [ 'name' ],
'url' => $server [ 'url' ],
'uuid' => $server [ 'uuid' ],
'authkey' => $server [ 'authkey' ]
2019-05-30 14:42:29 +02:00
);
$this -> Server -> create ();
2019-05-30 14:50:51 +02:00
$result = $this -> Server -> save ( $toSave );
2019-05-30 14:42:29 +02:00
if ( $result ) {
if ( $this -> _isRest ()) {
$server = $this -> Server -> find ( 'first' , array (
'conditions' => array ( 'Server.id' => $this -> Server -> id ),
'recursive' => - 1
));
return $this -> RestResponse -> viewData ( $server , $this -> response -> type ());
} else {
$this -> Flash -> success ( __ ( 'The server has been saved' ));
2019-05-30 14:46:33 +02:00
$this -> redirect ( array ( 'action' => 'index' , $this -> Server -> id ));
2019-05-30 14:42:29 +02:00
}
} else {
if ( $this -> _isRest ()) {
return $this -> RestResponse -> saveFailResponse ( 'Servers' , 'addFromJson' , false , $this -> Server -> validationErrors , $this -> response -> type ());
} else {
$this -> Flash -> error ( __ ( 'Could not save the server. Error: %s' , json_encode ( $this -> Server -> validationErrors , true )));
$this -> redirect ( array ( 'action' => 'index' ));
}
}
}
}
2019-09-09 13:00:21 +02:00
public function resetRemoteAuthKey ( $id )
{
if ( ! $this -> request -> is ( 'post' )) {
throw new MethodNotAllowedException ( __ ( 'This endpoint expects POST requests.' ));
}
$result = $this -> Server -> resetRemoteAuthkey ( $id );
if ( $result !== true ) {
if ( ! $this -> _isRest ()) {
$this -> Flash -> error ( $result );
$this -> redirect ( array ( 'action' => 'index' ));
} else {
return $this -> RestResponse -> saveFailResponse ( 'Servers' , 'resetRemoteAuthKey' , $id , $message , $this -> response -> type ());
}
} else {
$message = __ ( 'API key updated.' );
if ( ! $this -> _isRest ()) {
$this -> Flash -> success ( $message );
$this -> redirect ( array ( 'action' => 'index' ));
} else {
return $this -> RestResponse -> saveSuccessResponse ( 'Servers' , 'resetRemoteAuthKey' , $message , $this -> response -> type ());
}
}
}
2019-09-13 11:49:12 +02:00
2019-09-13 15:50:06 +02:00
public function changePriority ( $id = false , $direction = 'down' ) {
2019-09-13 11:49:12 +02:00
$this -> Server -> id = $id ;
if ( ! $this -> Server -> exists ()) {
throw new InvalidArgumentException ( __ ( 'ID has to be a valid server connection' ));
}
if ( $direction !== 'up' && $direction !== 'down' ) {
throw new InvalidArgumentException ( __ ( 'Invalid direction. Valid options: ' , 'up' , 'down' ));
}
$success = $this -> Server -> reprioritise ( $id , $direction );
if ( $success ) {
$message = __ ( 'Priority changed.' );
return $this -> RestResponse -> saveSuccessResponse ( 'Servers' , 'changePriority' , $message , $this -> response -> type ());
} else {
$message = __ ( 'Priority could not be changed.' );
2019-09-13 15:50:06 +02:00
return $this -> RestResponse -> saveFailResponse ( 'Servers' , 'changePriority' , $id , $message , $this -> response -> type ());
2019-09-13 11:49:12 +02:00
}
}
2019-10-10 12:02:23 +02:00
public function releaseUpdateLock ()
{
if ( ! $this -> request -> is ( 'post' )) {
throw new MethodNotAllowedException ( __ ( 'This endpoint expects POST requests.' ));
}
if ( ! $this -> _isSiteAdmin ()) {
2019-11-08 11:51:53 +01:00
throw new MethodNotAllowedException ( __ ( 'Only site admin accounts can release the update lock.' ));
2019-10-10 12:02:23 +02:00
}
$this -> Server -> changeLockState ( false );
2019-10-15 11:44:34 +02:00
$this -> Server -> resetUpdateFailNumber ();
2019-10-10 12:02:23 +02:00
$this -> redirect ( array ( 'action' => 'updateProgress' ));
}
2019-11-08 13:52:00 +01:00
public function dbSchemaDiagnostic ()
{
if ( ! $this -> _isSiteAdmin ()) {
throw new MethodNotAllowedException ( __ ( 'Only site admin accounts get the DB schema diagnostic.' ));
}
2019-11-19 18:07:30 +01:00
$dbSchemaDiagnostics = $this -> Server -> dbSchemaDiagnostic ();
if ( $this -> _isRest ()) {
return $this -> RestResponse -> viewData ( $dbSchemaDiagnostics , $this -> response -> type ());
} else {
$this -> set ( 'checkedTableColumn' , $dbSchemaDiagnostics [ 'checked_table_column' ]);
$this -> set ( 'dbSchemaDiagnostics' , $dbSchemaDiagnostics [ 'diagnostic' ]);
2019-12-18 15:53:20 +01:00
$this -> set ( 'dbIndexDiagnostics' , $dbSchemaDiagnostics [ 'diagnostic_index' ]);
2019-11-19 18:07:30 +01:00
$this -> set ( 'expectedDbVersion' , $dbSchemaDiagnostics [ 'expected_db_version' ]);
$this -> set ( 'actualDbVersion' , $dbSchemaDiagnostics [ 'actual_db_version' ]);
$this -> set ( 'error' , $dbSchemaDiagnostics [ 'error' ]);
$this -> set ( 'remainingLockTime' , $dbSchemaDiagnostics [ 'remaining_lock_time' ]);
$this -> set ( 'updateFailNumberReached' , $dbSchemaDiagnostics [ 'update_fail_number_reached' ]);
$this -> set ( 'updateLocked' , $dbSchemaDiagnostics [ 'update_locked' ]);
2019-12-10 10:49:02 +01:00
$this -> set ( 'dataSource' , $dbSchemaDiagnostics [ 'dataSource' ]);
2019-12-17 10:54:45 +01:00
$this -> set ( 'columnPerTable' , $dbSchemaDiagnostics [ 'columnPerTable' ]);
$this -> set ( 'indexes' , $dbSchemaDiagnostics [ 'indexes' ]);
2019-11-19 18:07:30 +01:00
$this -> render ( '/Elements/healthElements/db_schema_diagnostic' );
}
2019-11-08 13:52:00 +01:00
}
2019-11-20 15:30:06 +01:00
public function viewDeprecatedFunctionUse ()
{
$data = $this -> Deprecation -> getDeprecatedAccessList ( $this -> Server );
if ( $this -> _isRest ()) {
return $this -> RestResponse -> viewData ( $data , $this -> response -> type ());
} else {
$this -> layout = false ;
$this -> set ( 'data' , $data );
}
}
2020-06-22 16:14:16 +02:00
/**
* List all tags for the rule picker .
*
* @ return array
*/
private function __getTags ()
{
$this -> loadModel ( 'Tag' );
$list = $this -> Tag -> find ( 'list' , array (
'recursive' => - 1 ,
'order' => array ( 'LOWER(TRIM(Tag.name))' => 'ASC' ),
'fields' => array ( 'name' ),
));
$allTags = array ();
foreach ( $list as $id => $name ) {
$allTags [] = array ( 'id' => $id , 'name' => trim ( $name ));
}
return $allTags ;
}
2013-05-22 10:52:03 +02:00
}