コード例 #1
0
int32_t
krb_rd_safe(void *in, u_int32_t in_length, des_cblock *key, 
	    struct sockaddr_in *sender, struct sockaddr_in *receiver, 
	    MSG_DAT *m_data)
{
    unsigned char *p = (unsigned char*)in, *start;

    unsigned char pvno, type;
    int little_endian;
    struct timeval tv;
    u_int32_t src_addr;
    int delta_t;
    

    pvno = *p++;
    if(pvno != KRB_PROT_VERSION)
	return RD_AP_VERSION;
    
    type = *p++;
    little_endian = type & 1;
    type &= ~1;
    if(type != AUTH_MSG_SAFE)
	return RD_AP_MSG_TYPE;

    start = p;
    
    p += krb_get_int(p, &m_data->app_length, 4, little_endian);
    
    if(m_data->app_length + 31 > in_length)
	return RD_AP_MODIFIED;
    
    m_data->app_data = p;

    p += m_data->app_length;

    m_data->time_5ms = *p++;

    p += krb_get_address(p, &src_addr);

    if (!krb_equiv(src_addr, sender->sin_addr.s_addr))
        return RD_AP_BADD;

    p += krb_get_int(p, (u_int32_t *)&m_data->time_sec, 4, little_endian);
    m_data->time_sec = lsb_time(m_data->time_sec, sender, receiver);
    
    gettimeofday(&tv, NULL);

    delta_t = abs((int)((long) tv.tv_sec - m_data->time_sec));
    if (delta_t > CLOCK_SKEW) return RD_AP_TIME;

    /*
     * caller must check timestamps for proper order and replays, since
     * server might have multiple clients each with its own timestamps
     * and we don't assume tightly synchronized clocks.
     */

    {
	unsigned char new_checksum[16];
	unsigned char old_checksum[16];
	fixup_quad_cksum(start, p - start, key, 
			 new_checksum, old_checksum, little_endian);
	if((dqc_type == DES_QUAD_GUESS || dqc_type == DES_QUAD_NEW) && 
	   memcmp(new_checksum, p, 16) == 0)
	    dqc_type = DES_QUAD_NEW;
	else if((dqc_type == DES_QUAD_GUESS || dqc_type == DES_QUAD_OLD) && 
		memcmp(old_checksum, p, 16) == 0)
	    dqc_type = DES_QUAD_OLD;
	else
	    return RD_AP_MODIFIED;
    }
    return KSUCCESS;
}
コード例 #2
0
ファイル: rd_priv.c プロジェクト: 1ack/Impala
int32_t
krb_rd_priv(void *in, u_int32_t in_length, 
	    struct des_ks_struct *schedule, des_cblock *key, 
	    struct sockaddr_in *sender, struct sockaddr_in *receiver, 
	    MSG_DAT *m_data)
{
    unsigned char *p = (unsigned char*)in;
    int little_endian;
    u_int32_t clen;
    struct timeval tv;
    u_int32_t src_addr;
    int delta_t;

    unsigned char pvno, type;

    pvno = *p++;
    if(pvno != KRB_PROT_VERSION)
	return RD_AP_VERSION;
    
    type = *p++;
    little_endian = type & 1;
    type &= ~1;

    p += krb_get_int(p, &clen, 4, little_endian);
    
    if(clen + 2 > in_length)
	return RD_AP_MODIFIED;

    des_pcbc_encrypt((des_cblock*)p, (des_cblock*)p, clen, 
		     schedule, key, DES_DECRYPT);
    
    p += krb_get_int(p, &m_data->app_length, 4, little_endian);
    if(m_data->app_length + 17 > in_length)
	return RD_AP_MODIFIED;

    m_data->app_data = p;
    p += m_data->app_length;
    
    m_data->time_5ms = *p++;

    p += krb_get_address(p, &src_addr);

    if (!krb_equiv(src_addr, sender->sin_addr.s_addr))
	return RD_AP_BADD;

    p += krb_get_int(p, (u_int32_t *)&m_data->time_sec, 4, little_endian);

    m_data->time_sec = lsb_time(m_data->time_sec, sender, receiver);
    
    gettimeofday(&tv, NULL);

    /* check the time integrity of the msg */
    delta_t = abs((int)((long) tv.tv_sec - m_data->time_sec));
    if (delta_t > CLOCK_SKEW)
	return RD_AP_TIME;
    if (krb_debug)
	krb_warning("delta_t = %d\n", (int) delta_t);

    /*
     * caller must check timestamps for proper order and
     * replays, since server might have multiple clients
     * each with its own timestamps and we don't assume
     * tightly synchronized clocks.
     */

    return KSUCCESS;
}