Exemplo n.º 1
0
static struct scache_entry *
find_or_add(const char *name)
{
	int hash_index;
	struct scache_entry *ptr;

	ptr = scache_hash[hash_index = sc_hash(name)];
	for (; ptr; ptr = ptr->next)
	{
		if(!irccmp(ptr->name, name))
			return ptr;
	}

	ptr = (struct scache_entry *) rb_malloc(sizeof(struct scache_entry));
	s_assert(0 != ptr);

	rb_strlcpy(ptr->name, name, sizeof(ptr->name));
	ptr->info[0] = '\0';
	ptr->flags = 0;
	ptr->known_since = rb_current_time();
	ptr->last_connect = 0;
	ptr->last_split = 0;

	ptr->next = scache_hash[hash_index];
	scache_hash[hash_index] = ptr;
	return ptr;
}
Exemplo n.º 2
0
/*******************************************************************-o-******
 * hash_engineID
 *
 * Parameters:
 *    *engineID
 *     engineID_len
 *      
 * Returns:
 *    >0            etimelist index for this engineID.
 *    SNMPERR_GENERR        Error.
 *    
 * 
 * Use a cheap hash to build an index into the etimelist.  Method is 
 * to hash the engineID, then split the hash into u_int's and add them up
 * and modulo the size of the list.
 *
 */
int hash_engineID (const u_char * engineID, u_int engineID_len)
{
    int rval = SNMPERR_GENERR;

    size_t buf_len = SNMP_MAXBUF;

    u_int additive = 0;

    u_char *bufp, buf[SNMP_MAXBUF];

    void *context = NULL;



    /*
     * Sanity check.
     */
    if (!engineID || (engineID_len <= 0))
    {
        QUITFUN (SNMPERR_GENERR, hash_engineID_quit);
    }


    /*
     * Hash engineID into a list index.
     */
#ifndef NETSNMP_DISABLE_MD5
    rval = sc_hash (usmHMACMD5AuthProtocol,
                    sizeof (usmHMACMD5AuthProtocol) / sizeof (oid), engineID, engineID_len, buf, &buf_len);
#else
    rval = sc_hash (usmHMACSHA1AuthProtocol,
                    sizeof (usmHMACSHA1AuthProtocol) / sizeof (oid), engineID, engineID_len, buf, &buf_len);
#endif
    QUITFUN (rval, hash_engineID_quit);

    for (bufp = buf; (bufp - buf) < (int) buf_len; bufp += 4)
    {
        additive += (u_int) * bufp;
    }

  hash_engineID_quit:
    SNMP_FREE (context);
    memset (buf, 0, SNMP_MAXBUF);

    return (rval < 0) ? rval : (int) (additive % ETIMELIST_SIZE);

}                                /* end hash_engineID() */
Exemplo n.º 3
0
const char *
find_or_add(const char *name)
{
	int hash_index;
	SCACHE *ptr;

	ptr = scache_hash[hash_index = sc_hash(name)];
	for (; ptr; ptr = ptr->next)
	{
		if(!irccmp(ptr->name, name))
			return (ptr->name);
	}

	ptr = (SCACHE *) MyMalloc(sizeof(SCACHE));
	s_assert(0 != ptr);

	strlcpy(ptr->name, name, sizeof(ptr->name));

	ptr->next = scache_hash[hash_index];
	scache_hash[hash_index] = ptr;
	return ptr->name;
}
Exemplo n.º 4
0
_KEYTOOLS_NOT_AVAILABLE
#endif						/* internal or openssl */




/*******************************************************************-o-******
 * decode_keychange
 *
 * Parameters:
 *	*hashtype	MIB OID of the hash transform to use.
 *	 hashtype_len	Length of the hash transform MIB OID.
 *	*oldkey		Old key that is used to encode the new key.
 *	 oldkey_len	Length of oldkey in bytes.
 *	*kcstring	Encoded KeyString buffer containing the new key.
 *	 kcstring_len	Length of kcstring in bytes.
 *	*newkey		Buffer to hold the extracted new key.
 *	*newkey_len	Length of newkey in bytes.
 *
 * Returns:
 *	SNMPERR_SUCCESS			Success.
 *	SNMPERR_GENERR			All errors.
 *
 *
 * Decodes a string of bits encoded according to the KeyChange TC described
 * in RFC 2274, Section 5.  The new key is extracted from *kcstring with
 * the aid of the old key.
 *
 * Upon successful return, *newkey_len contains the length of the new key.
 *
 *
 * ASSUMES	Old key is exactly 1/2 the length of the KeyChange buffer,
 *		although this length may be less than the hash transform
 *		output.  Thus the new key length will be equal to the old
 *		key length.
 */

