1 /* 2 * Copyright © [2008-2009] Novell, Inc. All Rights Reserved. 3 * 4 * USE AND REDISTRIBUTION OF THIS WORK IS SUBJECT TO THE DEVELOPER LICENSE AGREEMENT 5 * OR OTHER AGREEMENT THROUGH WHICH NOVELL, INC. MAKES THE WORK AVAILABLE. THIS WORK 6 * MAY NOT BE ADAPTED WITHOUT NOVELL'S PRIOR WRITTEN CONSENT. 7 * 8 * NOVELL PROVIDES THE WORK "AS IS," WITHOUT ANY EXPRESS OR IMPLIED WARRANTY, 9 * INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR 10 * A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. NOVELL, THE AUTHORS OF THE WORK, AND THE 11 * OWNERS OF COPYRIGHT IN THE WORK ARE NOT LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER 12 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF, 13 * OR IN CONNECTION WITH THE WORK OR THE USE OR OTHER DEALINGS IN THE WORK. 14 */ 15 16 /** 17 * @fileoverview 18 * This file defines the Record class, which represents the input record from the data source 19 * (typically an event, but could be a record defining an Identity or other object). 20 * @name Record Class 21 */ 22 23 /** 24 * Constructs a new instance of a Record object. 25 * @class 26 * The Record class represents the next record (or partial record) in the inbound data 27 * stream from some event source. There are a number of attributes and methods defined for 28 * this class, but for the most part it is used as a general storage container for the data 29 * in the input record plus all strings parsed out of that data. 30 * <p> 31 * This constructor only sets pre-defined default attributes; in most cases you will use 32 * the Connector.read() method to fetch an actual populated record. In fact, the template 33 * will usually do this for you at the beginning of each loop. 34 * <p> 35 * The Connector will set various attributes in the Record object according to the input. 36 * Note that if there are multiple Connectors sending data to the Collector, they will all 37 * feed the same queue; you can determine which Connector sent you the data by the UUID or 38 * the connection mode. 39 * <p> 40 * Connectors in general operate in one of two modes which will affect what the received 41 * record looks like: 42 * <ul> 43 * <li>Buffer string mode: In this mode, the input from the event source is presented as a 44 * single string, which will be in <code>rec.s_RXBufferString</code>. If the event source produces complex 45 * data output, it may be pre-processed into NVP format. 46 * <li>Map mode: The input from the event source is placed into several variables, with names 47 * determined by the Connector. The DB Connector, for example, will return a variable for each 48 * column returned by the query. 49 * </ul> 50 * In addition to the <code>s_RXBufferString</code> and data map variables, there are also a number of additional 51 * defaults that most Connectors will set in the input map: 52 * <ul> 53 * <li><code>rec.CONNECTION_METHOD</code>: The type of Connector that delivered the data 54 * <li><code>rec.CONNECTION_MODE</code>: The connection mode in use by that Connector - this may affect the format 55 * of the data. 56 * <li><code>rec.i_RXBufferLength</code>: If s_RXBufferString is set, this is the length of that string. Can be used 57 * to determine if an empty record was retrieved. 58 * <li><code>rec.s_raw_message</code>: A copy of the raw message recieved. This is used by the signing feature. 59 * <li><code>rec.o</code>: Used as a status variable to indicate the state of the Connector. 60 * <li><code>rec.s_RV21</code>: The UUID of the Collector Manager that this Collector is running on. 61 * <li><code>rec.s_RV22</code>: The UUID of this Collector instance. 62 * <li><code>rec.s_RV23</code>: The UUID of the Connector delivering this data. 63 * <li><code>rec.s_RV24</code>: The UUID of the Event Source from which this data was captured. 64 * <li><code>rec.s_RV25</code>: A UUID assigned to this data record. 65 * </ul> 66 * For most of these variables, the template will handle processing them. You can use 67 * <code>rec.CONNECTION_METHOD</code> and <code>rec.CONNECTION_MODE</code> to select the appropriate parsing 68 * methods, and <code>rec.i_RXBufferLength</code> to check for error conditions. 69 * <p> 70 * @author Novell Engineering 71 * @version 6.1 72 * @constructor 73 */ 74 function Record() { 75 // Initial blank objects 76 var hashMap = new HashMap(); 77 /** 78 * Dummy connector data object to pass to fireEvent(); will be replaced when data is read in most cases 79 * @type ConnectorData 80 */ 81 this.connectorData = new ConnectorData(hashMap); 82 83 /** 84 * Empty object to hold field-based structured input 85 */ 86 this.RXMap={}; 87 88 /** 89 * Converts a Record object into another object. 90 * This method defaults to converting to an output Event, but can be used to convert 91 * input into other objects like Identities, Assets, Vulnerabilities, etc. 92 * <p>Example: 93 * <pre> 94 * // Usually the template will take care of conversion of your completely parsed record into 95 * // the output event. But in case you need to convert to some other type of object: 96 * rec.convert(outputID, instance.MAPS.Rec2ID); 97 * </pre> 98 * @param {Object} output The object that the Record will be converted into. 99 * @param {DataMap} map The map to be used for the conversion. 100 * @return {Boolean} Result of conversion attempt 101 * @see DataMap 102 */ 103 this.convert = function(output, map){ 104 if ( typeof map == 'undefined' || !(map instanceof DataMap)) { return false; } 105 if (map.preconvert) { 106 map.preconvert(this, output); 107 } else { 108 for (var src in map) { 109 if (typeof map[src] != "function") { 110 try { 111 eval("output[src] = this" + map[src]); // Need to handle multilevel attrs 112 if (output[src]) { 113 output[src] = String(output[src]); // coerce to String 114 } else { 115 delete output[src]; // Not sure why, but otherwise undefined is retained? 116 } 117 } catch (err) { /* do nothing */ } 118 } 119 120 } 121 } 122 return true; 123 }; 124 125 /** 126 * This method sends a generic unparsed event where minimal processing is performed. 127 * In general this method is used to report unrecognized or unsupported records received from the 128 * event source. Collectors are typically written to support the most common events received from a 129 * particular source; in many cases infrequent events or events caused by add-on modules are not 130 * parsed by the default Collector code. 131 * <p>Note that there are two template parameters which control unparsed events: 132 * <ul> 133 * <li>Report Unparsed Events: This turns on/off the reporting of unparsed (unsupported) events. 134 * <li>Unparsed Events Severity: The reported severity of unparsed events. 135 * </ul> 136 * <p>When developing a Collector, you will usually want to attempt to parse the input records, 137 * and then call this method of the attempt is unsuccessful. In fact, the original template code 138 * has an example of this: see the parse() method which calls this method and then returns false 139 * to halt processing of this record. 140 * @param {Event} e An Event object (optional) to use as the basis for the unparsed event. Will default to the global 'curEvt' object. 141 * @return {Boolean} Whether an event was set or not. 142 */ 143 this.sendUnsupported = function(e) { 144 var appid; 145 if (typeof e == "undefined" || !(e instanceof Event)) { 146 e = curEvt; 147 } 148 if (typeof instance.CONFIG.params.Report_Unsupp != 'undefined' && instance.CONFIG.params.Report_Unsupp == "yes" ) { 149 if (typeof instance.CONFIG.params.Unsupp_Severity != "undefined") { 150 e.Severity = instance.CONFIG.params.Unsupp_Severity; 151 } else { 152 e.Severity = 0; 153 } 154 if (typeof this.s_AppId != "undefined" && this.s_AppId != "") { // If we know the appid, inject it into the event name 155 appid = " " + this.s_AppId; 156 } else { 157 appid = ""; 158 } 159 if (instance.CONFIG.params.UseConnectorName) { // This is the Generic Collector, so use the Connector name 160 e.EventName = this.CONNECTION_METHOD + appid + " Event"; 161 } else { 162 e.EventName = instance.CONFIG.collectorScript + appid + " Event"; 163 } 164 if (this.CONNECTION_MODE == "map") { 165 if ( typeof this.s_Body != "undefined" && this.s_Body != "") { 166 e.Message = this.s_Body; 167 } else { 168 e.Message = String(rec.connectorData); 169 } 170 } else { 171 e.Message = this.s_RXBufferString; 172 } 173 e.send(instance.MAPS.UnsupEvt); 174 return true; 175 } 176 return false; 177 }; 178 } 179 180