Beispiel #1
0
int32_t
krb_mk_priv(void *in, void *out, u_int32_t length, 
	    struct des_ks_struct *schedule, des_cblock *key, 
	    struct sockaddr_in *sender, struct sockaddr_in *receiver)
{
    unsigned char *p = (unsigned char*)out;
    unsigned char *cipher;

    struct timeval tv;
    u_int32_t src_addr;
    u_int32_t len;

    p += krb_put_int(KRB_PROT_VERSION, p, 1, 1);
    p += krb_put_int(AUTH_MSG_PRIVATE, p, 1, 1);

    len = 4 + length + 1 + 4 + 4;
    len = (len + 7) & ~7;
    p += krb_put_int(len, p, 4, 4);
    
    cipher = p;

    p += krb_put_int(length, p, 4, 4);
    
    memcpy(p, in, length);
    p += length;
    
    krb_kdctimeofday(&tv);

    *p++ =tv.tv_usec / 5000;
    
    src_addr = sender->sin_addr.s_addr;
    p += krb_put_address(src_addr, p, 4);

    p += krb_put_int(lsb_time(tv.tv_sec, sender, receiver), p, 4, 4);
    
    memset(p, 0, 7);

    des_pcbc_encrypt((des_cblock *)cipher, (des_cblock *)cipher,
		     len, schedule, key, DES_ENCRYPT);

    return  (cipher - (unsigned char*)out) + len;
}
Beispiel #2
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;
}
Beispiel #3
0
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;
}