Exemplo n.º 1
0
// 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;
}
Exemplo n.º 2
0
// 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;
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
0
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;
}
Exemplo n.º 5
0
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;
    }
}
Exemplo n.º 6
0
// 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;
}
Exemplo n.º 7
0
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;
}
Exemplo n.º 8
0
// 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;
}
Exemplo n.º 9
0
        A(const char *msg) : message(msg)
        {
            TRACE;

            LOG_BEGIN(Logger::DEBUG)
            LOG_PROP("message", message)
            LOG_SPROP(message)
            LOG_END("my member");
        }
Exemplo n.º 10
0
// 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;
}
Exemplo n.º 11
0
    void testBasic()
    {
        TEST_HEADER;

        int ears(2);

        LOG_BEGIN(Logger::DEBUG)
        LOG_PROP("noses", 1)
        LOG_PROP("ears", ears)
        LOG_END("An avarege human");
    }
Exemplo n.º 12
0
// 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;
  }
}
Exemplo n.º 13
0
// 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);
}
Exemplo n.º 14
0
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;
}
Exemplo n.º 15
0
    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");
    }
Exemplo n.º 16
0
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;
        }
    }
}
Exemplo n.º 17
0
// 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;
}
Exemplo n.º 18
0
  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();
  }
Exemplo n.º 19
0
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;
}
Exemplo n.º 20
0
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;
}
Exemplo n.º 21
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;
}
Exemplo n.º 22
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;
}
Exemplo n.º 23
0
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();
}
Exemplo n.º 24
0
// 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
}
Exemplo n.º 25
0
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;
    }
}
Exemplo n.º 26
0
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;
    }
}
Exemplo n.º 27
0
// 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;
    }
  }
}
Exemplo n.º 28
0
// 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;
}
Exemplo n.º 29
0
// 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;
}
Exemplo n.º 30
0
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;
}