Ejemplo n.º 1
0
 /**
  * Execute the command.
  *
  * @return array
  */
 public function handle()
 {
     // Start with building a classification lookup table
     $classNames = [];
     foreach (Lang::get('classifications') as $classID => $class) {
         $classNames[$class['name']] = $classID;
     }
     // Also build a types lookup table
     $typeNames = [];
     foreach (Lang::get('types.type') as $typeID => $type) {
         $typeNames[$type['name']] = $typeID;
     }
     // Also build a status lookup table
     $statusNames = [];
     foreach (Lang::get('types.status') as $statusID => $status) {
         $statusNames[$status['name']] = $statusID;
     }
     foreach ($this->events as $event) {
         /* Here we will thru all the events and look if these is an existing ticket. We will split them up into
          * two seperate arrays: $eventsNew and $events$known. We can save all the known events in the DB with
          * a single event saving loads of queries
          *
          * IP Owner is leading, as in most cases even if the domain is moved
          * The server might still have a problem. Next to the fact that domains
          * Arent transferred to a new owner 'internally' anyways.
          *
          * So we do a lookup based on the IP same as with the 3.x engine. After
          * the lookup we check wither the domain contact was changed, if so we UPDATE
          * the ticket and put a note somewhere about it. This way the IP owner does
          * not get a new ticket on this matter and the new domain owner is getting updates.
          *
          * As the ASH link is based on the contact code, the old domain owner will not
          * have any access to the ticket anymore.
          */
         // Lookup the ip contact and if needed the domain contact too
         $ipContact = FindContact::byIP($event['ip']);
         if ($event['domain'] != '') {
             $domainContact = FindContact::byDomain($event['domain']);
         }
         // Search to see if there is an existing ticket for this event classification
         // Todo: somehow add the domain too!!!!
         $search = Ticket::where('ip', '=', $event['ip'])->where('class_id', '=', $classNames[$event['class']], 'AND')->where('type_id', '=', $typeNames[$event['type']], 'AND')->where('ip_contact_reference', '=', $ipContact->reference, 'AND')->where('status_id', '!=', 2, 'AND')->get();
         if ($search->count() === 0) {
             // Build an array with all new tickes and save it with its related event and evidence link.
             $newTicket = new Ticket();
             $newTicket->ip = $event['ip'];
             $newTicket->domain = $event['domain'];
             $newTicket->class_id = $classNames[$event['class']];
             $newTicket->type_id = $typeNames[$event['type']];
             $newTicket->ip_contact_reference = $ipContact->reference;
             $newTicket->ip_contact_name = $ipContact->name;
             $newTicket->ip_contact_email = $ipContact->email;
             $newTicket->ip_contact_rpchost = $ipContact->rpc_host;
             $newTicket->ip_contact_rpckey = $ipContact->rpc_key;
             $newTicket->ip_contact_auto_notify = $ipContact->auto_notify;
             if ($event['domain'] != '') {
                 $newTicket->domain_contact_reference = $domainContact->reference;
                 $newTicket->domain_contact_name = $domainContact->name;
                 $newTicket->domain_contact_email = $domainContact->email;
                 $newTicket->domain_contact_rpchost = $domainContact->rpc_host;
                 $newTicket->domain_contact_rpckey = $domainContact->rpc_key;
                 $newTicket->domain_contact_auto_notify = $domainContact->auto_notify;
             }
             $newTicket->status_id = 1;
             $newTicket->notified_count = 0;
             $newTicket->last_notify_count = 0;
             $newTicket->last_notify_timestamp = 0;
             $newTicket->save();
             $newEvent = new Event();
             $newEvent->evidence_id = $this->evidenceID;
             $newEvent->information = $event['information'];
             $newEvent->source = $event['source'];
             $newEvent->ticket_id = $newTicket->id;
             $newEvent->timestamp = $event['timestamp'];
             $newEvent->save();
             // Call notifier action handler, type new
         } elseif ($search->count() === 1) {
             $ticketID = $search[0]->id;
             if (Event::where('information', '=', $event['information'])->where('source', '=', $event['source'])->where('ticket_id', '=', $ticketID)->where('timestamp', '=', $event['timestamp'])->exists()) {
                 // Exact duplicate match so we will ignore this event
             } else {
                 // New unique event, so we will save this
                 $newEvent = new Event();
                 $newEvent->evidence_id = $this->evidenceID;
                 $newEvent->information = $event['information'];
                 $newEvent->source = $event['source'];
                 $newEvent->ticket_id = $ticketID;
                 $newEvent->timestamp = $event['timestamp'];
                 $newEvent->save();
                 // Call notifier action handler, type update
             }
             // This is an existing ticket
         } else {
             $this->failed('Unable to link to ticket, multiple open tickets found for same event type');
         }
     }
     $this->success('');
 }