/* XXX:  if the newkey is not long enough, it should be freed and remalloced */
int
decode_keychange(	oid	*hashtype,	u_int  hashtype_len,
                    u_char	*oldkey,	size_t  oldkey_len,
                    u_char	*kcstring,	size_t  kcstring_len,
                    u_char	*newkey,	size_t *newkey_len)
#if defined(USE_OPENSSL) || defined(USE_INTERNAL_MD5)
{
    int		 rval    = SNMPERR_SUCCESS;
    size_t		 properlength = 0;
    u_int		 nbytes  = 0;

    u_char		*bufp,
                tmp_buf[SNMP_MAXBUF];
    size_t           tmp_buf_len = SNMP_MAXBUF;
    void		*context = NULL;
    u_char          *tmpbuf = NULL;



    /*
     * Sanity check.
     */
    if ( !hashtype || !oldkey || !kcstring || !newkey || !newkey_len
            || (oldkey_len<=0) || (kcstring_len<=0) || (*newkey_len<=0)
            || (hashtype_len != USM_LENGTH_OID_TRANSFORM) )
    {
        QUITFUN(SNMPERR_GENERR, decode_keychange_quit);
    }


    /*
     * Setup for the transform type.
     */
    properlength = sc_get_properlength(hashtype, hashtype_len);
    if (properlength == SNMPERR_GENERR)
        QUITFUN(SNMPERR_GENERR, decode_keychange_quit);


    if ( ((oldkey_len*2) != kcstring_len) || (*newkey_len < oldkey_len) )
    {
        QUITFUN(SNMPERR_GENERR, decode_keychange_quit);
    }

    properlength = oldkey_len;
    *newkey_len = properlength;

    /*
     * Use the old key and the given KeyChange TC string to recover
     * the new key:
     *	. Hash (oldkey | random_bytes) (into newkey),
     *	. XOR hash and encoded (second) half of kcstring (into newkey).
     */
    tmpbuf = (u_char *)malloc(properlength*2);
    if (tmpbuf) {
        memcpy(tmpbuf, oldkey, properlength);
        memcpy(tmpbuf+properlength, kcstring, properlength);

        rval = sc_hash(hashtype, hashtype_len, tmpbuf, properlength*2,
                       tmp_buf, &tmp_buf_len);
        QUITFUN(rval, decode_keychange_quit);

        memcpy(newkey, tmp_buf, properlength);
        bufp   = kcstring+properlength;
        nbytes = 0;
        while ((int)(nbytes++) < properlength) {
            *newkey++ = *newkey ^ *bufp++;
        }
    }

decode_keychange_quit:
    if (rval != SNMPERR_SUCCESS) {
        memset(newkey, 0, properlength);
    }
    memset(tmp_buf, 0, SNMP_MAXBUF);
    SNMP_FREE(context);
    if (tmpbuf != NULL) SNMP_FREE(tmpbuf);

    return rval;

}  /* end decode_keychange() */
Exemplo n.º 5
0
_KEYTOOLS_NOT_AVAILABLE
#endif						/* internal or openssl */




