Changeset 1719464


Ignore:
Timestamp:
2006-06-28T14:47:05Z (18 years ago)
Author:
Wilmer van der Gaast <wilmer@…>
Branches:
master
Children:
5c9512f
Parents:
b3c467b
Message:

Added random_bytes() function for better/more reliable randomization and
moved set_eval_ops() to a slightly more suitable place.

Files:
6 edited

Legend:

Unmodified
Added
Removed
  • lib/misc.c

    rb3c467b r1719464  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2004 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2006 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    1111 * Copyright (C) 1998-1999, Mark Spencer <markster@marko.net>
    1212 *                          (and possibly other members of the Gaim team)
    13  * Copyright 2002-2005 Wilmer van der Gaast <wilmer@gaast.net>
     13 * Copyright 2002-2006 Wilmer van der Gaast <wilmer@gaast.net>
    1414 */
    1515
     
    422422}
    423423
    424 char *set_eval_charset( irc_t *irc, set_t *set, char *value )
    425 {
    426         GIConv cd;
    427 
    428         if ( g_strncasecmp( value, "none", 4 ) == 0 )
    429                 return( value );
    430 
    431         cd = g_iconv_open( "UTF-8", value );
    432         if( cd == (GIConv) -1 )
    433                 return( NULL );
    434 
    435         g_iconv_close( cd );
    436         return( value );
    437 }
     424/* A pretty reliable random number generator. Tries to use the /dev/random
     425   devices first, and falls back to the random number generator from libc
     426   when it fails. Opens randomizer devices with O_NONBLOCK to make sure a
     427   lack of entropy won't halt BitlBee. */
     428void random_bytes( unsigned char *buf, int count )
     429{
     430        static int use_dev = -1;
     431       
     432        /* Actually this probing code isn't really necessary, is it? */
     433        if( use_dev == -1 )
     434        {
     435                if( access( "/dev/random", R_OK ) == 0 || access( "/dev/urandom", R_OK ) == 0 )
     436                        use_dev = 1;
     437                else
     438                {
     439                        use_dev = 0;
     440                        srand( ( getpid() << 16 ) ^ time( NULL ) );
     441                }
     442        }
     443       
     444        if( use_dev )
     445        {
     446                int fd;
     447               
     448                /* At least on Linux, /dev/random can block if there's not
     449                   enough entropy. We really don't want that, so if it can't
     450                   give anything, use /dev/urandom instead. */
     451                if( ( fd = open( "/dev/random", O_RDONLY | O_NONBLOCK ) ) >= 0 )
     452                        if( read( fd, buf, count ) == count )
     453                        {
     454                                close( fd );
     455                                return;
     456                        }
     457                close( fd );
     458               
     459                /* urandom isn't supposed to block at all, but just to be
     460                   sure. If it blocks, we'll disable use_dev and use the libc
     461                   randomizer instead. */
     462                if( ( fd = open( "/dev/urandom", O_RDONLY | O_NONBLOCK ) ) >= 0 )
     463                        if( read( fd, buf, count ) == count )
     464                        {
     465                                close( fd );
     466                                return;
     467                        }
     468                close( fd );
     469               
     470                /* If /dev/random blocks once, we'll still try to use it
     471                   again next time. If /dev/urandom also fails for some
     472                   reason, stick with libc during this session. */
     473               
     474                use_dev = 0;
     475                srand( ( getpid() << 16 ) ^ time( NULL ) );
     476        }
     477       
     478        if( !use_dev )
     479        {
     480                int i;
     481               
     482                /* Possibly the LSB of rand() isn't very random on some
     483                   platforms. Seems okay on at least Linux and OSX though. */
     484                for( i = 0; i < count; i ++ )
     485                        buf[i] = rand() & 0xff;
     486        }
     487}
  • lib/misc.h

    rb3c467b r1719464  
    2424*/
    2525
    26 #ifndef _UTIL_H
    27 #define _UTIL_H
     26#ifndef _MISC_H
     27#define _MISC_H
     28
     29#include <gmodule.h>
     30#include <time.h>
    2831
    2932G_MODULE_EXPORT void strip_linefeed( gchar *text );
     
    4548
    4649G_MODULE_EXPORT signed int do_iconv( char *from_cs, char *to_cs, char *src, char *dst, size_t size, size_t maxbuf );
    47 char *set_eval_charset( irc_t *irc, set_t *set, char *value );
     50
     51G_MODULE_EXPORT void random_bytes( unsigned char *buf, int count );
    4852
    4953#endif
  • lib/rc4.c

    rb3c467b r1719464  
    3939
    4040#include <glib.h>
     41#include <gmodule.h>
    4142#include <stdlib.h>
    4243#include <string.h>
     44#include "misc.h"
    4345#include "rc4.h"
    4446
     
    134136        key = g_malloc( key_len );
    135137        strcpy( (char*) key, password );
    136         for( i = 0; i < RC4_IV_LEN; i ++ )
    137                 key[key_len-RC4_IV_LEN+i] = crypt[0][i] = rand() & 0xff;
     138       
     139        /* Add the salt. Save it for later (when decrypting) and, of course,
     140           add it to the encryption key. */
     141        random_bytes( crypt[0], RC4_IV_LEN );
     142        memcpy( key + key_len - RC4_IV_LEN, crypt[0], RC4_IV_LEN );
    138143       
    139144        /* Generate the initial S[] from the IVed key. */
  • set.c

    rb3c467b r1719464  
    224224}
    225225
     226char *set_eval_charset( irc_t *irc, set_t *set, char *value )
     227{
     228        GIConv cd;
     229
     230        if ( g_strncasecmp( value, "none", 4 ) == 0 )
     231                return( value );
     232
     233        cd = g_iconv_open( "UTF-8", value );
     234        if( cd == (GIConv) -1 )
     235                return( NULL );
     236
     237        g_iconv_close( cd );
     238        return( value );
     239}
  • set.h

    rb3c467b r1719464  
    4747char *set_eval_int( irc_t *irc, set_t *set, char *value );
    4848char *set_eval_bool( irc_t *irc, set_t *set, char *value );
     49
    4950char *set_eval_to_char( irc_t *irc, set_t *set, char *value );
    5051char *set_eval_ops( irc_t *irc, set_t *set, char *value );
    51 
    52 
     52char *set_eval_charset( irc_t *irc, set_t *set, char *value );
  • storage_xml.c

    rb3c467b r1719464  
    371371        nick_t *nick;
    372372        account_t *acc;
    373         int fd, i;
     373        int fd;
    374374        md5_byte_t pass_md5[21];
    375375        md5_state_t md5_state;
     
    396396           (to prevent dictionary lookups of passwords) to end up with a 21-
    397397           byte password hash, more convenient for base64 encoding. */
    398         for( i = 0; i < 5; i ++ )
    399                 pass_md5[16+i] = rand() & 0xff;
     398        random_bytes( pass_md5 + 16, 5 );
    400399        md5_init( &md5_state );
    401400        md5_append( &md5_state, (md5_byte_t*) irc->password, strlen( irc->password ) );
Note: See TracChangeset for help on using the changeset viewer.