// Search the cache for a message id, return it and remove it from the cache int v3MP::Cache::get_entry(int searchedID, bool local_request, struct Cache::Entry_T *res) { if ((!table) || (!res)) return SNMPv3_MP_ERROR; BEGIN_REENTRANT_CODE_BLOCK; for (int i=0; i < entries; i++) if ((table[i].msg_id == searchedID) && (table[i].local_request == local_request)) { res->msg_id = table[i].msg_id; res->req_id = table[i].req_id; res->local_request = table[i].local_request; res->sec_engine_id = table[i].sec_engine_id; res->sec_model = table[i].sec_model; res->sec_name = table[i].sec_name; res->sec_level = table[i].sec_level; res->context_engine_id = table[i].context_engine_id; res->context_name = table[i].context_name; res->sec_state_ref = table[i].sec_state_ref; res->error_code = table[i].error_code; LOG_BEGIN(loggerModuleName, INFO_LOG | 8); LOG("v3MP::Cache: Found entry (n) (msg id) (type)"); LOG(i); LOG(searchedID); LOG(local_request ? "local" : "remote"); LOG_END; entries--; if (entries > i) { table[i] = table[entries]; LOG_BEGIN(loggerModuleName, INFO_LOG | 10); LOG("v3MP::Cache: Moving entry (from) (to)"); LOG(entries); LOG(i); LOG_END; } return SNMPv3_MP_OK; } LOG_BEGIN(loggerModuleName, WARNING_LOG | 5); LOG("v3MP::Cache: Entry not found (msg id) (type)"); LOG(searchedID); LOG(local_request ? "local" : "remote"); LOG_END; return SNMPv3_MP_ERROR; }
// Remove the entry for the given address/port from the table. int v3MP::EngineIdTable::delete_entry(const OctetStr &host, int port) { if (!table) return SNMPv3_MP_NOT_INITIALIZED; int i, found = 0; BEGIN_REENTRANT_CODE_BLOCK; for (i = 0; i < entries; i++) if ((table[i].port == port) && (table[i].host == host)) { found=1; break; } if (!found) { LOG_BEGIN(loggerModuleName, WARNING_LOG | 4); LOG("v3MP::EngineIdTable: cannot remove nonexisting entry (host) (port)"); LOG(host.get_printable()); LOG(port); LOG_END; return SNMPv3_MP_ERROR; } /* i is the entry to remove */ if (i != entries - 1) table[i] = table[entries-1]; entries--; return SNMPv3_MP_OK; }
CSNMPMessage * CSNMPMessageQueue::AddEntry(unsigned long id, Snmp * snmp, SnmpSocket socket, const SnmpTarget &target, Pdu &pdu, unsigned char * rawPdu, size_t rawPduLen, const Address & address, snmp_callback callBack, void * callData) { if (snmp != m_snmpSession) { LOG_BEGIN(WARNING_LOG | 1); LOG("MsgQueue: WARNING: Adding message for other Snmp object."); LOG_END; } CSNMPMessage *newMsg = new CSNMPMessage(id, snmp, socket, target, pdu, rawPdu, rawPduLen, address, callBack, callData); lock(); /*---------------------------------------------------------*/ /* Insert entry at head of list, done automagically by the */ /* constructor function, so don't use the return value. */ /*---------------------------------------------------------*/ (void) new CSNMPMessageQueueElt(newMsg, m_head.GetNext(), &m_head); ++m_msgCount; unlock(); return newMsg; }
int CSNMPMessage::ResendMessage() { if (m_received) { // Don't bother to resend if we already have the response SetSendTime(); return SNMP_CLASS_SUCCESS; } LOG_BEGIN(DEBUG_LOG | 10); LOG("MsgQueue: Message (msg id) (req id) (info)"); #ifdef _SNMPv3 LOG(m_pdu.get_message_id()); #endif LOG(m_pdu.get_request_id()); LOG((m_target->get_retry() <= 0) ? "TIMEOUT" : "RESEND"); LOG_END; if (m_target->get_retry() <= 0) { // This message has timed out Callback(SNMP_CLASS_TIMEOUT); // perform callback with the error return SNMP_CLASS_TIMEOUT; } m_target->set_retry(m_target->get_retry() - 1); SetSendTime(); int status = send_snmp_request(m_socket, m_rawPdu, m_rawPduLen, *m_address); if (status != 0) return SNMP_CLASS_TL_FAILED; return SNMP_CLASS_SUCCESS; }
string const & SystemUserInfo::getgroupnamebygid(gid_t id) { map<uid_t, string>::iterator iter = mGrGidCache.lower_bound( id ); if( iter != mGrGidCache.end() && iter->first == id ) { return iter->second; } else { struct group grent, *result = NULL; memset( &grent, 0, sizeof(grent) ); int rc = findgroupbygid(id, &grent, mSysBuf.getBuffer(), mSysBuf.getBufSize(), &result); LOG_BEGIN( loggerModuleName, DEBUG_LOG | 0 ); LOG( "getgroupnamebygid(id): (rc)(grent.gr_name)" ); LOG(id); LOG(rc); LOG(to_string((void *)(grent.gr_name)).c_str()); LOG_END; if( ( 0 == rc ) && (grent.gr_name) ) { iter = mGrGidCache.insert( iter, make_pair( id, grent.gr_name ) ); mGrNameCache.insert( make_pair( grent.gr_name, id ) ); } else { iter = mGrGidCache.insert( iter, make_pair( id, emptyString ) ); } return iter->second; } }
// Get the engineID of the SNMP entity at the given host/port. int v3MP::EngineIdTable::get_entry(OctetStr &engine_id, const OctetStr &host, int port) const { if (!table) return SNMPv3_MP_NOT_INITIALIZED; BEGIN_REENTRANT_CODE_BLOCK_CONST; int i, found = 0; for (i = 0; i < entries; i++) if ((table[i].port == port) && (table[i].host == host)) { found=1; break; } if (!found) { LOG_BEGIN(loggerModuleName, INFO_LOG | 4); LOG("v3MP::EngineIdTable: Dont know engine id for (host) (port)"); LOG(host.get_printable()); LOG(port); LOG_END; return SNMPv3_MP_ERROR; } engine_id = table[i].engine_id; return SNMPv3_MP_OK; }
bool SslConnection::receive() { TRACE; int ret = SSL_read(m_sslHandle, m_buffer, m_bufferLength); if ( ret > 0 ) { LOG_BEGIN(Logger::INFO) LOG_PROP("Host", m_timedTcpConnection->getHost()) LOG_PROP("Port", m_timedTcpConnection->getPort()) LOG_PROP("Socket", m_timedTcpConnection->getSocket()) LOG_PROP("Bytes", ret) LOG_END("Received message from peer."); return m_message->buildMessage( (void*)m_buffer, (size_t)ret); } unsigned long sslErrNo = ERR_get_error(); if ( ret == 0 && (sslErrNo == SSL_ERROR_ZERO_RETURN || sslErrNo == SSL_ERROR_NONE) ) { LOG( Logger::INFO, "SSL connection has been closed, cannot read."); return false; } LOG (Logger::ERR, (getSslError("The shutdown was not successful. ") + "system error: " + std::string(strerror(errno))).c_str() ); return false; }
// Search the cache for a message id, return the error code and int v3MP::Cache::get_entry(int msg_id, bool local_request, int *error_code, struct SecurityStateReference **sec_state_ref) { if (!table) return SNMPv3_MP_ERROR; BEGIN_REENTRANT_CODE_BLOCK; for (int i=0; i < entries; i++) { if ((msg_id == table[i].msg_id) && (local_request == table[i].local_request)) { *error_code = table[i].error_code; *sec_state_ref = table[i].sec_state_ref; entries--; LOG_BEGIN(loggerModuleName, INFO_LOG | 8); LOG("v3MP::Cache: Found entry (n) (msg id) (type)"); LOG(i); LOG(msg_id); LOG(local_request ? "local" : "remote"); LOG_END; if (entries > i) { table[i] = table[entries]; LOG_BEGIN(loggerModuleName, INFO_LOG | 10); LOG("v3MP::Cache: Moving entry (from) (to)"); LOG(entries); LOG(i); LOG_END; } return SNMPv3_MP_OK; } } LOG_BEGIN(loggerModuleName, WARNING_LOG | 5); LOG("v3MP::Cache: Entry not found (msg id) (type)"); LOG(msg_id); LOG(local_request ? "local" : "remote"); LOG_END; return SNMPv3_MP_ERROR; }
A(const char *msg) : message(msg) { TRACE; LOG_BEGIN(Logger::DEBUG) LOG_PROP("message", message) LOG_SPROP(message) LOG_END("my member"); }
// Delete the entry with the given request ans message id from the cache. void v3MP::Cache::delete_entry(unsigned long req_id, int msg_id, bool local_request) { if (!table) return; BEGIN_REENTRANT_CODE_BLOCK; for (int i=0; i<entries; i++) if ((table[i].req_id == req_id) && (table[i].msg_id == msg_id) && (table[i].local_request == local_request)) { LOG_BEGIN(loggerModuleName, INFO_LOG | 8); LOG("v3MP::Cache: Delete unprocessed entry (n) (req id) (msg id) (type)"); LOG(i); LOG(req_id); LOG(msg_id); LOG(local_request ? "local" : "remote"); LOG_END; usm->delete_sec_state_reference(table[i].sec_state_ref); entries--; if (entries > i) { table[i] = table[entries]; LOG_BEGIN(loggerModuleName, INFO_LOG | 10); LOG("v3MP::Cache: Moving entry (from) (to)"); LOG(entries); LOG(i); LOG_END; } return; } LOG_BEGIN(loggerModuleName, INFO_LOG | 8); LOG("v3MP::Cache: Entry to delete not found (req id) (msg id) (type)"); LOG(req_id); LOG(msg_id); LOG(local_request ? "local" : "remote"); LOG_END; return; }
void testBasic() { TEST_HEADER; int ears(2); LOG_BEGIN(Logger::DEBUG) LOG_PROP("noses", 1) LOG_PROP("ears", ears) LOG_END("An avarege human"); }
// Construct engine id table v3MP::EngineIdTable::EngineIdTable(int initial_size) { if (initial_size < 1) initial_size = 10; if (!initialize_table(initial_size)) { LOG_BEGIN(loggerModuleName, ERROR_LOG | 0); LOG("v3MP::EngineIdTable: Error creating empty table."); LOG_END; } }
// Tests if the given buffer contains a SNMPv3-Message. bool v3MP::is_v3_msg(unsigned char *buffer, int length) { unsigned char type; long version; // get the type buffer = asn_parse_header(buffer, &length, &type); if (!buffer) { LOG_BEGIN(loggerModuleName, WARNING_LOG | 1); LOG("Testing for v3 message: Bad header"); LOG_END; return false; } if (type != ASN_SEQ_CON) { LOG_BEGIN(loggerModuleName, WARNING_LOG | 1); LOG("Testing for v3 message: Wrong auth header type"); LOG((int)type); LOG_END; return false; } // get the version buffer = asn_parse_int(buffer, &length, &type, &version); if (!buffer) { LOG_BEGIN(loggerModuleName, WARNING_LOG | 1); LOG("Testing for v3 message: Bad parse of version"); LOG_END; return 0; } return (version == SNMP_VERSION_3); }
void DataSourceStatgrab::report_sg_error(string const &who, string const &what) { sg_error_details err_det; char *errmsg = NULL; sg_error errc; if( SG_ERROR_NONE != ( errc = sg_get_error_details(&err_det) ) ) { LOG_BEGIN( loggerModuleName, ERROR_LOG | 1 ); LOG( string( string("report_sg_error(") + who + ", " + what + "): can't get error details - " + sg_str_error(errc) ).c_str() ); LOG_END; return; } if( NULL == sg_strperror(&errmsg, &err_det) ) { errc = sg_get_error(); LOG_BEGIN( loggerModuleName, ERROR_LOG | 1 ); LOG( string( string("report_sg_error(") + who + ", " + what + "): can't prepare error message - " + sg_str_error(errc) ).c_str() ); LOG_END; return; } LOG_BEGIN( loggerModuleName, ERROR_LOG | 1 ); if( errmsg ) { LOG( string( who + ": " + what + " - " + errmsg ).c_str() ); } else { LOG( string( who + ": " + what + " - " + sg_str_error( sg_get_error() ) + " - unknown details" ).c_str() ); } LOG_END; free( errmsg ); return; }
static void f() { TRACE_STATIC; LOG_STATIC(Logger::INFO, "From static function"); int a(4); std::string b("eer"); LOG_BEGIN(Logger::DEBUG) LOG_SPROP(a) LOG_SPROP(b) LOG_END_STATIC("Properties from a static function"); }
Agent::~Agent() { Snmp::socket_cleanup(); // Shut down socket subsystem for( vector<MibModule *>::size_type i = 0; i < mMibModules.size(); ++i ) { MibModule *modInfo = mMibModules[i]; if( !modInfo->UnregisterMibs( *mMib ) ) { LOG_BEGIN(loggerModuleName, ERROR_LOG | 1); LOG("Agent::~Agent(): mibs module unregistering failed at (index)"); LOG(i); LOG_END; } } delete mMib; mMib = 0; delete mReqList; mReqList = 0; delete mSnmp; mSnmp = 0; delete mVacm; mVacm = 0; delete mv3mp; mv3mp = 0; for( vector<MibModule *>::size_type i = 0; i < mMibModules.size(); ++i ) { MibModule *modInfo = mMibModules[i]; if( !modInfo->ShutdownModule() ) { LOG_BEGIN(loggerModuleName, ERROR_LOG | 1); LOG("Agent::~Agent(): mibs module shutdown failed at (index)"); LOG(i); LOG_END; } } }
// Remove all entries from the engine id table. int v3MP::EngineIdTable::reset() { if (!table) return SNMPv3_MP_NOT_INITIALIZED; LOG_BEGIN(loggerModuleName, INFO_LOG | 1); LOG("v3MP::EngineIdTable: Resetting table."); LOG_END; BEGIN_REENTRANT_CODE_BLOCK; entries = 0; return SNMPv3_MP_OK; }
void onMessageReady() { TRACE; LOG_BEGIN(Logger::INFO) LOG_PROP("message", m_buffer) LOG_PROP("host", m_connection->getHost()) LOG_PROP("port", m_connection->getPort()) LOG_END("Got message."); m_buffer.clear(); std::unique_lock<std::mutex> lock(m_flag.m_mutex); m_flag.m_isReady = true; m_flag.m_condition_variable.notify_one(); }
bool DataSourceStatgrab::ShutdownStatgrab() { if( SG_ERROR_NONE != sg_shutdown() ) { LOG_BEGIN(loggerModuleName, ERROR_LOG | 0); LOG("ShutdownDataSourceStatgrab(): sg_shutdown() failed"); LOG(sg_str_error(sg_get_error())); LOG(sg_get_error_arg()); LOG_END; return false; } return true; }
v3MP::Cache::Cache() { // init cache table = new struct Entry_T[5]; if (!table) { LOG_BEGIN(loggerModuleName, ERROR_LOG | 1); LOG("v3MP::Cache: could not create empty table."); LOG_END; max_entries = 0; } else max_entries = 5; entries = 0; }
int Agent::RefreshMibConfig() { for( vector<MibModule *>::size_type i = 0; i < mMibModules.size(); ++i ) { MibModule *modInfo = mMibModules[i]; if( !modInfo->RefreshConfig( *mMib ) ) { LOG_BEGIN(loggerModuleName, ERROR_LOG | 1); LOG("Agent::~Agent(): mibs module config refresh failed at (index)"); LOG(i); LOG_END; } } return 0; }
int CSNMPMessageQueue::DeleteEntry(const unsigned long uniqueId) { CSNMPMessageQueueElt *msgEltPtr = m_head.GetNext(); while (msgEltPtr){ if (msgEltPtr->TestId(uniqueId)) { delete msgEltPtr; m_msgCount--; LOG_BEGIN(DEBUG_LOG | 10); LOG("MsgQueue: Removed entry (req id)"); LOG(uniqueId); LOG_END; return SNMP_CLASS_SUCCESS; } msgEltPtr = msgEltPtr->GetNext(); } return SNMP_CLASS_INVALID_REQID; }
void Agent::Init() { mMib->add(new sysGroup( "Smart-SNMPd, Agent++ based snmpd version " SMART_SNMP_VERSION_STRING, SM_SMART_SNMPD_MIB "." SMART_SNMP_VERSION_STRING, 10 ) ); mMib->add(new snmpGroup()); mMib->add(new snmp_target_mib()); mMib->add(new snmp_notification_mib()); for( vector<MibModule *>::size_type i = 0; i < mMibModules.size(); ++i ) { MibModule *modInfo = mMibModules[i]; if( !modInfo->RegisterMibs( *mMib ) ) { LOG_BEGIN(loggerModuleName, ERROR_LOG | 1); LOG("Agent::~Agent(): mibs module registering failed at (index)"); LOG(i); LOG_END; } } UserInit(); #ifdef AGENTPP_USE_THREAD_POOL int numberOfJobThreads = Config::getInstance().getNumberOfJobThreads(); if( numberOfJobThreads > 0 ) { QueuedThreadPool *tp = new QueuedThreadPool(numberOfJobThreads); mMib->set_thread_pool(tp); tp->start(); } #endif mMib->init(); #ifdef AGENTPP_USE_THREAD_POOL if( numberOfJobThreads <= 0 ) { mMib->delete_thread_pool(); } #endif mReqList->set_snmp(mSnmp); VacmInit(); }
// Decode the given encoded string into the output buffer. void decodeString(const unsigned char* in, const int in_length, char* out) { char* out_ptr = out; const unsigned char* in_ptr = in; if ((in_length % 2) || (in_length < 0)) { LOG_BEGIN(WARNING_LOG | 3); LOG("decodeString: Illegal input length (len)"); LOG(in_length); LOG_END; *out = 0; return; } for (int i= in_length / 2; i > 0; i--) { *out_ptr = (*in_ptr++ & 0xF) << 4; *out_ptr++ |= (*in_ptr++ & 0xF); } *out_ptr = 0; // make sure it is null terminated }
gid_t SystemUserInfo::getgroupidbyname(string const &name) { map<string, gid_t>::iterator iter = mGrNameCache.lower_bound( name ); if( iter != mGrNameCache.end() && iter->first == name ) { return iter->second; } else { struct group grent, *result = NULL; memset( &grent, 0, sizeof(grent) ); int rc = findgroupbyname( name.c_str(), &grent, mSysBuf.getBuffer(), mSysBuf.getBufSize(), &result ); LOG_BEGIN( loggerModuleName, DEBUG_LOG | 0 ); LOG( "getgroupidbyname(name): (rc)(gid)" ); LOG(name.c_str()); LOG(rc); LOG(grent.gr_gid); LOG_END; if( 0 == rc ) { mGrGidCache.insert( make_pair( grent.gr_gid, name ) ); } else { grent.gr_gid = (uid_t)-1; } iter = mGrNameCache.insert( iter, make_pair( name, grent.gr_gid ) ); return grent.gr_gid; } }
uid_t SystemUserInfo::getuseridbyname(string const &name) { map<string, uid_t>::iterator iter = mPwNameCache.lower_bound( name ); if( iter != mPwNameCache.end() && iter->first == name ) { return iter->second; } else { struct passwd pwent, *result = NULL; memset( &pwent, 0, sizeof(pwent) ); int rc = finduserbyname( name.c_str(), &pwent, mSysBuf.getBuffer(), mSysBuf.getBufSize(), &result ); LOG_BEGIN( loggerModuleName, DEBUG_LOG | 0 ); LOG( "getuseridbyname(name): (rc)(uid)" ); LOG(name.c_str()); LOG(rc); LOG(pwent.pw_uid); LOG_END; if( 0 == rc ) { mPwUidCache.insert( make_pair( pwent.pw_uid, name ) ); } else { pwent.pw_uid = (uid_t)-1; } iter = mPwNameCache.insert( iter, make_pair( name, pwent.pw_uid ) ); return pwent.pw_uid; } }
// Do the complete process of encoding the given values into the buffer // ready to send to the target. int v3MP::snmp_build(struct snmp_pdu *pdu, unsigned char *packet, int *out_length, // maximum Bytes in packet const OctetStr &securityEngineID, const OctetStr &securityName, int securityModel, int securityLevel, const OctetStr &contextEngineID, const OctetStr &contextName) { Buffer<unsigned char> scopedPDU(MAX_SNMP_PACKET); unsigned char *scopedPDUPtr = scopedPDU.get_ptr(); unsigned char globalData[MAXLENGTH_GLOBALDATA]; int globalDataLength = MAXLENGTH_GLOBALDATA; int scopedPDULength, maxLen = *out_length; Buffer<unsigned char> buf(MAX_SNMP_PACKET); unsigned char *bufPtr = buf.get_ptr(); long bufLength = 0, rc; int msgID; int cachedErrorCode = SNMPv3_MP_OK; struct SecurityStateReference *securityStateReference = NULL; int isRequestMessage = 0; if ((pdu->command == GET_REQ_MSG) || (pdu->command == GETNEXT_REQ_MSG) || (pdu->command == SET_REQ_MSG) || (pdu->command == GETBULK_REQ_MSG) || (pdu->command == TRP_REQ_MSG) || (pdu->command == INFORM_REQ_MSG) || (pdu->command == TRP2_REQ_MSG)) isRequestMessage = 1; if (isRequestMessage) { if (securityEngineID.len() == 0) { // First Contact => use user noAuthNoPriv and USM securityLevel = SNMP_SECURITY_LEVEL_NOAUTH_NOPRIV; securityModel = SNMP_SECURITY_MODEL_USM; } cur_msg_id_lock.lock(); msgID = cur_msg_id; cur_msg_id++; if (cur_msg_id >= MAX_MPMSGID) cur_msg_id = 1; cur_msg_id_lock.unlock(); #ifdef INVALID_MSGID LOG_BEGIN(loggerModuleName, ERROR_LOG | 1); LOG("*** WARNING: Using constant MessageID! ***"); LOG_END; msgID = 0xdead; #endif if (securityEngineID.len() == 0) { // length==0 => SecurityLevel == noAuthNoPriv // => we do not send any management information // => delete VariableBinding clear_pdu(pdu); } } else { // it is a response => search for request debugprintf(3, "Looking up cache"); msgID = pdu->msgid; rc = cache.get_entry(msgID, CACHE_REMOTE_REQ, &cachedErrorCode, &securityStateReference); if (rc != SNMPv3_MP_OK) { debugprintf(0, "mp: Cache lookup error"); return SNMPv3_MP_MATCH_ERROR; } } LOG_BEGIN(loggerModuleName, DEBUG_LOG | 5); LOG("v3MP: Building message with (SecurityEngineID) (securityName) (securityLevel) (contextEngineID) (contextName)"); LOG(securityEngineID.get_printable()); LOG(securityName.get_printable()); LOG(securityLevel); LOG(contextEngineID.get_printable()); LOG(contextName.get_printable()); LOG_END; // encode vb in buf scopedPDUPtr = build_vb(pdu, scopedPDUPtr, &maxLen); if (!scopedPDUPtr) { LOG_BEGIN(loggerModuleName, WARNING_LOG | 1); LOG("v3MP: Error encoding vbs into buffer"); LOG_END; return SNMPv3_MP_BUILD_ERROR; } scopedPDULength = SAFE_INT_CAST(scopedPDUPtr - scopedPDU.get_ptr()); //build dataPDU in buf maxLen = *out_length; scopedPDUPtr = scopedPDU.get_ptr(); bufPtr = build_data_pdu(pdu, bufPtr, &maxLen, scopedPDUPtr, scopedPDULength); if (!bufPtr) { LOG_BEGIN(loggerModuleName, WARNING_LOG | 1); LOG("v3MP: Error encoding data pdu into buffer"); LOG_END; return SNMPv3_MP_BUILD_ERROR; } bufLength = SAFE_INT_CAST(bufPtr - buf.get_ptr()); // serialize scopedPDU maxLen = *out_length; scopedPDUPtr = asn1_build_scoped_pdu(scopedPDUPtr, &maxLen, contextEngineID.data(), contextEngineID.len(), contextName.data(), contextName.len(), buf.get_ptr(), bufLength); if (!scopedPDUPtr) { LOG_BEGIN(loggerModuleName, WARNING_LOG | 1); LOG("v3MP: Error encoding scoped pdu into buffer"); LOG_END; return SNMPv3_MP_BUILD_ERROR; } scopedPDULength = SAFE_INT_CAST(scopedPDUPtr - scopedPDU.get_ptr()); // build msgGlobalData unsigned char *globalDataPtr = (unsigned char *)&globalData; unsigned char msgFlags; switch (securityLevel) { case SNMP_SECURITY_LEVEL_NOAUTH_NOPRIV: { msgFlags = 0 ; break;} case SNMP_SECURITY_LEVEL_AUTH_NOPRIV: { msgFlags = SNMPv3_AUTHFLAG; break;} case SNMP_SECURITY_LEVEL_AUTH_PRIV: { msgFlags = SNMPv3_AUTHFLAG | SNMPv3_PRIVFLAG; break;} default: { LOG_BEGIN(loggerModuleName, WARNING_LOG | 1); LOG("v3MP: Unknown security level requested, will use authPriv"); LOG(securityLevel); LOG_END; msgFlags = SNMPv3_AUTHFLAG | SNMPv3_PRIVFLAG; } } if ((pdu->command == GET_REQ_MSG) || (pdu->command == GETNEXT_REQ_MSG) || (pdu->command == SET_REQ_MSG) || (pdu->command == GETBULK_REQ_MSG) || (pdu->command == INFORM_REQ_MSG)) msgFlags = msgFlags | SNMPv3_REPORTABLEFLAG; globalDataPtr = asn1_build_header_data(globalDataPtr, &globalDataLength, msgID, *out_length, // maxMessageSize msgFlags, securityModel); if (!globalDataPtr) { LOG_BEGIN(loggerModuleName, ERROR_LOG | 1); LOG("v3MP: Error building header data"); LOG_END; return SNMPv3_MP_BUILD_ERROR; } globalDataLength = SAFE_INT_CAST(globalDataPtr - (unsigned char *)&globalData); switch (securityModel) { case SNMP_SECURITY_MODEL_USM: { int use_own_engine_id = 0; if ((pdu->command == TRP_REQ_MSG) || (pdu->command == GET_RSP_MSG) || (pdu->command == REPORT_MSG) || (pdu->command == TRP2_REQ_MSG)) { use_own_engine_id = 1; } rc = usm->generate_msg(globalData, globalDataLength, *out_length, (use_own_engine_id ? own_engine_id_oct : securityEngineID), securityName, securityLevel, scopedPDU.get_ptr(), scopedPDULength, securityStateReference, packet, out_length); if ( rc == SNMPv3_USM_OK ) { // build cache if (!((pdu->command == TRP_REQ_MSG) || (pdu->command == GET_RSP_MSG) || (pdu->command == REPORT_MSG) || (pdu->command == TRP2_REQ_MSG))) cache.add_entry(msgID, pdu->reqid, securityEngineID, securityModel, securityName, securityLevel, contextEngineID, contextName, securityStateReference, SNMPv3_MP_OK, CACHE_LOCAL_REQ); LOG_BEGIN(loggerModuleName, INFO_LOG | 3); LOG("v3MP: Message built OK"); LOG_END; return SNMPv3_MP_OK; } else { LOG_BEGIN(loggerModuleName, WARNING_LOG | 1); LOG("v3MP: Returning error for building message"); LOG(rc); LOG_END; return rc; } } default: { LOG_BEGIN(loggerModuleName, WARNING_LOG | 1); LOG("v3MP: Should build message with unsupported securityModel"); LOG(securityModel); LOG_END; return SNMPv3_MP_UNSUPPORTED_SECURITY_MODEL; } } }
// Add an entry to the table. int v3MP::EngineIdTable::add_entry(const OctetStr &engine_id, const OctetStr &host, int port) { if (!table) return SNMPv3_MP_NOT_INITIALIZED; LOG_BEGIN(loggerModuleName, INFO_LOG | 9); LOG("v3MP::EngineIdTable: adding new entry (id) (host) (port)"); LOG(engine_id.get_printable()); LOG(host.get_printable()); LOG(port); LOG_END; BEGIN_REENTRANT_CODE_BLOCK; for (int i = 0; i < entries; i++) if (((table[i].port == port) && (table[i].host == host)) || (table[i].engine_id == engine_id)) { LOG_BEGIN(loggerModuleName, INFO_LOG | 2); LOG("v3MP::EngineIdTable: replace entry (old id) (old host) (old port) (id) (host) (port)"); LOG(table[i].engine_id.get_printable()); LOG(table[i].host.get_printable()); LOG(table[i].port); LOG(engine_id.get_printable()); LOG(host.get_printable()); LOG(port); LOG_END; table[i].engine_id = engine_id; table[i].host = host; table[i].port = port; return SNMPv3_MP_OK; // host is in table } table[entries].engine_id = engine_id; table[entries].host = host; table[entries].port = port; entries++; if (entries == max_entries) { // resize Table struct Entry_T *tmp; tmp = new struct Entry_T[2 * max_entries]; if (!tmp) { entries--; return SNMPv3_MP_ERROR; } for (int i = 0; i < entries; i++) tmp[i] = table[i]; delete [] table; table = tmp; max_entries *= 2; } return SNMPv3_MP_OK; }
// Add an entry to the cache. int v3MP::Cache::add_entry(int msg_id, unsigned long req_id, const OctetStr &sec_engine_id, int sec_model, const OctetStr &sec_name, int sec_level, const OctetStr &context_engine_id, const OctetStr &context_name, struct SecurityStateReference *sec_state_ref, int error_code, bool local_request) { if (!table) return SNMPv3_MP_ERROR; LOG_BEGIN(loggerModuleName, INFO_LOG | 8); LOG("v3MP::Cache: adding new entry (n) (msg id) (req id) (type)"); LOG(entries); LOG(msg_id); LOG(req_id); LOG(local_request ? "local" : "remote"); LOG_END; BEGIN_REENTRANT_CODE_BLOCK; for (int i = 0; i < entries; i++) if ((table[i].msg_id == msg_id) && (table[i].req_id == req_id) && (table[i].local_request == local_request) && (table[i].sec_engine_id == sec_engine_id) && (table[i].sec_model == sec_model) && (table[i].sec_name == sec_name) && (table[i].sec_level == sec_level) && (table[i].context_engine_id == context_engine_id) && (table[i].context_name == context_name)) { LOG_BEGIN(loggerModuleName, WARNING_LOG | 3); LOG("v3MP::Cache: Dont add doubled entry (msg id) (req id)"); LOG(msg_id); LOG(req_id); LOG_END; return SNMPv3_MP_DOUBLED_MESSAGE; } table[entries].msg_id = msg_id; table[entries].req_id = req_id; table[entries].local_request = local_request; table[entries].sec_engine_id = sec_engine_id; table[entries].sec_model = sec_model; table[entries].sec_name = sec_name; table[entries].sec_level = sec_level; table[entries].context_engine_id = context_engine_id; table[entries].context_name = context_name; table[entries].sec_state_ref = sec_state_ref; table[entries].error_code = error_code; entries++; if (entries == max_entries) { // resize Table struct Entry_T *tmp; tmp = new struct Entry_T[2 * max_entries]; if (!tmp) { entries--; return SNMPv3_MP_ERROR; } for (int i=0; i<entries;i++) tmp[i] = table[i]; delete [] table; table = tmp; max_entries *= 2; } return SNMPv3_MP_OK; }
bool DataSourceExternalCommand::updateMibObj() { ExternalCommand *cmd; MibObjectConfig const mibCfg = mMibObj->getConfig(); LOG_BEGIN( loggerModuleName, DEBUG_LOG | 1 ); LOG("DataSourceExternalCommand::updateMibObj(): (commandline)"); LOG( mCommandLine.c_str() ); LOG_END; ThreadSynchronize guard(*this); if( !mibCfg.ExternalCommand.User.empty() ) cmd = new ExternalCommandAsUser(mibCfg.ExternalCommand); else cmd = new ExternalCommand(mibCfg.ExternalCommand); MibObject::ContentManagerType &cntMgr = mMibObj->beginContentUpdate(); cntMgr.clear(); ExtCmdMib smExtCmdMib( cntMgr ); smExtCmdMib.setLastStartedTimestamp( time(NULL) ); smExtCmdMib.setCommandConfig( mibCfg.ExternalCommand.Executable, mCommandLine, mibCfg.ExternalCommand.User ); int comp_rc; if( ( comp_rc = cmd->start() ) != 0 ) { #if 0 mMibObj->set_value( mLastExitCodeOid, SnmpInt32(-1) ); mMibObj->set_value( mLastSignalCodeOid, SnmpInt32(-1) ); mMibObj->set_value( mLastErrorCodeOid, SnmpInt32(comp_rc) ); #else smExtCmdMib.setLastExecutionErrorCode( comp_rc ); #endif LOG_BEGIN( loggerModuleName, ERROR_LOG | 1 ); LOG( "DataSourceExternalCommand::updateMibObj(): (command line) failed to start with (error)" ); LOG( mCommandLine.c_str() ); LOG( comp_rc ); LOG_END; delete cmd; // copy last updated timestamp because it's lost otherwise after commit smExtCmdMib.setUpdateTimestamp( mMibObj->GetLastUpdate() ); mMibObj->commitContentUpdate(); return false; } LOG_BEGIN( loggerModuleName, DEBUG_LOG | 5 ); LOG( "DataSourceExternalCommand::updateMibObj(): (command line) started with (pid)" ); LOG( mCommandLine.c_str() ); LOG( cmd->getChildPid() ); LOG_END; while( cmd->poll(5) ) (void)0; /* nop() */ cmd->finish(); #if 0 rc = mMibObj->set_value( mLastFinishedTimestampOid, Counter64( time(NULL) ) ); status &= rc; rc = mMibObj->set_value( mLastExitCodeOid, SnmpInt32( cmd->getExitCode() ) ); status &= rc; rc = mMibObj->set_value( mLastSignalCodeOid, SnmpInt32( cmd->getExitSignal() ) ); status &= rc; rc = mMibObj->set_value( mLastErrorMessageOid, OctetStr( cmd->getErrBuf().c_str() ) ); status &= rc; #else smExtCmdMib.setLastExecutionState( cmd->getExitCode(), cmd->getExitSignal(), cmd->getErrBuf(), time(NULL) ); #endif LOG_BEGIN( loggerModuleName, DEBUG_LOG | 1 ); LOG( "DataSourceExternalCommand::updateMibObj(): (command line) finished with (exit code) (exit signal)" ); LOG( mCommandLine.c_str() ); LOG( cmd->getExitCode() ); LOG( cmd->getExitSignal() ); LOG_END; if( cmd->getExitCode() != 0 ) { delete cmd; // copy last updated timestamp because it's lost otherwise after commit smExtCmdMib.setUpdateTimestamp( mMibObj->GetLastUpdate() ); mMibObj->commitContentUpdate(); return false; } ParseExternalJson pej; pej.reserve(mExpectedEntryCount); if( 0 == ( comp_rc = pej.parse( cmd->getOutBuf() ) ) ) { LOG_BEGIN(loggerModuleName, DEBUG_LOG | 1 ); LOG( "DataSourceExternalCommand::updateMibObj(): json output successful parsed" ); LOG_END; smExtCmdMib.setLastErrorCode( 0 ); } else { LOG_BEGIN(loggerModuleName, ERROR_LOG | 3 ); LOG( "DataSourceExternalCommand::updateMibObj(): error parsing json output" ); LOG_END; smExtCmdMib.setLastErrorCode( comp_rc ); // copy last updated timestamp because it's lost otherwise after commit smExtCmdMib.setUpdateTimestamp( mMibObj->GetLastUpdate() ); mMibObj->commitContentUpdate(); delete cmd; return false; } delete cmd; vector<ExternalDataTuple> const &data = pej.getData(); mExpectedEntryCount = data.size(); #if 0 MibStaticTable *extContent = new MibStaticTable( mExternalDataOid ); for( vector<ExternalDataTuple>::const_iterator iter = data.begin(); iter != data.end(); ++iter ) { const ExternalDataTuple &edt = *iter; extContent->add( MibStaticEntry( Vbx( edt.Oid, *edt.Datum ) ) ); } rc = mMibObj->set_value( extContent ); status &= rc; rc = mMibObj->set_value( mLastUpdateTimestampOid, Counter64( time(NULL) ) ); status &= rc; #else smExtCmdMib.setCommandResult( data ); smExtCmdMib.setUpdateTimestamp( time(NULL) ); mMibObj->commitContentUpdate(); #endif return true; }