2016-06-04 01:10:45 +02:00
< ? php
2013-11-06 10:52:18 +01:00
App :: uses ( 'AppShell' , 'Console/Command' );
2021-11-20 14:32:39 +01:00
App :: uses ( 'ProcessTool' , 'Tools' );
2022-03-02 16:54:08 +01:00
App :: uses ( 'FileAccessTool' , 'Tools' );
App :: uses ( 'JsonTool' , 'Tools' );
2021-07-26 12:06:14 +02:00
/**
* @ property Server $Server
2021-11-10 10:32:10 +01:00
* @ property Feed $Feed
2022-04-13 23:05:12 +02:00
* @ property Warninglist $warninglist
2022-03-02 16:54:08 +01:00
* @ property AdminSetting $AdminSetting
2022-05-14 10:39:29 +02:00
* @ property Taxonomy $Taxonomy
2022-05-15 08:52:51 +02:00
* @ property Warninglist $Warninglist
2022-05-09 21:52:28 +02:00
* @ property Attribute $Attribute
* @ property Job $Job
2022-10-19 21:16:17 +02:00
* @ property Correlation $Correlation
* @ property OverCorrelatingValue $OverCorrelatingValue
2021-07-26 12:06:14 +02:00
*/
2013-11-06 10:52:18 +01:00
class AdminShell extends AppShell
{
2022-08-10 14:17:20 +02:00
public $uses = [
'Event' , 'Post' , 'Attribute' , 'Job' , 'User' , 'Task' , 'Allowedlist' , 'Server' , 'Organisation' ,
'AdminSetting' , 'Galaxy' , 'Taxonomy' , 'Warninglist' , 'Noticelist' , 'ObjectTemplate' , 'Bruteforce' ,
'Role' , 'Feed' , 'SharingGroupBlueprint' , 'Correlation' , 'OverCorrelatingValue'
];
2021-09-27 15:01:53 +02:00
public function getOptionParser ()
{
$parser = parent :: getOptionParser ();
$parser -> addSubcommand ( 'updateJSON' , array (
'help' => __ ( 'Update the JSON definitions of MISP.' ),
));
2022-04-13 23:05:12 +02:00
$parser -> addSubcommand ( 'updateWarningLists' , array (
'help' => __ ( 'Update the JSON definition of warninglists.' ),
2022-10-24 10:56:41 +02:00
'parser' => [
'options' => [
'verbose' => [
'help' => 'Show verbose output.' ,
'default' => false ,
'boolean' => true
]
]
]
2022-04-13 23:05:12 +02:00
));
2022-05-14 10:39:29 +02:00
$parser -> addSubcommand ( 'updateTaxonomies' , array (
'help' => __ ( 'Update the JSON definition of taxonomies.' ),
));
2021-09-27 15:01:53 +02:00
$parser -> addSubcommand ( 'setSetting' , [
2024-01-14 15:47:20 +01:00
'help' => __ ( 'Set setting in MISP config' ),
2021-09-27 15:01:53 +02:00
'parser' => [
'arguments' => [
'name' => [ 'help' => __ ( 'Setting name' ), 'required' => true ],
2024-01-14 15:47:20 +01:00
'value' => [ 'help' => __ ( 'Setting value' )],
2021-09-27 15:01:53 +02:00
],
'options' => [
2021-11-05 22:49:11 +01:00
'force' => [
2021-09-27 15:01:53 +02:00
'short' => 'f' ,
'help' => 'Force the command.' ,
'default' => false ,
'boolean' => true
2021-11-05 22:49:11 +01:00
],
'null' => [
'short' => 'n' ,
'help' => 'Set the value to null.' ,
'default' => false ,
'boolean' => true
],
2021-09-27 15:01:53 +02:00
]
],
]);
2021-09-30 15:13:34 +02:00
$parser -> addSubcommand ( 'live' , [
'help' => __ ( 'Set if MISP instance is live and accessible for users.' ),
'parser' => [
'arguments' => [
2024-01-09 12:36:47 +01:00
'state' => [ 'help' => __ ( 'Set Live state (boolean). If not provided, current state will be printed.' )],
2021-09-30 15:13:34 +02:00
],
],
]);
2021-11-07 17:21:55 +01:00
$parser -> addSubcommand ( 'reencrypt' , [
'help' => __ ( 'Reencrypt encrypted values in database (authkeys and sensitive system settings).' ),
'parser' => [
'options' => [
'old' => [ 'help' => __ ( 'Old key. If not provided, current key will be used.' )],
'new' => [ 'help' => __ ( 'New key. If not provided, new key will be generated.' )],
],
],
]);
2024-01-05 16:39:46 +01:00
$parser -> addSubcommand ( 'isEncryptionKeyValid' , [
'help' => __ ( 'Check if current encryption key is valid.' ),
'parser' => [
'options' => [
2024-01-16 13:47:17 +01:00
'encryptionKey' => [ 'help' => __ ( 'Encryption key to test. If not provided, current key will be used.' )],
2024-01-05 16:39:46 +01:00
],
],
]);
2022-03-02 16:54:08 +01:00
$parser -> addSubcommand ( 'dumpCurrentDatabaseSchema' , [
'help' => __ ( 'Dump current database schema to JSON file.' ),
]);
2021-10-29 10:54:37 +02:00
$parser -> addSubcommand ( 'removeOrphanedCorrelations' , [
'help' => __ ( 'Remove orphaned correlations.' ),
]);
$parser -> addSubcommand ( 'optimiseTables' , [
'help' => __ ( 'Optimise database tables.' ),
]);
2021-11-11 10:14:46 +01:00
$parser -> addSubcommand ( 'redisMemoryUsage' , [
'help' => __ ( 'Get detailed information about Redis memory usage.' ),
]);
2021-11-13 11:34:27 +01:00
$parser -> addSubcommand ( 'redisReady' , [
'help' => __ ( 'Check if it is possible connect to Redis.' ),
]);
2022-01-11 14:42:45 +01:00
$parser -> addSubcommand ( 'securityAudit' , [
'help' => __ ( 'Run security audit.' ),
]);
2022-01-20 09:55:21 +01:00
$parser -> addSubcommand ( 'securityAuditTls' , [
2022-01-22 09:30:15 +01:00
'help' => __ ( 'Run security audit to test enabled/disabled ciphers and protocols in TLS connections.' ),
2022-01-20 09:55:21 +01:00
]);
2022-01-21 20:09:51 +01:00
$parser -> addSubcommand ( 'configLint' , [
'help' => __ ( 'Check if settings has correct value.' ),
]);
2024-01-13 12:53:07 +01:00
$parser -> addSubcommand ( 'createZmqConfig' , [
'help' => __ ( 'Create config file for ZeroMQ server.' ),
]);
2023-06-28 09:29:30 +02:00
$parser -> addSubcommand ( 'scanAttachment' , [
'help' => __ ( 'Scan attachments with AV.' ),
'parser' => [
'arguments' => [
'type' => [ 'help' => __ ( 'all, Attribute or ShadowAttribute' ), 'required' => true ],
'attributeId' => [ 'help' => __ ( 'ID to scan.' )],
'jobId' => [ 'help' => __ ( 'Job ID' )],
],
],
]);
2021-09-27 15:01:53 +02:00
return $parser ;
}
2020-02-10 15:15:59 +01:00
2023-07-10 15:30:28 +02:00
public function jobForgot ()
{
if ( empty ( $this -> args [ 0 ])) {
die ( 'Usage: ' . $this -> Server -> command_line_functions [ 'console_admin_tasks' ][ 'data' ][ 'Forgot' ] . PHP_EOL );
}
$email = $this -> args [ 0 ];
$ip = empty ( $this -> args [ 1 ]) ? null : $this -> args [ 1 ];
$jobId = empty ( $this -> args [ 2 ]) ? null : $this -> args [ 2 ];
$this -> User -> forgot ( $email , $ip , $jobId );
}
2020-02-10 15:15:59 +01:00
public function jobGenerateCorrelation ()
{
2023-09-11 10:36:56 +02:00
$jobId = $this -> args [ 0 ] ? ? null ;
if ( empty ( $jobId )) {
$jobId = $this -> Job -> createJob (
'SYSTEM' ,
Job :: WORKER_DEFAULT ,
'generate correlation' ,
'All attributes' ,
'Job created.'
);
2021-08-16 21:56:04 +02:00
}
2022-10-19 21:16:17 +02:00
$this -> Correlation -> generateCorrelation ( $jobId );
2019-04-10 08:29:28 +02:00
}
2016-06-04 01:08:16 +02:00
2022-08-10 14:17:20 +02:00
public function jobGenerateOccurrences ()
{
if ( empty ( $this -> args [ 0 ])) {
die ( 'Usage: ' . $this -> Server -> command_line_functions [ 'console_admin_tasks' ][ 'data' ][ 'Generate over-correlation occurrences' ] . PHP_EOL );
}
$jobId = $this -> args [ 0 ];
$this -> OverCorrelatingValue -> generateOccurrences ( $jobId );
}
2020-02-10 15:15:59 +01:00
public function jobPurgeCorrelation ()
{
2021-08-16 21:56:04 +02:00
if ( empty ( $this -> args [ 0 ])) {
die ( 'Usage: ' . $this -> Server -> command_line_functions [ 'console_admin_tasks' ][ 'data' ][ 'Purge correlation' ] . PHP_EOL );
}
2019-04-10 08:29:28 +02:00
$jobId = $this -> args [ 0 ];
2022-10-19 21:16:17 +02:00
$this -> Correlation -> purgeCorrelations ();
2022-05-26 15:42:16 +02:00
$this -> Job -> saveStatus ( $jobId );
2019-04-10 08:29:28 +02:00
}
2016-12-22 15:30:06 +01:00
2020-02-10 15:15:59 +01:00
public function jobGenerateShadowAttributeCorrelation ()
{
2021-08-16 21:56:04 +02:00
if ( empty ( $this -> args [ 0 ])) {
die ( 'Usage: ' . $this -> Server -> command_line_functions [ 'console_admin_tasks' ][ 'data' ][ 'Generate shadow attribute correlation' ] . PHP_EOL );
}
2019-04-10 08:29:28 +02:00
$jobId = $this -> args [ 0 ];
$this -> loadModel ( 'Job' );
$this -> Job -> id = $jobId ;
$this -> loadModel ( 'ShadowAttribute' );
$this -> ShadowAttribute -> generateCorrelation ( $jobId );
}
2016-06-04 01:08:16 +02:00
2020-02-10 15:15:59 +01:00
public function updateMISP ()
{
2019-04-02 10:18:00 +02:00
$status = array ( 'branch' => '2.4' );
echo $this -> Server -> update ( $status ) . PHP_EOL ;
}
2020-02-10 15:15:59 +01:00
public function updateAfterPull ()
{
2021-08-16 21:56:04 +02:00
if ( empty ( $this -> args [ 0 ]) || empty ( $this -> args [ 1 ]) || empty ( $this -> args [ 2 ])) {
die ( 'Usage: ' . $this -> Server -> command_line_functions [ 'console_admin_tasks' ][ 'data' ][ 'Update after pull' ] . PHP_EOL );
}
2019-04-05 14:28:19 +02:00
$this -> loadModel ( 'Job' );
$this -> loadModel ( 'Server' );
$submodule_name = $this -> args [ 0 ];
$jobId = $this -> args [ 1 ];
$userId = $this -> args [ 2 ];
$this -> Job -> id = $jobId ;
2019-04-05 16:04:22 +02:00
$result = $this -> Server -> updateAfterPull ( $submodule_name , $userId );
$this -> Job -> saveField ( 'progress' , 100 );
2019-08-29 17:36:47 +02:00
$this -> Job -> saveField ( 'date_modified' , date ( " Y-m-d H:i:s " ));
2019-04-05 14:28:19 +02:00
if ( $result ) {
2019-04-05 16:04:22 +02:00
$this -> Job -> saveField ( 'message' , __ ( 'Database updated: ' . $submodule_name ));
2019-04-05 14:28:19 +02:00
} else {
2019-04-05 16:04:22 +02:00
$this -> Job -> saveField ( 'message' , __ ( 'Could not update the database: ' . $submodule_name ));
2019-04-05 14:28:19 +02:00
}
2019-04-10 08:40:03 +02:00
}
2019-04-10 08:50:25 +02:00
2021-11-20 14:41:19 +01:00
public function restartWorkers ()
{
if ( Configure :: read ( 'SimpleBackgroundJobs.enabled' )) {
$this -> error ( 'This method does nothing when SimpleBackgroundJobs are enabled.' );
}
$this -> Server -> restartWorkers ();
echo PHP_EOL . 'Workers restarted.' . PHP_EOL ;
}
2019-04-09 13:32:35 +02:00
public function restartWorker ()
{
2021-11-20 14:41:19 +01:00
if ( Configure :: read ( 'SimpleBackgroundJobs.enabled' )) {
$this -> error ( 'This method does nothing when SimpleBackgroundJobs are enabled.' );
}
2019-04-09 13:32:35 +02:00
if ( empty ( $this -> args [ 0 ]) || ! is_numeric ( $this -> args [ 0 ])) {
2021-08-16 21:56:04 +02:00
die ( 'Usage: ' . $this -> Server -> command_line_functions [ 'worker_management_tasks' ][ 'data' ][ 'Restart a worker' ] . PHP_EOL );
2019-04-09 13:32:35 +02:00
}
2021-08-16 21:56:04 +02:00
2019-04-09 13:32:35 +02:00
$pid = $this -> args [ 0 ];
$result = $this -> Server -> restartWorker ( $pid );
if ( $result === true ) {
$response = __ ( 'Worker restarted.' );
} else {
$response = __ ( 'Could not restart the worker. Reason: %s' , $result );
}
echo sprintf (
'%s%s%s' ,
PHP_EOL ,
$response ,
PHP_EOL
);
}
public function killWorker ()
{
2021-11-20 14:41:19 +01:00
if ( Configure :: read ( 'SimpleBackgroundJobs.enabled' )) {
$this -> error ( 'This method does nothing when SimpleBackgroundJobs are enabled.' );
}
2019-04-09 13:32:35 +02:00
if ( empty ( $this -> args [ 0 ]) || ! is_numeric ( $this -> args [ 0 ])) {
2021-08-16 21:56:04 +02:00
die ( 'Usage: ' . $this -> Server -> command_line_functions [ 'worker_management_tasks' ][ 'data' ][ 'Kill a worker' ] . PHP_EOL );
2019-04-09 13:32:35 +02:00
}
2021-08-16 21:56:04 +02:00
2019-04-09 13:32:35 +02:00
$pid = $this -> args [ 0 ];
$result = $this -> Server -> killWorker ( $pid , false );
echo sprintf (
'%s%s%s' ,
PHP_EOL ,
__ ( 'Worker killed.' ),
PHP_EOL
);
}
public function startWorker ()
{
2021-11-20 14:41:19 +01:00
if ( Configure :: read ( 'SimpleBackgroundJobs.enabled' )) {
$this -> error ( 'This method does nothing when SimpleBackgroundJobs are enabled.' );
}
2019-04-09 13:32:35 +02:00
if ( empty ( $this -> args [ 0 ])) {
2021-08-16 21:56:04 +02:00
die ( 'Usage: ' . $this -> Server -> command_line_functions [ 'worker_management_tasks' ][ 'data' ][ 'Start a worker' ] . PHP_EOL );
2019-04-09 13:32:35 +02:00
}
2021-08-16 21:56:04 +02:00
2019-04-09 13:32:35 +02:00
$queue = $this -> args [ 0 ];
$this -> Server -> startWorker ( $queue );
echo sprintf (
'%s%s%s' ,
PHP_EOL ,
__ ( 'Worker started.' ),
PHP_EOL
);
}
2020-02-10 15:15:59 +01:00
public function updateJSON ()
{
2021-09-26 21:36:22 +02:00
$this -> out ( 'Updating all JSON structures.' );
2019-04-10 10:09:25 +02:00
$results = $this -> Server -> updateJSON ();
foreach ( $results as $type => $result ) {
2021-09-26 21:36:22 +02:00
$type = Inflector :: pluralize ( Inflector :: humanize ( $type ));
2019-04-10 08:29:28 +02:00
if ( $result !== false ) {
2021-09-26 21:36:22 +02:00
$this -> out ( __ ( '%s updated.' , $type ));
2019-04-10 08:29:28 +02:00
} else {
2021-09-26 21:36:22 +02:00
$this -> out ( __ ( 'Could not update %s.' , $type ));
2019-04-10 08:29:28 +02:00
}
}
2021-09-26 21:36:22 +02:00
$this -> out ( 'All JSON structures updated. Thank you and have a very safe and productive day.' );
2019-04-10 08:29:28 +02:00
}
2018-07-05 09:23:17 +02:00
2020-02-10 15:15:59 +01:00
public function updateGalaxies ()
{
2019-04-10 08:29:28 +02:00
// The following is 7.x upwards only
//$value = $this->args[0] ?? $this->args[0] ?? 0;
$value = empty ( $this -> args [ 0 ]) ? null : $this -> args [ 0 ];
if ( $value === 'false' ) $value = 0 ;
if ( $value === 'true' ) $value = 1 ;
if ( $value === 'force' ) $value = 1 ;
$force = $value ;
$result = $this -> Galaxy -> update ( $force );
if ( $result ) {
2019-05-01 15:27:38 +02:00
echo 'Galaxies updated' . PHP_EOL ;
2019-04-10 08:29:28 +02:00
} else {
2019-05-01 15:27:38 +02:00
echo 'Could not update Galaxies' . PHP_EOL ;
2019-04-10 08:29:28 +02:00
}
}
2018-07-08 23:07:36 +02:00
2020-02-10 15:15:59 +01:00
public function updateTaxonomies ()
{
2019-04-10 08:29:28 +02:00
$result = $this -> Taxonomy -> update ();
2022-05-14 10:39:29 +02:00
$successes = empty ( $result [ 'success' ]) ? 0 : count ( $result [ 'success' ]);
$fails = empty ( $result [ 'fails' ]) ? 0 : count ( $result [ 'fails' ]);
if ( $successes === 0 && $fails === 0 ) {
$message = __ ( 'All taxonomies are up to date already.' );
} elseif ( $successes === 0 && $fails > 0 ) {
2021-03-24 11:33:14 +01:00
$message = __ ( 'Could not update any of the taxonomies.' );
2022-05-14 10:39:29 +02:00
} else {
2021-03-24 11:33:14 +01:00
$message = __ ( 'Successfully updated %s taxonomies.' , $successes );
2022-05-14 10:39:29 +02:00
if ( $fails !== 0 ) {
2021-03-24 11:33:14 +01:00
$message .= __ ( ' However, could not update %s taxonomies.' , $fails );
}
2019-04-10 08:29:28 +02:00
}
2022-05-14 10:39:29 +02:00
$this -> out ( $message );
if ( $fails ) {
$this -> out ( __ ( 'Fails:' ));
foreach ( $result [ 'fails' ] as $fail ) {
$this -> out ( " { $fail [ 'namespace' ] } : { $fail [ 'fail' ] } " );
}
}
2019-04-10 08:29:28 +02:00
}
2018-07-08 23:07:36 +02:00
2021-03-24 21:36:51 +01:00
public function enableTaxonomyTags ()
{
if ( empty ( $this -> args [ 0 ]) || ! is_numeric ( $this -> args [ 0 ])) {
echo 'Usage: ' . APP . '/cake ' . 'Admin enableTaxonomyTags [taxonomy_id]' . PHP_EOL ;
} else {
$result = $this -> Taxonomy -> addTags ( intval ( $this -> args [ 0 ]));
if ( $result ) {
echo 'Taxonomy tags enabled' . PHP_EOL ;
} else {
echo 'Could not enable taxonomy tags' . PHP_EOL ;
}
}
}
2019-12-16 13:20:19 +01:00
public function updateWarningLists ()
2019-09-27 14:18:35 +02:00
{
$result = $this -> Warninglist -> update ();
2022-10-24 10:56:41 +02:00
if ( $this -> params [ 'verbose' ]) {
$this -> out ( $this -> json ( $result ));
} else {
$success = count ( $result [ 'success' ]);
$fails = count ( $result [ 'fails' ]);
$this -> out ( " $success warninglists updated, $fails fails " );
if ( $fails ) {
$this -> out ( __ ( 'Fails:' ));
foreach ( $result [ 'fails' ] as $fail ) {
$this -> out ( " { $fail [ 'name' ] } : { $fail [ 'fail' ] } " );
}
$this -> _stop ( 1 );
2022-05-15 08:52:51 +02:00
}
}
2019-04-10 08:29:28 +02:00
}
2018-07-10 13:18:43 +02:00
2020-02-10 15:15:59 +01:00
public function updateNoticeLists ()
{
2019-04-10 08:29:28 +02:00
$result = $this -> Noticelist -> update ();
if ( $result ) {
2019-05-01 15:27:38 +02:00
echo 'Notice lists updated' . PHP_EOL ;
2019-04-10 08:29:28 +02:00
} else {
2019-05-01 15:27:38 +02:00
echo 'Could not update notice lists' . PHP_EOL ;
2019-04-10 08:29:28 +02:00
}
}
2018-07-08 23:07:36 +02:00
2019-05-08 02:13:59 +02:00
# FIXME: Fails to pass userId/orgId properly, global update works.
2020-02-10 15:15:59 +01:00
public function updateObjectTemplates ()
{
2019-04-10 08:29:28 +02:00
if ( empty ( $this -> args [ 0 ])) {
2021-08-16 21:56:04 +02:00
die ( 'Usage: ' . $this -> Server -> command_line_functions [ 'console_admin_tasks' ][ 'data' ][ 'Update object templates' ] . PHP_EOL );
2019-04-10 08:29:28 +02:00
} else {
$userId = $this -> args [ 0 ];
2019-12-16 13:20:19 +01:00
$user = $this -> User -> getAuthUser ( $userId );
2019-05-08 02:13:59 +02:00
# If the user_id passed does not exist, do a global update.
2019-04-10 08:29:28 +02:00
if ( empty ( $user )) {
2019-05-08 02:12:18 +02:00
echo 'User with ID: ' . $userId . ' not found' . PHP_EOL ;
2019-05-08 02:09:41 +02:00
$result = $this -> ObjectTemplate -> update ();
2019-04-10 08:29:28 +02:00
} else {
$result = $this -> ObjectTemplate -> update ( $user , false , false );
2021-01-22 10:49:33 +01:00
}
$successes = count ( ! empty ( $result [ 'success' ]) ? $result [ 'success' ] : []);
$fails = count ( ! empty ( $result [ 'fails' ]) ? $result [ 'fails' ] : []);
$message = '' ;
if ( $successes == 0 && $fails == 0 ) {
$message = __ ( 'All object templates are up to date already.' );
} elseif ( $successes == 0 && $fails > 0 ) {
$message = __ ( 'Could not update any of the object templates.' );
} elseif ( $successes > 0 ) {
$message = __ ( 'Successfully updated %s object templates.' , $successes );
if ( $fails != 0 ) {
$message .= __ ( ' However, could not update %s object templates.' , $fails );
2019-04-10 08:29:28 +02:00
}
}
2021-01-22 10:49:33 +01:00
echo $message . PHP_EOL ;
2019-04-10 08:29:28 +02:00
}
}
2020-02-10 15:15:59 +01:00
public function jobUpgrade24 ()
{
2021-08-16 21:56:04 +02:00
if ( empty ( $this -> args [ 0 ]) || empty ( $this -> args [ 1 ])) {
die ( 'Usage: ' . $this -> Server -> command_line_functions [ 'console_admin_tasks' ][ 'data' ][ 'Job upgrade' ] . PHP_EOL );
}
2019-04-10 08:29:28 +02:00
$jobId = $this -> args [ 0 ];
$user_id = $this -> args [ 1 ];
$this -> loadModel ( 'Job' );
$this -> Job -> id = $jobId ;
$this -> loadModel ( 'Server' );
$this -> Server -> upgrade2324 ( $user_id , $jobId );
$this -> Job -> saveField ( 'progress' , 100 );
$this -> Job -> saveField ( 'message' , 'Job done.' );
$this -> Job -> saveField ( 'status' , 4 );
}
2017-01-30 09:16:43 +01:00
2020-02-10 15:15:59 +01:00
public function prune_update_logs ()
{
2021-08-16 21:56:04 +02:00
if ( empty ( $this -> args [ 0 ]) || empty ( $this -> args [ 1 ])) {
die ( 'Usage: ' . $this -> Server -> command_line_functions [ 'console_admin_tasks' ][ 'data' ][ 'Prune update logs' ] . PHP_EOL );
}
2019-04-10 08:29:28 +02:00
$jobId = $this -> args [ 0 ];
$user_id = $this -> args [ 1 ];
$user = $this -> User -> getAuthUser ( $user_id );
$this -> loadModel ( 'Job' );
$this -> Job -> id = $jobId ;
$this -> loadModel ( 'Log' );
$this -> Log -> pruneUpdateLogs ( $jobId , $user );
$this -> Job -> saveField ( 'progress' , 100 );
$this -> Job -> saveField ( 'message' , 'Job done.' );
$this -> Job -> saveField ( 'status' , 4 );
}
2018-04-01 17:31:31 +02:00
2020-02-10 15:15:59 +01:00
public function getWorkers ()
{
2019-04-10 08:29:28 +02:00
$result = $this -> Server -> workerDiagnostics ( $workerIssueCount );
2019-04-09 13:32:35 +02:00
$query = 'all' ;
if ( ! empty ( $this -> args [ 0 ])) {
$query = $this -> args [ 0 ];
}
if ( $query === 'dead' ) {
$dead_workers = array ();
foreach ( $result as $queue => $data ) {
if ( ! empty ( $data [ 'workers' ])) {
foreach ( $data [ 'workers' ] as $k => $worker ) {
if ( $worker [ 'alive' ]) {
unset ( $result [ $queue ][ 'workers' ][ $k ]);
}
}
}
if ( empty ( $result [ $queue ][ 'workers' ])) {
unset ( $result [ $queue ]);
}
}
}
2019-04-10 08:29:28 +02:00
echo json_encode ( $result , JSON_PRETTY_PRINT ) . PHP_EOL ;
2019-04-09 13:32:35 +02:00
}
2019-03-01 06:27:39 +01:00
2020-02-10 15:15:59 +01:00
public function getSetting ()
{
2019-04-10 08:29:28 +02:00
$param = empty ( $this -> args [ 0 ]) ? 'all' : $this -> args [ 0 ];
$settings = $this -> Server -> serverSettingsRead ();
$result = $settings ;
2021-11-05 10:49:16 +01:00
if ( $param !== 'all' ) {
2019-04-10 08:29:28 +02:00
$result = 'No valid setting found for ' . $param ;
foreach ( $settings as $setting ) {
2021-11-05 10:49:16 +01:00
if ( $setting [ 'setting' ] === $param ) {
2019-04-10 08:29:28 +02:00
$result = $setting ;
break ;
}
}
}
2024-01-14 15:47:20 +01:00
$this -> out ( $this -> json ( $result ));
2019-03-01 06:27:39 +01:00
}
2018-04-01 17:31:31 +02:00
2020-02-10 15:15:59 +01:00
public function setSetting ()
{
2024-01-14 15:47:20 +01:00
list ( $settingName ) = $this -> args ;
if ( $this -> params [ 'null' ] && isset ( $this -> args [ 1 ])) {
$this -> error ( __ ( 'Trying to set setting to null value, but value was provided.' ));
} else if ( $this -> params [ 'null' ]) {
2021-11-05 22:49:11 +01:00
$value = null ;
2024-01-14 15:47:20 +01:00
} elseif ( isset ( $this -> args [ 1 ])) {
$value = $this -> args [ 1 ];
} else {
$this -> error ( __ ( 'No setting value provided.' ));
2021-11-05 22:49:11 +01:00
}
2024-01-14 15:47:20 +01:00
$setting = $this -> Server -> getSettingData ( $settingName );
2021-10-08 12:33:09 +02:00
if ( empty ( $setting )) {
2024-01-14 15:47:20 +01:00
$message = 'Invalid setting "' . $settingName . '". Please make sure that the setting that you are attempting to change exists and if a module parameter, the modules are running.' . PHP_EOL ;
2021-10-08 12:33:09 +02:00
$this -> error ( __ ( 'Setting change rejected.' ), $message );
}
2024-01-14 15:47:20 +01:00
// Convert value to boolean or to int
if ( $value !== null ) {
if ( $setting [ 'type' ] === 'boolean' ) {
$value = $this -> toBoolean ( $value );
} else if ( $setting [ 'type' ] === 'numeric' ) {
if ( is_numeric ( $value )) {
$value = ( int ) $value ;
} elseif ( $value === 'true' || $value === 'false' ) {
$value = $value === 'true' ? 1 : 0 ; // special case for `debug` setting
} else {
$this -> error ( __ ( 'Setting "%s" change rejected.' , $settingName ), __ ( 'Provided value %s is not a number.' , $value ));
}
}
}
$result = $this -> Server -> serverSettingsEditValue ( 'SYSTEM' , $setting , $value , $this -> params [ 'force' ]);
2021-10-08 12:33:09 +02:00
if ( $result === true ) {
2024-01-14 15:47:20 +01:00
$this -> out ( __ ( 'Setting "%s" changed to %s' , $settingName , is_string ( $value ) ? '"' . $value . '"' : json_encode ( $value )));
2019-04-10 08:29:28 +02:00
} else {
2021-10-08 12:33:09 +02:00
$message = __ ( " The setting change was rejected. MISP considers the requested setting value as invalid and would lead to the following error: \n \n \" %s \" \n \n If you still want to force this change, please supply the --force argument. \n " , $result );
$this -> error ( __ ( 'Setting change rejected.' ), $message );
2019-04-10 08:29:28 +02:00
}
}
2018-06-15 23:01:07 +02:00
2020-02-10 15:15:59 +01:00
public function setDatabaseVersion ()
{
2021-08-16 21:56:04 +02:00
if ( empty ( $this -> args [ 0 ])) {
die ( 'Usage: ' . $this -> Server -> command_line_functions [ 'console_admin_tasks' ][ 'data' ][ 'Set database version' ] . PHP_EOL );
} else {
2019-04-10 08:29:28 +02:00
$db_version = $this -> AdminSetting -> find ( 'first' , array (
'conditions' => array ( 'setting' => 'db_version' )
));
if ( ! empty ( $db_version )) {
2019-07-08 15:46:29 +02:00
$db_version [ 'AdminSetting' ][ 'value' ] = trim ( $this -> args [ 0 ]);
2019-04-10 08:29:28 +02:00
$this -> AdminSetting -> save ( $db_version );
echo 'Database version set. MISP will replay all of the upgrade scripts since the selected version on the next user login.' . PHP_EOL ;
} else {
echo 'Something went wrong. Could not find the existing db version.' . PHP_EOL ;
}
}
}
2018-06-15 23:01:07 +02:00
2020-02-10 15:15:59 +01:00
public function runUpdates ()
{
2021-11-20 14:32:39 +01:00
$whoami = ProcessTool :: whoami ();
2021-09-26 21:36:22 +02:00
if ( in_array ( $whoami , [ 'httpd' , 'www-data' , 'apache' , 'wwwrun' , 'travis' , 'www' ], true ) || $whoami === Configure :: read ( 'MISP.osuser' )) {
$this -> out ( 'Executing all updates to bring the database up to date with the current version.' );
2023-12-14 14:19:46 +01:00
$lock = $this -> AdminSetting -> find ( 'first' , array ( 'conditions' => array ( 'setting' => 'update_locked' )));
if ( ! empty ( $lock )) {
$this -> AdminSetting -> delete ( $lock [ 'AdminSetting' ][ 'id' ]);
}
2020-02-26 16:18:37 +01:00
$processId = empty ( $this -> args [ 0 ]) ? false : $this -> args [ 0 ];
2019-09-30 15:31:49 +02:00
$this -> Server -> runUpdates ( true , false , $processId );
2023-06-09 08:22:45 +02:00
$this -> Server -> cleanCacheFiles ();
2021-09-26 21:36:22 +02:00
$this -> out ( 'All updates completed.' );
2019-04-29 11:09:04 +02:00
} else {
2021-09-26 21:36:22 +02:00
$this -> error ( 'This OS user is not allowed to run this command.' , 'Run it under `www-data` or `httpd` or `apache` or `wwwrun` or set MISP.osuser in the configuration.' . PHP_EOL . 'You tried to run this command as: ' . $whoami );
2019-04-29 11:09:04 +02:00
}
2019-02-09 20:57:34 +01:00
}
2020-02-10 15:15:59 +01:00
public function getAuthkey ()
{
2021-09-27 15:01:53 +02:00
if ( Configure :: read ( " Security.advanced_authkeys " )) {
$this -> error ( 'Advanced autkeys enabled, it is not possible to get user authkey.' );
}
2018-07-28 09:06:06 +02:00
if ( empty ( $this -> args [ 0 ])) {
2021-08-16 21:56:04 +02:00
die ( 'Usage: ' . $this -> Server -> command_line_functions [ 'console_admin_tasks' ][ 'data' ][ 'Get authkey' ] . PHP_EOL );
2018-07-28 09:06:06 +02:00
} else {
$user = $this -> User -> find ( 'first' , array (
'recursive' => - 1 ,
'conditions' => array ( 'User.email' => strtolower ( $this -> args [ 0 ])),
'fields' => array ( 'User.authkey' )
));
if ( empty ( $user )) {
echo 'Invalid user.' . PHP_EOL ;
} else {
echo $user [ 'User' ][ 'authkey' ] . PHP_EOL ;
}
}
}
2021-09-26 21:40:18 +02:00
public function redisReady ()
{
try {
2023-05-24 10:28:39 +02:00
$redis = RedisTool :: init ();
for ( $i = 0 ; $i < 10 ; $i ++ ) {
2024-03-21 12:25:37 +01:00
$pong = $redis -> ping ();
if ( $pong !== true ) {
$this -> out ( 'Redis is still loading... ' . $pong );
2023-05-24 10:28:39 +02:00
sleep ( 1 );
} else {
break ;
}
}
if ( $i === 9 ) {
$this -> out ( 'Redis is still loading, but we will continue.' );
} else {
$this -> out ( 'Successfully connected to Redis.' );
}
2021-09-26 21:40:18 +02:00
} catch ( Exception $e ) {
$this -> error ( 'Redis connection is not available' , $e -> getMessage ());
}
}
2019-04-10 08:29:28 +02:00
public function clearBruteforce ()
{
$conditions = array ( 'Bruteforce.username !=' => '' );
if ( ! empty ( $this -> args [ 0 ])) {
2018-12-02 21:39:01 +01:00
$conditions = array ( 'Bruteforce.username' => $this -> args [ 0 ]);
}
2019-04-10 08:29:28 +02:00
$result = $this -> Bruteforce -> deleteAll ( $conditions , false , false );
$target = empty ( $this -> args [ 0 ]) ? 'all users' : $this -> args [ 0 ];
if ( $result ) {
2021-09-26 21:36:22 +02:00
echo 'Bruteforce entries for ' . $target . ' deleted.' . PHP_EOL ;
2019-04-10 08:29:28 +02:00
} else {
echo 'Something went wrong, could not delete bruteforce entries for ' . $target . '.' . PHP_EOL ;
}
}
2019-04-04 16:35:27 +02:00
public function setDefaultRole ()
{
if ( empty ( $this -> args [ 0 ]) || ! is_numeric ( $this -> args [ 0 ])) {
$roles = $this -> Role -> find ( 'list' , array (
'fields' => array ( 'id' , 'name' )
));
foreach ( $roles as $k => $role ) {
$roles [ $k ] = $k . '. ' . $role ;
}
$roles = implode ( PHP_EOL , $roles );
echo " Roles: \n " . $roles . $this -> separator ();
2021-08-16 21:56:04 +02:00
die ( 'Usage: ' . $this -> Server -> command_line_functions [ 'console_admin_tasks' ][ 'data' ][ 'Set default role' ] . PHP_EOL );
2019-04-04 16:35:27 +02:00
} else {
$role = $this -> Role -> find ( 'first' , array (
'recursive' => - 1 ,
'conditions' => array ( 'Role.id' => $this -> args [ 0 ])
));
if ( ! empty ( $role )) {
$result = $this -> AdminSetting -> changeSetting ( 'default_role' , $role [ 'Role' ][ 'id' ]);
echo 'Default Role updated to ' . escapeshellcmd ( $role [ 'Role' ][ 'name' ]) . PHP_EOL ;
} else {
echo 'Something went wrong, invalid Role.' . PHP_EOL ;
}
}
}
private function separator ()
{
return PHP_EOL . '---------------------------------------------------------------' . PHP_EOL ;
}
2019-04-07 16:24:44 +02:00
2021-08-24 17:35:09 +02:00
/**
* @ deprecated Use UserShell instead
*/
2019-04-07 16:24:44 +02:00
public function change_authkey ()
{
2024-01-12 11:57:02 +01:00
$this -> deprecated ( 'cake user change_authkey [user_id]' );
2019-04-07 16:24:44 +02:00
if ( empty ( $this -> args [ 0 ])) {
2021-08-16 21:56:04 +02:00
echo 'MISP apikey command line tool' . PHP_EOL . 'To assign a new random API key for a user: ' . APP . 'Console/cake Admin change_authkey [user_email]' . PHP_EOL . 'To assign a fixed API key: ' . APP . 'Console/cake Admin change_authkey [user_email] [authkey]' . PHP_EOL ;
2019-04-07 16:24:44 +02:00
die ();
}
2021-08-16 21:56:04 +02:00
2019-04-07 16:24:44 +02:00
if ( ! empty ( $this -> args [ 1 ])) {
$authKey = $this -> args [ 1 ];
} else {
$authKey = $this -> User -> generateAuthKey ();
}
$user = $this -> User -> find ( 'first' , array (
'conditions' => array ( 'email' => $this -> args [ 0 ]),
'recursive' => - 1 ,
'fields' => array ( 'User.id' , 'User.email' , 'User.authkey' )
));
if ( empty ( $user )) {
2019-05-01 15:27:38 +02:00
echo 'Invalid e-mail, user not found.' . PHP_EOL ;
2019-04-07 16:24:44 +02:00
die ();
}
$user [ 'User' ][ 'authkey' ] = $authKey ;
$fields = array ( 'id' , 'email' , 'authkey' );
if ( ! $this -> User -> save ( $user , true , $fields )) {
echo 'Could not update authkey, reason:' . PHP_EOL . json_encode ( $this -> User -> validationErrors ) . PHP_EOL ;
die ();
}
echo 'Updated, new key:' . PHP_EOL . $authKey . PHP_EOL ;
}
2019-04-29 11:09:04 +02:00
2019-05-08 11:51:26 +02:00
public function recoverSinceLastSuccessfulUpdate ()
{
$this -> loadModel ( 'Log' );
$logs = $this -> Log -> find ( 'all' , array (
'conditions' => array (
'action' => 'update_database' ,
2019-05-22 11:01:46 +02:00
'title LIKE ' => array (
'Successfuly executed the SQL query for %' ,
'Issues executing the SQL query for %'
)
2019-05-08 11:51:26 +02:00
),
'order' => 'id DESC'
));
$last_db_num = - 1 ;
foreach ( $logs as $i => $log ) {
preg_match_all ( '/.* the SQL query for (\d+)/' , $log [ 'Log' ][ 'title' ], $matches );
if ( ! empty ( $matches [ 1 ])) {
$last_db_num = $matches [ 1 ][ 0 ];
break ;
}
}
if ( $last_db_num > 0 ) {
echo __ ( 'Last DB num which was successfully executed: ' ) . h ( $last_db_num ) . PHP_EOL ;
// replay all update from that point.
$this -> loadModel ( 'AdminSetting' );
$db_version = $this -> AdminSetting -> find ( 'first' , array ( 'conditions' => array ( 'setting' => 'db_version' )));
if ( ! empty ( $db_version )) {
$db_version [ 'AdminSetting' ][ 'value' ] = $last_db_num ;
$this -> AdminSetting -> save ( $db_version );
$this -> Server -> runUpdates ( true );
} else {
echo __ ( 'Something went wrong. Could not find the existing db version' ) . PHP_EOL ;
}
} else {
echo __ ( 'DB was never successfully updated or we are on a fresh install' ) . PHP_EOL ;
}
}
2019-08-01 15:15:20 +02:00
public function cleanCaches ()
{
echo 'Cleaning caches...' . PHP_EOL ;
$this -> Server -> cleanCacheFiles ();
echo '...caches lost in time, like tears in rain.' . PHP_EOL ;
}
2019-09-09 13:00:21 +02:00
public function resetSyncAuthkeys ()
{
if ( empty ( $this -> args [ 0 ])) {
echo sprintf (
2021-08-16 21:56:04 +02:00
__ ( " MISP mass sync authkey reset command line tool " . PHP_EOL . " Usage: %sConsole/cake Admin resetSyncAuthkeys [user_id] " . PHP_EOL ), APP
2019-09-09 13:00:21 +02:00
);
die ();
} else {
$userId = $this -> args [ 0 ];
$user = $this -> User -> getAuthUser ( $userId );
if ( empty ( $user )) {
echo __ ( 'Invalid user.' ) . " \n \n " ;
}
if ( ! $user [ 'Role' ][ 'perm_site_admin' ]) {
echo __ ( 'User has to be a site admin.' ) . " \n \n " ;
}
if ( ! empty ( $this -> args [ 1 ])) {
$jobId = $this -> args [ 1 ];
} else {
$jobId = false ;
}
$this -> User -> resetAllSyncAuthKeys ( $user , $jobId );
}
}
2019-09-13 10:48:43 +02:00
public function purgeFeedEvents ()
{
if (
( empty ( $this -> args [ 0 ]) || ! is_numeric ( $this -> args [ 0 ])) ||
( empty ( $this -> args [ 1 ]) || ! is_numeric ( $this -> args [ 1 ]))
) {
2021-08-16 21:56:04 +02:00
die ( 'Usage: ' . $this -> Server -> command_line_functions [ 'console_admin_tasks' ][ 'data' ][ 'Purge feed events' ] . PHP_EOL );
2019-09-13 10:48:43 +02:00
} else {
$user_id = $this -> args [ 0 ];
$feed_id = $this -> args [ 1 ];
$result = $this -> Feed -> cleanupFeedEvents ( $user_id , $feed_id );
if ( is_string ( $result )) {
echo __ ( " \n Error: %s \n " , $result );
} else {
echo __ ( " %s events purged. \n " , $result );
}
}
}
2019-09-26 15:20:32 +02:00
public function dumpCurrentDatabaseSchema ()
{
2019-12-18 15:53:20 +01:00
$dbActualSchema = $this -> Server -> getActualDBSchema ();
2021-09-26 18:00:49 +02:00
$dbVersion = $this -> AdminSetting -> getSetting ( 'db_version' );
2019-12-18 15:53:20 +01:00
if ( ! empty ( $dbVersion ) && ! empty ( $dbActualSchema [ 'schema' ])) {
2022-03-02 16:54:08 +01:00
$data = [
2019-12-18 15:53:20 +01:00
'schema' => $dbActualSchema [ 'schema' ],
2019-12-18 16:21:13 +01:00
'indexes' => $dbActualSchema [ 'indexes' ],
2022-03-02 16:54:08 +01:00
'db_version' => $dbVersion ,
];
FileAccessTool :: writeToFile ( ROOT . DS . 'db_schema.json' , JsonTool :: encode ( $data , true ));
$this -> out ( __ ( " > Database schema dumped on disk " ));
2019-09-26 15:20:32 +02:00
} else {
2022-03-02 16:54:08 +01:00
$this -> error ( __ ( 'Something went wrong.' ), __ ( 'Could not find the existing db version or fetch the current database schema.' ));
2019-09-26 15:20:32 +02:00
}
}
2020-02-20 16:07:10 +01:00
2021-08-24 17:35:09 +02:00
/**
* @ deprecated Use UserShell instead
*/
2020-02-20 16:07:10 +01:00
public function UserIP ()
{
2024-01-12 11:57:02 +01:00
$this -> deprecated ( 'cake user user_ips [user_id]' );
2020-02-20 16:07:10 +01:00
if ( empty ( $this -> args [ 0 ])) {
die ( 'Usage: ' . $this -> Server -> command_line_functions [ 'console_admin_tasks' ][ 'data' ][ 'Get IPs for user ID' ] . PHP_EOL );
}
2021-08-16 21:56:04 +02:00
2020-02-20 16:07:10 +01:00
$user_id = trim ( $this -> args [ 0 ]);
$redis = $this -> Server -> setupRedis ();
$user = $this -> User -> find ( 'first' , array (
'recursive' => - 1 ,
'conditions' => array ( 'User.id' => $user_id )
));
if ( empty ( $user )) {
2021-08-16 21:56:04 +02:00
echo PHP_EOL . 'Invalid user ID.' . PHP_EOL ;
2020-02-20 16:07:10 +01:00
die ();
}
$ips = $redis -> smembers ( 'misp:user_ip:' . $user_id );
$ips = implode ( PHP_EOL , $ips );
echo sprintf (
'%s==============================%sUser #%s: %s%s==============================%s%s%s==============================%s' ,
PHP_EOL , PHP_EOL , $user [ 'User' ][ 'id' ], $user [ 'User' ][ 'email' ], PHP_EOL , PHP_EOL , $ips , PHP_EOL , PHP_EOL
);
}
2021-09-27 15:01:53 +02:00
/**
* @ deprecated Use UserShell instead
*/
2020-02-20 16:07:10 +01:00
public function IPUser ()
{
2024-01-12 11:57:02 +01:00
$this -> deprecated ( 'cake user ip_user [ip]' );
2020-02-20 16:07:10 +01:00
if ( empty ( $this -> args [ 0 ])) {
die ( 'Usage: ' . $this -> Server -> command_line_functions [ 'console_admin_tasks' ][ 'data' ][ 'Get user ID for user IP' ] . PHP_EOL );
}
2021-08-16 21:56:04 +02:00
2020-02-20 16:07:10 +01:00
$ip = trim ( $this -> args [ 0 ]);
$redis = $this -> Server -> setupRedis ();
$user_id = $redis -> get ( 'misp:ip_user:' . $ip );
if ( empty ( $user_id )) {
echo PHP_EOL . 'No hits.' . PHP_EOL ;
die ();
}
$user = $this -> User -> find ( 'first' , array (
'recursive' => - 1 ,
'conditions' => array ( 'User.id' => $user_id )
));
echo sprintf (
'%s==============================%sIP: %s%s==============================%sUser #%s: %s%s==============================%s' ,
PHP_EOL , PHP_EOL , $ip , PHP_EOL , PHP_EOL , $user [ 'User' ][ 'id' ], $user [ 'User' ][ 'email' ], PHP_EOL , PHP_EOL
);
}
2020-10-08 19:27:49 +02:00
public function scanAttachment ()
{
$input = $this -> args [ 0 ];
2023-06-28 09:29:30 +02:00
$attributeId = $this -> args [ 1 ] ? ? null ;
$jobId = $this -> args [ 2 ] ? ? null ;
2020-10-08 19:27:49 +02:00
$this -> loadModel ( 'AttachmentScan' );
$result = $this -> AttachmentScan -> scan ( $input , $attributeId , $jobId );
if ( $result === false ) {
echo 'Job failed' . PHP_EOL ;
} else {
echo $result . PHP_EOL ;
}
}
2021-01-07 09:31:38 +01:00
public function cleanExcludedCorrelations ()
{
$jobId = $this -> args [ 0 ];
$this -> CorrelationExclusion = ClassRegistry :: init ( 'CorrelationExclusion' );
$this -> CorrelationExclusion -> clean ( $jobId );
$this -> Job -> id = $jobId ;
$this -> Job -> saveField ( 'progress' , 100 );
$this -> Job -> saveField ( 'message' , 'Job done.' );
$this -> Job -> saveField ( 'status' , 4 );
}
2021-02-25 11:37:37 +01:00
2021-10-29 10:54:37 +02:00
public function removeOrphanedCorrelations ()
{
$count = $this -> Server -> removeOrphanedCorrelations ();
$this -> out ( __ ( '%s orphaned correlation removed' , $count ));
}
public function optimiseTables ()
{
$dataSource = $this -> Server -> getDataSource ();
$tables = $dataSource -> listSources ();
/** @var ProgressShellHelper $progress */
$progress = $this -> helper ( 'progress' );
$progress -> init ([
'total' => count ( $tables ),
'width' => 50 ,
]);
foreach ( $tables as $table ) {
2023-03-29 23:50:54 +02:00
$dataSource -> query ( 'OPTIMIZE TABLE ' . $dataSource -> name ( $table ));
2021-10-29 10:54:37 +02:00
$progress -> increment ();
$progress -> draw ();
}
$this -> out ( 'Optimised.' );
}
2021-02-25 11:37:37 +01:00
public function updatesDone ()
{
$blocking = ! empty ( $this -> args [ 0 ]);
$done = $this -> AdminSetting -> updatesDone ( $blocking );
$this -> out ( $done ? 'True' : 'False' );
}
2021-04-21 12:53:05 +02:00
public function wipeDefaultClusters ()
{
$this -> loadModel ( 'GalaxyCluster' );
$this -> out ( 'Dropping default galaxy clusters. This process might take some time...' );
$this -> GalaxyCluster -> wipe_default ();
}
2021-07-16 15:13:55 +02:00
public function updateToAdvancedAuthKeys ()
{
$this -> loadModel ( 'User' );
$updated = $this -> User -> updateToAdvancedAuthKeys ();
$message = __ ( 'The upgrade process is complete, %s authkey(s) generated.' , $updated );
$this -> out ( $message );
}
2021-08-03 14:38:50 +02:00
public function schemaDiagnostics ()
{
$dbSchemaDiagnostics = $this -> Server -> dbSchemaDiagnostic ();
$this -> out ( '# Columns diagnostics' );
foreach ( $dbSchemaDiagnostics [ 'diagnostic' ] as $tableName => $diagnostics ) {
$diagnostics = array_filter ( $diagnostics , function ( $c ) {
return $c [ 'is_critical' ];
});
if ( empty ( $diagnostics )) {
continue ;
}
$this -> out ();
$this -> out ( 'Table ' . $tableName . ':' );
foreach ( $diagnostics as $diagnostic ) {
$this -> out ( ' - ' . $diagnostic [ 'description' ]);
$this -> out ( ' Expected: ' . implode ( ' ' , $diagnostic [ 'expected' ]));
if ( ! empty ( $diagnostic [ 'actual' ])) {
$this -> out ( ' Actual: ' . implode ( ' ' , $diagnostic [ 'actual' ]));
}
}
}
$this -> out ();
$this -> out ( '# Index diagnostics' );
foreach ( $dbSchemaDiagnostics [ 'diagnostic_index' ] as $tableName => $diagnostics ) {
$this -> out ();
$this -> out ( 'Table ' . $tableName . ':' );
foreach ( $diagnostics as $info ) {
$this -> out ( ' - ' . $info [ 'message' ]);
}
}
}
2021-09-30 15:13:34 +02:00
public function live ()
{
if ( isset ( $this -> args [ 0 ])) {
$newStatus = $this -> toBoolean ( $this -> args [ 0 ]);
$overallSuccess = false ;
try {
2024-01-09 12:36:47 +01:00
$redis = RedisTool :: init ();
2021-09-30 15:13:34 +02:00
if ( $newStatus ) {
$redis -> del ( 'misp:live' );
$this -> out ( 'Set live status to True in Redis.' );
} else {
$redis -> set ( 'misp:live' , '0' );
$this -> out ( 'Set live status to False in Redis.' );
}
$overallSuccess = true ;
} catch ( Exception $e ) {
$this -> out ( '<warning>Redis is not reachable.</warning>' );
}
$success = $this -> Server -> serverSettingsSaveValue ( 'MISP.live' , $newStatus );
if ( $success ) {
$this -> out ( 'Set live status in PHP config file.' );
$overallSuccess = true ;
} else {
$this -> out ( '<warning>Could not set MISP.live in PHP config file.</warning>' );
}
if ( $overallSuccess ) {
$this -> out ( $newStatus ? 'MISP is now live. Users can now log in.' : 'MISP is now disabled. Only site admins can log in.' );
} else {
$this -> error ( 'Could not save live status in Redis or PHP config file.' );
}
} else {
$this -> out ( 'Current status:' );
$this -> out ( 'PHP Config file: ' . ( Configure :: read ( 'MISP.live' ) ? 'True' : 'False' ));
2024-01-09 12:36:47 +01:00
$newStatus = RedisTool :: init () -> get ( 'misp:live' );
2021-09-30 15:13:34 +02:00
$this -> out ( 'Redis: ' . ( $newStatus !== '0' ? 'True' : 'False' ));
}
}
2021-11-07 17:21:55 +01:00
public function reencrypt ()
{
$old = $this -> params [ 'old' ] ? ? null ;
$new = $this -> params [ 'new' ] ? ? null ;
if ( $new !== null && strlen ( $new ) < 32 ) {
2022-02-19 11:16:03 +01:00
$this -> error ( 'New key must be at least 32 chars long.' );
2021-11-07 17:21:55 +01:00
}
if ( $old === null ) {
$old = Configure :: read ( 'Security.encryption_key' );
}
if ( $new === null ) {
// Generate random new key
2022-02-19 11:16:03 +01:00
$new = rtrim ( base64_encode ( random_bytes ( 32 )), " = " );
2021-11-07 17:21:55 +01:00
}
$this -> Server -> getDataSource () -> begin ();
try {
/** @var SystemSetting $systemSetting */
$systemSetting = ClassRegistry :: init ( 'SystemSetting' );
$systemSetting -> reencrypt ( $old , $new );
$this -> Server -> reencryptAuthKeys ( $old , $new );
/** @var Cerebrate $cerebrate */
$cerebrate = ClassRegistry :: init ( 'Cerebrate' );
$cerebrate -> reencryptAuthKeys ( $old , $new );
$result = $this -> Server -> serverSettingsSaveValue ( 'Security.encryption_key' , $new , true );
$this -> Server -> getDataSource () -> commit ();
if ( ! $result ) {
$this -> error ( 'Encrypt key was changed, but it is not possible to save key to config file' , __ ( 'Please insert new key "%s" to config file manually.' , $new ));
}
} catch ( Exception $e ) {
$this -> Server -> getDataSource () -> rollback ();
throw $e ;
}
$this -> out ( __ ( 'New encryption key "%s" saved into config file.' , $new ));
}
2021-11-10 10:32:10 +01:00
2024-01-05 16:39:46 +01:00
public function isEncryptionKeyValid ()
{
$encryptionKey = $this -> params [ 'encryptionKey' ] ? ? null ;
if ( $encryptionKey === null ) {
$encryptionKey = Configure :: read ( 'Security.encryption_key' );
}
if ( ! $encryptionKey ) {
$this -> error ( 'No encryption key provided' );
}
/** @var SystemSetting $systemSetting */
$systemSetting = ClassRegistry :: init ( 'SystemSetting' );
2024-01-16 13:47:17 +01:00
try {
$systemSetting -> isEncryptionKeyValid ( $encryptionKey );
$this -> Server -> isEncryptionKeyValid ( $encryptionKey );
} catch ( Exception $e ) {
$this -> error ( $e -> getMessage (), __ ( 'Probably provided encryption key is invalid' ));
}
2024-01-05 16:39:46 +01:00
}
2021-11-10 10:32:10 +01:00
public function redisMemoryUsage ()
{
2022-10-08 18:16:54 +02:00
$redis = RedisTool :: init ();
2021-11-10 10:32:10 +01:00
$output = [];
2022-10-08 18:16:54 +02:00
list ( $count , $size ) = RedisTool :: sizeByPrefix ( $redis , 'misp:feed_cache:*' );
2021-11-10 10:32:10 +01:00
$output [ 'feed_cache_count' ] = $count ;
$output [ 'feed_cache_size' ] = $size ;
// Size of different feeds
$feedIds = $this -> Feed -> find ( 'column' , [
'fields' => [ 'id' ],
]);
$redis -> pipeline ();
foreach ( $feedIds as $feedId ) {
$redis -> rawCommand ( " memory " , " usage " , 'misp:feed_cache:' . $feedId );
}
$feedSizes = $redis -> exec ();
foreach ( $feedIds as $k => $feedId ) {
if ( $feedSizes [ $k ]) {
2021-11-10 18:15:59 +01:00
$output [ 'feed_cache_size_' . $feedId ] = $feedSizes [ $k ];
}
}
2022-10-08 18:16:54 +02:00
list ( $count , $size ) = RedisTool :: sizeByPrefix ( $redis , 'misp:server_cache:*' );
2021-11-10 18:15:59 +01:00
$output [ 'server_cache_count' ] = $count ;
$output [ 'server_cache_size' ] = $size ;
// Size of different server
$serverIds = $this -> Server -> find ( 'column' , [
'fields' => [ 'id' ],
]);
$redis -> pipeline ();
foreach ( $serverIds as $serverId ) {
$redis -> rawCommand ( " memory " , " usage " , 'misp:server_cache:' . $serverId );
}
$serverSizes = $redis -> exec ();
foreach ( $serverIds as $k => $serverId ) {
if ( $serverSizes [ $k ]) {
$output [ 'server_cache_size_' . $serverId ] = $serverSizes [ $k ];
2021-11-10 10:32:10 +01:00
}
}
2022-10-08 18:16:54 +02:00
list ( $count , $size ) = RedisTool :: sizeByPrefix ( $redis , 'misp:wlc:*' );
2021-11-10 10:32:10 +01:00
$output [ 'warninglist_cache_count' ] = $count ;
$output [ 'warninglist_cache_size' ] = $size ;
2022-10-08 18:16:54 +02:00
list ( $count , $size ) = RedisTool :: sizeByPrefix ( $redis , 'misp:warninglist_entries_cache:*' );
2021-11-10 10:32:10 +01:00
$output [ 'warninglist_entries_count' ] = $count ;
$output [ 'warninglist_entries_size' ] = $size ;
2022-10-08 18:16:54 +02:00
list ( $count , $size ) = RedisTool :: sizeByPrefix ( $redis , 'misp:top_correlation' );
2021-11-10 10:32:10 +01:00
$output [ 'top_correlation_count' ] = $count ;
$output [ 'top_correlation_size' ] = $size ;
2022-10-08 18:16:54 +02:00
list ( $count , $size ) = RedisTool :: sizeByPrefix ( $redis , 'misp:correlation_exclusions' );
2021-11-10 10:32:10 +01:00
$output [ 'correlation_exclusions_count' ] = $count ;
$output [ 'correlation_exclusions_size' ] = $size ;
2022-10-08 18:16:54 +02:00
list ( $count , $size ) = RedisTool :: sizeByPrefix ( $redis , 'misp:event_lock:*' );
2021-11-10 10:32:10 +01:00
$output [ 'event_lock_count' ] = $count ;
$output [ 'event_lock_size' ] = $size ;
2022-10-08 18:16:54 +02:00
list ( $count , $size ) = RedisTool :: sizeByPrefix ( $redis , 'misp:user_ip:*' );
2021-11-10 10:32:10 +01:00
$output [ 'user_ip_count' ] = $count ;
$output [ 'user_ip_size' ] = $size ;
2022-10-08 18:16:54 +02:00
list ( $count , $size ) = RedisTool :: sizeByPrefix ( $redis , 'misp:ip_user:*' );
2021-11-10 10:32:10 +01:00
$output [ 'user_ip_count' ] += $count ;
$output [ 'user_ip_size' ] += $size ;
2022-10-08 18:16:54 +02:00
list ( $count , $size ) = RedisTool :: sizeByPrefix ( $redis , 'misp:authkey_usage:*' );
2021-11-10 10:32:10 +01:00
$output [ 'authkey_usage_count' ] = $count ;
$output [ 'authkey_usage_size' ] = $size ;
2021-11-11 10:14:46 +01:00
$this -> out ( $this -> json ( $output ));
2021-11-10 10:32:10 +01:00
}
2022-01-11 14:42:45 +01:00
public function securityAudit ()
{
// Start session to initialize ini setting for session cookies
CakeSession :: start ();
CakeSession :: destroy ();
$formatFindings = function ( array $findings ) {
$value = '' ;
foreach ( $findings as $finding ) {
if ( $finding [ 0 ] === 'error' ) {
$value .= '<error>Error:</error>' ;
} else if ( $finding [ 0 ] === 'warning' ) {
$value .= '<warning>Warning:</warning>' ;
} else if ( $finding [ 0 ] === 'hint' ) {
continue ; // Ignore hints
}
$value .= ' ' . $finding [ 1 ] . PHP_EOL ;
}
return $value ;
};
App :: uses ( 'SecurityAudit' , 'Tools' );
$securityAudit = ( new SecurityAudit ()) -> run ( $this -> Server , true );
foreach ( $securityAudit as $field => $findings ) {
$value = $formatFindings ( $findings );
if ( ! empty ( $value )) {
$this -> out ( $field );
$this -> out ( '==============================' );
$this -> out ( $value );
}
}
}
2022-01-20 09:55:21 +01:00
public function securityAuditTls ()
{
App :: uses ( 'SecurityAudit' , 'Tools' );
$securityAudit = ( new SecurityAudit ()) -> tlsConnections ();
foreach ( $securityAudit as $type => $details ) {
$result = $details [ 'success' ] ? 'True' : 'False' ;
2022-01-22 09:30:15 +01:00
if ( isset ( $details [ 'expected' ]) && $details [ 'expected' ] !== $details [ 'success' ]) {
2022-01-20 09:55:21 +01:00
$result = " <error> $result </error> " ;
}
$this -> out ( " $type : $result " );
}
}
2022-01-21 20:09:51 +01:00
public function configLint ()
{
$serverSettings = $this -> Server -> serverSettingsRead ();
foreach ( $serverSettings as $setting ) {
if ( ! isset ( $setting [ 'error' ])) {
continue ;
}
if ( $setting [ 'errorMessage' ] === 'Value not set.' ) {
continue ; // Skip not set values.
}
$this -> out ( $setting [ 'setting' ] . ': ' . $setting [ 'errorMessage' ]);
}
}
2022-03-02 02:09:20 +01:00
public function executeSGBlueprint ()
{
$id = false ;
$target = 'all' ;
if ( ! empty ( $this -> args [ 0 ])) {
$target = trim ( $this -> args [ 0 ]);
}
if ( ! is_numeric ( $target ) && ! in_array ( $target , [ 'all' , 'attached' , 'deteached' ])) {
$this -> error ( __ ( 'Invalid target. Either pass a blueprint ID or one of the following filters: all, attached, detached.' ));
}
$conditions = [];
if ( is_numeric ( $target )) {
$conditions [ 'SharingGroupBlueprint' ][ 'id' ] = $target ;
} else if ( $target === 'attached' ) {
$conditions [ 'SharingGroupBlueprint' ][ 'sharing_group_id >' ] = 0 ;
} else if ( $target === 'detached' ) {
$conditions [ 'SharingGroupBlueprint' ][ 'sharing_group_id' ] = 0 ;
}
$sharingGroupBlueprints = $this -> SharingGroupBlueprint -> find ( 'all' , [ 'conditions' => $conditions , 'recursive' => 0 ]);
if ( empty ( $sharingGroupBlueprints )) {
$this -> error ( __ ( 'No valid blueprints found.' ));
}
$stats = $this -> SharingGroupBlueprint -> execute ( $sharingGroupBlueprints );
$message = __ (
'Done, %s sharing group blueprint(s) matched. Sharing group changes: Created: %s. Updated: %s. Failed to create: %s.' ,
count ( $sharingGroupBlueprints ),
$stats [ 'created' ],
$stats [ 'changed' ],
$stats [ 'failed' ]
);
$this -> out ( $message );
}
2022-08-03 15:44:27 +02:00
public function truncateTable ()
{
2022-08-04 10:49:04 +02:00
if ( ! isset ( $this -> args [ 0 ])) {
2022-08-03 15:44:27 +02:00
die ( 'Usage: ' . $this -> Server -> command_line_functions [ 'console_admin_tasks' ][ 'data' ][ 'Truncate table correlation' ] . PHP_EOL );
}
$userId = $this -> args [ 0 ];
if ( $userId ) {
$user = $this -> User -> getAuthUser ( $userId );
} else {
$user = [
'id' => 0 ,
'email' => 'SYSTEM' ,
'Organisation' => [
'name' => 'SYSTEM'
]
];
}
if ( empty ( $this -> args [ 1 ])) {
die ( 'Usage: ' . $this -> Server -> command_line_functions [ 'console_admin_tasks' ][ 'data' ][ 'Truncate table correlation' ] . PHP_EOL );
}
if ( ! empty ( $this -> args [ 2 ])) {
$jobId = $this -> args [ 2 ];
}
$table = trim ( $this -> args [ 1 ]);
$this -> Correlation -> truncate ( $user , $table );
if ( $jobId ) {
2022-08-04 10:49:04 +02:00
$this -> Job -> id = $jobId ;
2022-08-03 15:44:27 +02:00
$this -> Job -> saveField ( 'progress' , 100 );
$this -> Job -> saveField ( 'date_modified' , date ( " Y-m-d H:i:s " ));
$this -> Job -> saveField ( 'message' , __ ( 'Database truncated: ' . $table ));
}
}
2024-01-13 12:53:07 +01:00
public function createZmqConfig ()
{
$this -> Server -> getPubSubTool () -> createConfigFile ();
$this -> err ( " Config file created in " . PubSubTool :: SCRIPTS_TMP );
}
2013-11-06 10:52:18 +01:00
}