-- Copyright (C) 2009-2013 Faculty of Information Technology, Brno University of Technology
--
-- Author: Maros Barabas <ibarabas@fit.vutbr.cz>
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License Version 2 as
-- published by the Free Software Foundation.  You may not use, modify or
-- distribute this program under any other version of the GNU General
-- Public License.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program; if not, write to the Free Software
-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

CREATE TABLE schema ( vseq        INT4     NOT NULL,
                      ctime       TIMESTAMP with time zone NOT NULL,
                      PRIMARY KEY (vseq));
INSERT INTO schema  (vseq, ctime) VALUES ('107', now());

CREATE TABLE signature ( sig_id       SERIAL NOT NULL,
                         sig_name     TEXT NOT NULL,
                         sig_class_id INT8,
                         sig_priority INT8,
                         sig_rev      INT8,
                         sig_sid      INT8,
                         sig_gid      INT8,
                         PRIMARY KEY (sig_id));
CREATE INDEX sig_name_idx ON signature (sig_name);
CREATE INDEX sig_class_idx ON signature (sig_class_id);

CREATE TABLE sig_reference (sig_id  INT4  NOT NULL,
                            ref_seq INT4  NOT NULL,
                            ref_id  INT4  NOT NULL,
                            PRIMARY KEY(sig_id, ref_seq));

CREATE TABLE reference (  ref_id        SERIAL,
                          ref_system_id INT4 NOT NULL,
                          ref_tag       TEXT NOT NULL,
                          PRIMARY KEY (ref_id));

CREATE TABLE reference_system ( ref_system_id   SERIAL,
                                ref_system_name TEXT,
                                PRIMARY KEY (ref_system_id));

CREATE TABLE sig_class ( sig_class_id        SERIAL,
                         sig_class_name      TEXT NOT NULL,
                         PRIMARY KEY (sig_class_id) );
CREATE INDEX sig_class_name_idx ON sig_class (sig_class_name);

CREATE TABLE event  ( sid 	  INT4 NOT NULL,
                      cid 	  INT8 NOT NULL,
                      signature   INT4 NOT NULL, 
                      timestamp   timestamp with time zone NOT NULL,
                      PRIMARY KEY (sid,cid));
CREATE INDEX signature_idx ON event (signature);
CREATE INDEX timestamp_idx ON event (timestamp);

-- store info about the sensor supplying data
CREATE TABLE sensor ( sid	  SERIAL,
                      hostname    TEXT,
                      interface   TEXT,
                      filter	  TEXT,
                      detail	  INT2,
                      encoding	  INT2,
                      last_cid    INT8 NOT NULL,
                      PRIMARY KEY (sid));

-- All of the fields of an ip header
CREATE TABLE iphdr  ( sid 	  INT4 NOT NULL,
                      cid 	  INT8 NOT NULL,
                      ip_src      INT8 NOT NULL,
                      ip_dst      INT8 NOT NULL,
                      ip_ver      INT2,
                      ip_hlen     INT2,
                      ip_tos  	  INT2,
                      ip_len 	  INT4,
                      ip_id    	  INT4,
                      ip_flags    INT2,
                      ip_off      INT4,
                      ip_ttl   	  INT2,
                      ip_proto 	  INT2 NOT NULL,
                      ip_csum 	  INT4,
                      PRIMARY KEY (sid,cid));
CREATE INDEX ip_src_idx ON iphdr (ip_src);
CREATE INDEX ip_dst_idx ON iphdr (ip_dst);

-- All of the fields of a tcp header
CREATE TABLE tcphdr(  sid 	  INT4 NOT NULL,
                      cid 	  INT8 NOT NULL,
                      tcp_sport   INT4 NOT NULL,
                      tcp_dport   INT4 NOT NULL,
                      tcp_seq     INT8,
                      tcp_ack     INT8,
                      tcp_off     INT2,
                      tcp_res     INT2,
                      tcp_flags   INT2 NOT NULL,
                      tcp_win     INT4,
                      tcp_csum    INT4,
                      tcp_urp     INT4,
                      PRIMARY KEY (sid,cid));
CREATE INDEX tcp_sport_idx ON tcphdr (tcp_sport);
CREATE INDEX tcp_dport_idx ON tcphdr (tcp_dport);
CREATE INDEX tcp_flags_idx ON tcphdr (tcp_flags);

-- All of the fields of a udp header
CREATE TABLE udphdr(  sid 	  INT4 NOT NULL,
                      cid 	  INT8 NOT NULL,
                      udp_sport   INT4 NOT NULL,
                      udp_dport   INT4 NOT NULL,
                      udp_len     INT4,
                      udp_csum    INT4,
                      PRIMARY KEY (sid,cid));
CREATE INDEX udp_sport_idx ON udphdr (udp_sport);
CREATE INDEX udp_dport_idx ON udphdr (udp_dport);