Ejemplo n.º 2
0
 /**
  * Execute the command.
  *
  * @param array $events
  * @param integer $evidenceID
  * @return array
  */
 public function save($events, $evidenceID)
 {
     $ticketCount = 0;
     $eventCount = 0;
     $eventsIgnored = 0;
     foreach ($events as $event) {
         /* Here we will seek through all the events and look if there is an existing ticket. We will split them up
          * into two seperate arrays: $eventsNew and $events$known. We can save all the known events in the DB with
          * a single event saving loads of queries
          *
          * IP Owner is leading, as in most cases even if the domain is moved
          * The server might still have a problem. Next to the fact that domains
          * Arent transferred to a new owner 'internally' anyways.
          *
          * So we do a lookup based on the IP same as with the 3.x engine. After
          * the lookup we check wither the domain contact was changed, if so we UPDATE
          * the ticket and put a note somewhere about it. This way the IP owner does
          * not get a new ticket on this matter and the new domain owner is getting updates.
          *
          * As the ASH link is based on the contact code, the old domain owner will not
          * have any access to the ticket anymore.
          */
         // If an event is too old we are ignoring it
         if (config('main.reports.min_lastseen') !== false && strtotime(config('main.reports.min_lastseen')) !== false && strtotime(config('main.reports.min_lastseen') . ' ago') > $event['timestamp']) {
             Log::debug(get_class($this) . ': ' . "is ignoring event because its older then " . config('main.reports.min_lastseen'));
             continue;
         }
         // Start with building a classification lookup table  and switch out name for ID
         foreach ((array) Lang::get('classifications') as $classID => $class) {
             if ($class['name'] == $event['class']) {
                 $event['class'] = $classID;
             }
         }
         // Also build a types lookup table and switch out name for ID
         foreach ((array) Lang::get('types.type') as $typeID => $type) {
             if ($type['name'] == $event['type']) {
                 $event['type'] = $typeID;
             }
         }
         // Lookup the ip contact and if needed the domain contact too
         $findContact = new FindContact();
         $ipContact = $findContact->byIP($event['ip']);
         if ($event['domain'] != '') {
             $domainContact = $findContact->byDomain($event['domain']);
         } else {
             $domainContact = $findContact->undefined();
         }
         /*
          * Ignore the event if both ip and domain contacts are undefined and the resolving of an contact
          * was required. This is handy to ignore any reports that are not considered local, but use
          * with caution as it might just ignore anything if your IP/domains are not correctly configured
          */
         if ($ipContact->reference == 'UNDEF' && $domainContact->reference == 'UNDEF' && config('main.reports.resolvable_only') === true) {
             if (!empty($domainContact) && $domainContact->reference == 'UNDEF' || empty($domainContact)) {
                 Log::debug(get_class($this) . ': ' . "is ignoring event because there is no IP or Domain contact");
                 continue;
             }
         }
         /*
          * Search to see if there is an existing ticket for this event classification
          */
         $ticket = Ticket::where('ip', '=', $event['ip'])->where('class_id', '=', $event['class'], 'AND')->where('type_id', '=', $event['type'], 'AND')->where('ip_contact_reference', '=', $ipContact->reference, 'AND')->where('status_id', '!=', 2, 'AND')->get();
         if ($ticket->count() === 0) {
             /*
              * If there are no search results then there is no existing ticket and we should create one
              */
             $ticketCount++;
             $newTicket = new Ticket();
             $newTicket->ip = $event['ip'];
             $newTicket->domain = empty($event['domain']) ? '' : $event['domain'];
             $newTicket->class_id = $event['class'];
             $newTicket->type_id = $event['type'];
             $newTicket->ip_contact_account_id = $ipContact->account_id;
             $newTicket->ip_contact_reference = $ipContact->reference;
             $newTicket->ip_contact_name = $ipContact->name;
             $newTicket->ip_contact_email = $ipContact->email;
             $newTicket->ip_contact_api_host = $ipContact->api_host;
             $newTicket->ip_contact_api_key = $ipContact->api_key;
             $newTicket->ip_contact_auto_notify = $ipContact->auto_notify;
             $newTicket->ip_contact_notified_count = 0;
             $newTicket->domain_contact_account_id = $domainContact->account_id;
             $newTicket->domain_contact_reference = $domainContact->reference;
             $newTicket->domain_contact_name = $domainContact->name;
             $newTicket->domain_contact_email = $domainContact->email;
             $newTicket->domain_contact_api_host = $domainContact->api_host;
             $newTicket->domain_contact_api_key = $domainContact->api_key;
             $newTicket->domain_contact_auto_notify = $domainContact->auto_notify;
             $newTicket->domain_contact_notified_count = 0;
             $newTicket->status_id = 1;
             $newTicket->last_notify_count = 0;
             $newTicket->last_notify_timestamp = 0;
             $newTicket->save();
             $newEvent = new Event();
             $newEvent->evidence_id = $evidenceID;
             $newEvent->information = $event['information'];
             $newEvent->source = $event['source'];
             $newEvent->ticket_id = $newTicket->id;
             $newEvent->timestamp = $event['timestamp'];
             $newEvent->save();
         } elseif ($ticket->count() === 1) {
             /*
              * There is an existing ticket, so we just need to add the event to this ticket. If the event is an
              * exact match we consider it a duplicate and will ignore it.
              */
             $ticket = $ticket[0];
             if (Event::where('information', '=', $event['information'])->where('source', '=', $event['source'])->where('ticket_id', '=', $ticket->id)->where('timestamp', '=', $event['timestamp'])->exists()) {
                 $eventsIgnored++;
             } else {
                 // New unique event, so we will save this
                 $eventCount++;
                 $newEvent = new Event();
                 $newEvent->evidence_id = $evidenceID;
                 $newEvent->information = $event['information'];
                 $newEvent->source = $event['source'];
                 $newEvent->ticket_id = $ticket->id;
                 $newEvent->timestamp = $event['timestamp'];
                 $newEvent->save();
                 /*
                  * If the reference has changed for the domain owner, then we update the ticket with the new
                  * domain owner. We not check if anything else then the reference has changed. If you change the
                  * contact data you have the option to propogate it onto open tickets.
                  */
                 if (!empty($event['domain']) && $domainContact !== false && $domainContact->reference !== $ticket->domain_contact_reference) {
                     $ticket->domain_contact_reference = $domainContact->reference;
                     $ticket->domain_contact_name = $domainContact->name;
                     $ticket->domain_contact_email = $domainContact->email;
                     $ticket->domain_contact_api_host = $domainContact->api_host;
                     $ticket->domain_contact_api_key = $domainContact->api_key;
                     $ticket->domain_contact_auto_notify = $domainContact->auto_notify;
                     $ticket->account_id = $domainContact->account->id;
                     $ticket->save();
                 }
                 // TODO: If this is an abuse/escalation ticket and currently 'resolved' then put status back to Open
                 // TODO: Implement escalation triggers
             }
         } else {
             /*
              * We should not never have more then two open tickets for the same case. If this happens there is a
              * fault in the aggregator which must be resolved first. Until then we will permfail here.
              */
             $this->failed('Unable to link to ticket, multiple open tickets found for same event type');
         }
     }
     Log::debug(get_class($this) . ': ' . "has completed creating {$ticketCount} new tickets, " . "linking {$eventCount} new events and ignored {$eventsIgnored} duplicates");
     $this->success('');
 }