/*******************************************************************-o-******
 * encode_keychange
 *
 * Parameters:
 *	*hashtype	MIB OID for the hash transform type.
 *	 hashtype_len	Length of the MIB OID hash transform type.
 *	*oldkey		Old key that is used to encodes the new key.
 *	 oldkey_len	Length of oldkey in bytes.
 *	*newkey		New key that is encoded using the old key.
 *	 newkey_len	Length of new key in bytes.
 *	*kcstring	Buffer to contain the KeyChange TC string.
 *	*kcstring_len	Length of kcstring buffer.
 *
 * Returns:
 *	SNMPERR_SUCCESS			Success.
 *	SNMPERR_GENERR			All errors.
 *
 *
 * Uses oldkey and acquired random bytes to encode newkey into kcstring
 * according to the rules of the KeyChange TC described in RFC 2274, Section 5.
 *
 * Upon successful return, *kcstring_len contains the length of the
 * encoded string.
 *
 * ASSUMES	Old and new key are always equal to each other, although
 *		this may be less than the transform type hash output
 * 		output length (eg, using KeyChange for a DESPriv key when
 *		the user also uses SHA1Auth).  This also implies that the
 *		hash placed in the second 1/2 of the key change string
 *		will be truncated before the XOR'ing when the hash output is
 *		larger than that 1/2 of the key change string.
 *
 *		*kcstring_len will be returned as exactly twice that same
 *		length though the input buffer may be larger.
 *
 * XXX FIX:     Does not handle varibable length keys.
 * XXX FIX:     Does not handle keys larger than the hash algorithm used.
 */
int
encode_keychange(	oid	*hashtype,	u_int  hashtype_len,
                    u_char	*oldkey,	size_t  oldkey_len,
                    u_char	*newkey,	size_t  newkey_len,
                    u_char	*kcstring,	size_t *kcstring_len)
#if defined(USE_OPENSSL) || defined(USE_INTERNAL_MD5)
{
    int		 rval    = SNMPERR_SUCCESS;
    size_t		 properlength;
    size_t            nbytes  = 0;

    u_char          *tmpbuf = NULL;
    void		*context = NULL;


    /*
     * Sanity check.
     */
    if ( !hashtype || !oldkey || !newkey || !kcstring || !kcstring_len
            || (oldkey_len<=0) || (newkey_len<=0) || (*kcstring_len<=0)
            || (hashtype_len != USM_LENGTH_OID_TRANSFORM) )
    {
        QUITFUN(SNMPERR_GENERR, encode_keychange_quit);
    }

    /*
     * Setup for the transform type.
     */
    properlength = sc_get_properlength(hashtype, hashtype_len);
    if (properlength == SNMPERR_GENERR)
        QUITFUN(SNMPERR_GENERR, encode_keychange_quit);

    if ( (oldkey_len != newkey_len) || (*kcstring_len < (2*oldkey_len)) )
    {
        QUITFUN(SNMPERR_GENERR, encode_keychange_quit);
    }

    properlength = SNMP_MIN((int)oldkey_len, properlength);

    /*
     * Use the old key and some random bytes to encode the new key
     * in the KeyChange TC format:
     *	. Get random bytes (store in first half of kcstring),
     *	. Hash (oldkey | random_bytes) (into second half of kcstring),
     *	. XOR hash and newkey (into second half of kcstring).
     *
     * Getting the wrong number of random bytes is considered an error.
     */
    nbytes = properlength;

#if defined(SNMP_TESTING_CODE) && defined(RANDOMZEROS)
    memset(kcstring, 0, nbytes);
    DEBUGMSG(("encode_keychange",
              "** Using all zero bits for \"random\" delta of )"
              "the keychange string! **\n"));
#else /* !SNMP_TESTING_CODE */
    rval = sc_random(kcstring, &nbytes);
    QUITFUN(rval, encode_keychange_quit);
    if ((int)nbytes != properlength) {
        QUITFUN(SNMPERR_GENERR, encode_keychange_quit);
    }
#endif /* !SNMP_TESTING_CODE */

    tmpbuf = (u_char *)malloc(properlength*2);
    if (tmpbuf) {
        memcpy(tmpbuf, oldkey, properlength);
        memcpy(tmpbuf+properlength, kcstring, properlength);

        *kcstring_len -= properlength;
        rval = sc_hash(hashtype, hashtype_len, tmpbuf, properlength*2,
                       kcstring+properlength, kcstring_len);

        QUITFUN(rval, encode_keychange_quit);

        *kcstring_len = (properlength*2);

        kcstring += properlength;
        nbytes    = 0;
        while ((int)(nbytes++) < properlength) {
            *kcstring++ = *kcstring ^ *newkey++;
        }
    }

encode_keychange_quit:
    if (rval != SNMPERR_SUCCESS) memset(kcstring, 0, *kcstring_len);
    SNMP_FREE(tmpbuf);
    SNMP_FREE(context);

    return rval;

}  /* end encode_keychange() */
Exemplo n.º 6
0
_KEYTOOLS_NOT_AVAILABLE
#endif						/* internal or openssl */