-- All of the fields of an icmp header
CREATE TABLE icmphdr( sid 	  INT4 NOT NULL,
                      cid 	  INT8 NOT NULL,
                      icmp_type   INT2 NOT NULL,
                      icmp_code   INT2 NOT NULL,
                      icmp_csum   INT4, 
                      icmp_id     INT4,
                      icmp_seq    INT4,
                      PRIMARY KEY (sid,cid));
CREATE INDEX icmp_type_idx ON icmphdr (icmp_type);

-- Protocol options
CREATE TABLE opt    ( sid         INT4 NOT NULL,
                      cid         INT8 NOT NULL,
                      optid       INT2 NOT NULL,
                      opt_proto   INT2 NOT NULL,
                      opt_code    INT2 NOT NULL,
                      opt_len     INT4,
                      opt_data    TEXT,
                      PRIMARY KEY (sid,cid,optid));

-- Packet payload
CREATE TABLE data   ( sid          INT4 NOT NULL,
                      cid          INT8 NOT NULL,
                      data_payload TEXT,
                      PRIMARY KEY (sid,cid));

-- encoding is a lookup table for storing encoding types
CREATE TABLE encoding(encoding_type INT2 NOT NULL,
                      encoding_text TEXT NOT NULL,
                      PRIMARY KEY (encoding_type));
INSERT INTO encoding (encoding_type, encoding_text) VALUES (0, 'hex');
INSERT INTO encoding (encoding_type, encoding_text) VALUES (1, 'base64');
INSERT INTO encoding (encoding_type, encoding_text) VALUES (2, 'ascii');

-- detail is a lookup table for storing different detail levels
CREATE TABLE detail  (detail_type INT2 NOT NULL,
                      detail_text TEXT NOT NULL,
                      PRIMARY KEY (detail_type));
INSERT INTO detail (detail_type, detail_text) VALUES (0, 'fast');
INSERT INTO detail (detail_type, detail_text) VALUES (1, 'full');

-- be sure to also use the snortdb-extra tables if you want
-- mappings for tcp flags, protocols, and ports

-- These are new tables that will be filled with Argos
CREATE SCHEMA argos;
CREATE TABLE argos.exploitMemoryBlocks (
                      id                SERIAL NOT NULL,
                      id_incident       INT8 NOT NULL,
                      memBlockSize      INT8 NOT NULL,
                      memBlockData      TEXT NOT NULL,
                      PRIMARY KEY (id));
CREATE TABLE argos.exploitPackets (
                      id                SERIAL NOT NULL,
                      id_incident       INT8 NOT NULL,
                      packetSize        INT8 NOT NULL,
                      packetData        TEXT NOT NULL,
                      PRIMARY KEY (id));

CREATE TABLE argos.incidents (
                      id                SERIAL NOT NULL,
                      version           VARCHAR(10) NOT NULL,
                      arch              VARCHAR(10) NOT NULL,
                      type              VARCHAR(10) NOT NULL,
                      timestamp   	timestamp with time zone NOT NULL,
                      eflags            VARCHAR(10) NOT NULL,
                      faultyEIP         VARCHAR(10) NOT NULL,
                      PRIMARY KEY (id));

CREATE TABLE argos.memoryBlocks (
                      id                SERIAL NOT NULL,
                      id_incident       INT8 NOT NULL,
                      version           VARCHAR(10) NOT NULL,
                      tainted           BOOLEAN NOT NULL,
                      size              INT8 NOT NULL,
                      memPhysical       VARCHAR(10) NOT NULL,
                      memVirtual        VARCHAR(10) NOT NULL,
                      data            	TEXT NOT NULL,
                      PRIMARY KEY (id));

CREATE TABLE argos.registerNames (
                      id                SERIAL NOT NULL,
                      name              VARCHAR(5) NOT NULL,
                      PRIMARY KEY (id));
INSERT INTO argos.registerNames (id, name) VALUES (1, 'EAX');
INSERT INTO argos.registerNames (id, name) VALUES (2, 'EBX');
INSERT INTO argos.registerNames (id, name) VALUES (3, 'ECX');
INSERT INTO argos.registerNames (id, name) VALUES (4, 'EDX');
INSERT INTO argos.registerNames (id, name) VALUES (5, 'ESP');
INSERT INTO argos.registerNames (id, name) VALUES (6, 'EBP');
INSERT INTO argos.registerNames (id, name) VALUES (7, 'ESI');
INSERT INTO argos.registerNames (id, name) VALUES (8, 'EDI');
INSERT INTO argos.registerNames (id, name) VALUES (9, 'EIP');

CREATE TABLE argos.registers (
                      id                SERIAL NOT NULL,
                      id_incident       INT8 NOT NULL,
                      id_register       INT8 NOT NULL,
                      value             VARCHAR(10) NOT NULL,
                      memoryFromAddr    VARCHAR(10) NOT NULL,
                      netidx            INT8,
                      tainted           BOOLEAN NOT NULL,
                      PRIMARY KEY (id));