Ejemplo n.º 3
0
 /**
  * Execute the command.
  * @return array
  */
 public function handle()
 {
     $ticketCount = 0;
     $eventCount = 0;
     $eventsIgnored = 0;
     foreach ($this->events as $event) {
         /* Here we will thru all the events and look if these is an existing ticket. We will split them up into
          * two seperate arrays: $eventsNew and $events$known. We can save all the known events in the DB with
          * a single event saving loads of queries
          *
          * IP Owner is leading, as in most cases even if the domain is moved
          * The server might still have a problem. Next to the fact that domains
          * Arent transferred to a new owner 'internally' anyways.
          *
          * So we do a lookup based on the IP same as with the 3.x engine. After
          * the lookup we check wither the domain contact was changed, if so we UPDATE
          * the ticket and put a note somewhere about it. This way the IP owner does
          * not get a new ticket on this matter and the new domain owner is getting updates.
          *
          * As the ASH link is based on the contact code, the old domain owner will not
          * have any access to the ticket anymore.
          */
         // Start with building a classification lookup table  and switch out name for ID
         foreach ((array) Lang::get('classifications') as $classID => $class) {
             if ($class['name'] == $event['class']) {
                 $event['class'] = $classID;
             }
         }
         // Also build a types lookup table and switch out name for ID
         foreach ((array) Lang::get('types.type') as $typeID => $type) {
             if ($type['name'] == $event['type']) {
                 $event['type'] = $typeID;
             }
         }
         // Lookup the ip contact and if needed the domain contact too
         $ipContact = FindContact::byIP($event['ip']);
         if ($event['domain'] != '') {
             $domainContact = FindContact::byDomain($event['domain']);
         } else {
             $domainContact = false;
         }
         /*
          * Search to see if there is an existing ticket for this event classification
          */
         $search = Ticket::where('ip', '=', $event['ip'])->where('class_id', '=', $event['class'], 'AND')->where('type_id', '=', $event['type'], 'AND')->where('ip_contact_reference', '=', $ipContact->reference, 'AND')->where('status_id', '!=', 2, 'AND')->get();
         if ($search->count() === 0) {
             /*
              * If there are no search results then there is no existing ticket and we should create one
              */
             $ticketCount++;
             $newTicket = new Ticket();
             $newTicket->ip = $event['ip'];
             $newTicket->domain = $event['domain'];
             $newTicket->class_id = $event['class'];
             $newTicket->type_id = $event['type'];
             $newTicket->ip_contact_reference = $ipContact->reference;
             $newTicket->ip_contact_name = $ipContact->name;
             $newTicket->ip_contact_email = $ipContact->email;
             $newTicket->ip_contact_rpchost = $ipContact->rpc_host;
             $newTicket->ip_contact_rpckey = $ipContact->rpc_key;
             $newTicket->ip_contact_auto_notify = $ipContact->auto_notify;
             if (!empty($event['domain']) && $domainContact !== false) {
                 $newTicket->domain_contact_reference = $domainContact->reference;
                 $newTicket->domain_contact_name = $domainContact->name;
                 $newTicket->domain_contact_email = $domainContact->email;
                 $newTicket->domain_contact_rpchost = $domainContact->rpc_host;
                 $newTicket->domain_contact_rpckey = $domainContact->rpc_key;
                 $newTicket->domain_contact_auto_notify = $domainContact->auto_notify;
             }
             $newTicket->status_id = 1;
             $newTicket->notified_count = 0;
             $newTicket->last_notify_count = 0;
             $newTicket->last_notify_timestamp = 0;
             $newTicket->save();
             $newEvent = new Event();
             $newEvent->evidence_id = $this->evidenceID;
             $newEvent->information = $event['information'];
             $newEvent->source = $event['source'];
             $newEvent->ticket_id = $newTicket->id;
             $newEvent->timestamp = $event['timestamp'];
             $newEvent->save();
             // TODO - Call notifier action handler, type new
         } elseif ($search->count() === 1) {
             /*
              * There is an existing ticket, so we just need to add the event to this ticket. If the event is an
              * exact match we consider it a duplicate and will ignore it.
              */
             $ticketID = $search[0]->id;
             if (Event::where('information', '=', $event['information'])->where('source', '=', $event['source'])->where('ticket_id', '=', $ticketID)->where('timestamp', '=', $event['timestamp'])->exists()) {
                 $eventsIgnored++;
             } else {
                 // New unique event, so we will save this
                 $eventCount++;
                 $newEvent = new Event();
                 $newEvent->evidence_id = $this->evidenceID;
                 $newEvent->information = $event['information'];
                 $newEvent->source = $event['source'];
                 $newEvent->ticket_id = $ticketID;
                 $newEvent->timestamp = $event['timestamp'];
                 $newEvent->save();
                 // TODO - Update domain owner if changed based on the contactID (reference)
                 // TODO - Call notifier action handler, type update
             }
         } else {
             /*
              * We should not never have more then two open tickets for the same case. If this happens there is a
              * fault in the aggregator which must be resolved first. Until then we will permfail here.
              */
             $this->failed('Unable to link to ticket, multiple open tickets found for same event type');
         }
     }
     Log::debug('(JOB ' . getmypid() . ') ' . get_class($this) . ': ' . "has completed creating {$ticketCount} new tickets, " . "linking {$eventCount} new events and ignored {$eventsIgnored} duplicates");
     $this->success('');
 }