/*******************************************************************-o-******
 * generate_kul
 *
 * Parameters:
 *	*hashtype
 *	 hashtype_len
 *	*engineID
 *	 engineID_len
 *	*Ku		Master key for a given user.
 *	 ku_len		Length of Ku in bytes.
 *	*Kul		Localized key for a given user at engineID.
 *	*kul_len	Length of Kul buffer (IN); Length of Kul key (OUT).
 *
 * Returns:
 *	SNMPERR_SUCCESS			Success.
 *	SNMPERR_GENERR			All errors.
 *
 *
 * Ku MUST be the proper length (currently fixed) for the given hashtype.
 *
 * Upon successful return, Kul contains the localized form of Ku at
 * engineID, and the length of the key is stored in kul_len.
 *
 * The localized key method is defined in RFC2274, Sections 2.6 and A.2, and
 * originally documented in:
 *  	U. Blumenthal, N. C. Hien, B. Wijnen,
 *     	"Key Derivation for Network Management Applications",
 *	IEEE Network Magazine, April/May issue, 1997.
 *
 *
 * ASSUMES  SNMP_MAXBUF >= sizeof(Ku + engineID + Ku).
 *
 * NOTE  Localized keys for privacy transforms are generated via
 *	 the authentication transform held by the same usmUser.
 *
 * XXX	An engineID of any length is accepted, even if larger than
 *	what is spec'ed for the textual convention.
 */
int
generate_kul(	oid	*hashtype,	u_int  hashtype_len,
                u_char	*engineID,	size_t  engineID_len,
                u_char	*Ku,		size_t  ku_len,
                u_char	*Kul,		size_t *kul_len)
#if defined(USE_OPENSSL) || defined(USE_INTERNAL_MD5)
{
    int		 rval    = SNMPERR_SUCCESS;
    u_int		 nbytes  = 0;
    size_t           properlength;

    u_char		 buf[SNMP_MAXBUF];
    void		*context = NULL;
#ifdef SNMP_TESTING_CODE
    int		 i;
#endif


    /*
     * Sanity check.
     */
    if ( !hashtype || !engineID || !Ku || !Kul || !kul_len
            || (engineID_len<=0) || (ku_len<=0) || (*kul_len<=0)
            || (hashtype_len != USM_LENGTH_OID_TRANSFORM) )
    {
        QUITFUN(SNMPERR_GENERR, generate_kul_quit);
    }


    properlength = sc_get_properlength(hashtype, hashtype_len);
    if (properlength == SNMPERR_GENERR)
        QUITFUN(SNMPERR_GENERR, generate_kul_quit);


    if (((int)*kul_len < properlength) || ((int)ku_len < properlength) ) {
        QUITFUN(SNMPERR_GENERR, generate_kul_quit);
    }

    /*
     * Concatenate Ku and engineID properly, then hash the result.
     * Store it in Kul.
     */
    nbytes = 0;
    memcpy(buf,	   Ku,		properlength);
    nbytes += properlength;
    memcpy(buf+nbytes, engineID,	engineID_len);
    nbytes += engineID_len;
    memcpy(buf+nbytes, Ku,		properlength);
    nbytes += properlength;

    rval = sc_hash(hashtype, hashtype_len, buf, nbytes, Kul, kul_len);

#ifdef SNMP_TESTING_CODE
    DEBUGMSGTL(("generate_kul", "generating Kul (from Ku): "));
    for(i=0; i < *kul_len; i++)
        DEBUGMSG(("generate_kul", "%02x",Kul[i]));
    DEBUGMSG(("generate_kul", "keytools\n"));
#endif /* SNMP_TESTING_CODE */

    QUITFUN(rval, generate_kul_quit);


generate_kul_quit:
    SNMP_FREE(context);
    return rval;

}  /* end generate_kul() */