CREATE TABLE argos.nettracker (
                      id                SERIAL NOT NULL,
                      length            INT4 NOT NULL,
                      data              TEXT);

-- TODO Popis
CREATE TABLE aips (
                    id              SERIAL NOT NULL,
                    name            VARCHAR(255) NOT NULL,
                    timestamp       timestamp with time zone NOT NULL,
                    info            TEXT NOT NULL,
                    argos_id        INT8 NOT NULL,
                    snort_tid       INT8 NOT NULL,
                    PRIMARY KEY (id));

CREATE TABLE snort_link (
                    tid             INT8 NOT NULL,
                    event_cid       INT8 NOT NULL);


-- CREATE SCHEMA tcpdump;
CREATE TABLE tcpdump (
                    id              SERIAL NOT NULL,
                    id_incident     INT8 NOT NULL,
                    timestamp       timestamp with time zone NOT NULL,
                    size            INT4 NOT NULL,
                    type            VARCHAR(255) NOT NULL,
                    eth_src         VARCHAR(17),
                    eth_dst         VARCHAR(17),
                    sport           INT4,
                    dport           INT4,
                    sum             INT4,
                    tcp_seq         INT8,
                    tcp_ack         INT8,
                    tcp_off_x2      INT4,
                    tcp_flags       INT4,
                    tcp_win         INT4,
                    tcp_urp         INT4,
                    udp_ulen        INT4,
                    igmp_type       INT4,
                    igmp_maxresp    INT8,
                    igmp_group      INT8,
                    ip_v_hl         INT4,
                    ip_tos          INT4,
                    ip_len          INT4,
                    ip_id           INT4,
                    ip_off          INT4,
                    ip_ttl          INT4,
                    ip_p            INT4,
                    ip_sum          INT4,
                    ip_src          VARCHAR(15),
                    ip_dst          VARCHAR(15),
                    arp_hrd         INT4,
                    arp_pro         INT4,
                    arp_hln         INT4,
                    arp_pln         INT4,
                    arp_op          INT4,
                    arp_sha         VARCHAR(17),
                    arp_spa         VARCHAR(15),
                    arp_tha         VARCHAR(17),
                    arp_tpa         VARCHAR(15),
                    data            TEXT,
                    PRIMARY KEY (id));

-- SNORT PRIVILEGES
GRANT SELECT ON snort_link, aips, detail, encoding, event, reference, reference_system, schema, sensor, sig_class, sig_reference, signature TO snort;
GRANT INSERT ON snort_link, aips, data, event, icmphdr, iphdr, opt, reference, reference_system, sensor, sig_class, sig_reference, signature, tcphdr, udphdr TO snort;
GRANT UPDATE ON aips_id_seq, reference_ref_id_seq, reference_system_ref_system_id_seq, sensor_sid_seq, sig_class_sig_class_id_seq, signature_sig_id_seq TO snort;
-- ARGOS PRIVILEGES
GRANT SELECT, INSERT, DELETE ON aips, argos.exploitmemoryblocks, argos.exploitpackets, argos.incidents, argos.memoryblocks, argos.registernames, argos.registers, argos.nettracker TO argos;
GRANT USAGE, SELECT, UPDATE ON argos.exploitpackets_id_seq, argos.incidents_id_seq, argos.memoryblocks_id_seq, argos.registernames_id_seq, argos.registers_id_seq, argos.exploitmemoryblocks_id_seq, aips_id_seq, argos.nettracker_id_seq TO argos;
GRANT USAGE ON SCHEMA argos TO argos;
-- GRANT AIPS table
GRANT SELECT, INSERT ON aips TO postgres;

CREATE LANGUAGE plpgsql;
CREATE FUNCTION aips_insert_metadata() RETURNS trigger AS $emp_stamp$
DECLARE TSTMP INTEGER;
BEGIN
    IF EXISTS (SELECT argos_id FROM aips WHERE argos_id = NEW.id) THEN
        RAISE EXCEPTION 'Event already registered!';
    END IF;
    INSERT INTO AIPS
        (name, timestamp, info, argos_id, snort_tid) 
    VALUES
        ('', NEW.timestamp, '', NEW.id, 0);

    SELECT INTO TSTMP EXTRACT('epoch' FROM NEW.timestamp);
    PERFORM pg_notify('tcpdump', TSTMP || ':' || NEW.id );
    RETURN NULL;
END;
$emp_stamp$ LANGUAGE 'plpgsql';

CREATE TRIGGER aips_insert_metadata_trigger AFTER INSERT ON argos.incidents
FOR EACH ROW
EXECUTE PROCEDURE aips_insert_metadata();
