* $Source: /mit/kerberos/src/lib/krb/RCS/rd_priv.c,v $
* Copyright 1986, 1987, 1988 by the Massachusetts Institute
* For copying and distribution information, please see the file
* This routine dissects a a Kerberos 'private msg', decrypting it,
* checking its integrity, and returning a pointer to the application
* data contained and its length.
* Returns 0 (RD_AP_OK) for success or an error code (RD_AP_...). If
* the return value is RD_AP_TIME, then either the times are too far
* out of synch, OR the packet was modified.
* Steve Miller Project Athena MIT/DEC
static char *rcsid_rd_priv_c
=
"$Header: rd_priv.c,v 4.14 89/04/28 11:59:42 jtkohl Exp $";
#include <mit-copyright.h>
/* system include files */
/* application include files */
#include "lsb_addr_comp.h"
static struct timeval local_time
;
int private_msg_ver
= KRB_PROT_VERSION
;
* krb_rd_priv() checks the integrity of an
* krb_rd_priv() decrypts and checks the integrity of an
* AUTH_MSG_PRIVATE message. Given the message received, "in",
* the length of that message, "in_length", the key "schedule"
* and "key", and the network addresses of the
* and "key" to decrypt with, and the network addresses of the
* "sender" and "receiver" of the message, krb_rd_safe() returns
* RD_AP_OK if the message is okay, otherwise some error code.
* The message data retrieved from "in" are returned in the structure
* "m_data". The pointer to the application data
* "m_data". The pointer to the decrypted application data
* (m_data->app_data) refers back to the appropriate place in "in".
* See the file "mk_priv.c" for the format of the AUTH_MSG_PRIVATE
* message. The structure containing the extracted message
* information, MSG_DAT, is defined in "krb.h".
long krb_rd_priv(in
,in_length
,schedule
,key
,sender
,receiver
,m_data
)
u_char
*in
; /* pointer to the msg received */
u_long in_length
; /* length of "in" msg */
Key_schedule schedule
; /* precomputed key schedule */
C_Block key
; /* encryption key for seed and ivec */
struct sockaddr_in
*sender
;
struct sockaddr_in
*receiver
;
MSG_DAT
*m_data
; /*various input/output data from msg */
static u_long src_addr
; /* Can't send structs since no
if (gettimeofday(&local_time
,(struct timezone
*)0))
p
= in
; /* beginning of message */
if (*p
++ != KRB_PROT_VERSION
&& *(p
-1) != 3)
private_msg_ver
= *(p
-1);
if (((*p
) & ~1) != AUTH_MSG_PRIVATE
)
if ((*p
++ & 1) != HOST_BYTE_ORDER
)
bcopy((char *)p
,(char *)&c_length
,sizeof(c_length
));
/* check for rational length so we don't go comatose */
if (VERSION_SZ
+ MSG_TYPE_SZ
+ c_length
> in_length
)
* decrypt to obtain length, timestamps, app_data, and checksum
* use the session key as an ivec
q
= p
; /* mark start of encrypted stuff */
/* pcbc decrypt, use key as ivec */
pcbc_encrypt((C_Block
*) q
,(C_Block
*) q
, (long) c_length
,
/* safely get application data length */
bcopy((char *) p
,(char *)&(m_data
->app_length
),
sizeof(m_data
->app_length
));
swap_u_long(m_data
->app_length
);
p
+= sizeof(m_data
->app_length
); /* skip over */
if (m_data
->app_length
+ sizeof(c_length
) + sizeof(in_length
) +
sizeof(m_data
->time_sec
) + sizeof(m_data
->time_5ms
) +
sizeof(src_addr
) + VERSION_SZ
+ MSG_TYPE_SZ
/* we're now at the decrypted application data */
/* safely get time_5ms */
bcopy((char *) p
, (char *)&(m_data
->time_5ms
),
sizeof(m_data
->time_5ms
));
/* don't need to swap-- one byte for now */
p
+= sizeof(m_data
->time_5ms
);
/* safely get src address */
bcopy((char *) p
,(char *)&src_addr
,sizeof(src_addr
));
/* don't swap, net order always */
if (src_addr
!= (u_long
) sender
->sin_addr
.s_addr
)
/* safely get time_sec */
bcopy((char *) p
, (char *)&(m_data
->time_sec
),
sizeof(m_data
->time_sec
));
if (swap_bytes
) swap_u_long(m_data
->time_sec
);
p
+= sizeof(m_data
->time_sec
);
/* check direction bit is the sign bit */
/* For compatibility with broken old code, compares are done in VAX
if (lsb_net_ulong_less(sender
->sin_addr
.s_addr
,
receiver
->sin_addr
.s_addr
)==-1)
m_data
->time_sec
= - m_data
->time_sec
;
else if (lsb_net_ulong_less(sender
->sin_addr
.s_addr
,
receiver
->sin_addr
.s_addr
)==0)
if (lsb_net_ushort_less(sender
->sin_port
,receiver
->sin_port
)==-1)
m_data
->time_sec
= - m_data
->time_sec
;
* all that for one tiny bit!
* Heaven help those that talk to themselves.
/* check the time integrity of the msg */
delta_t
= abs((int)((long) local_time
.tv_sec
if (delta_t
> CLOCK_SKEW
)
printf("\ndelta_t = %d",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.
bcopy((char *) p
,(char *)&cksum
,sizeof(cksum
));
if (swap_bytes
) swap_u_long(cksum
)
* calculate the checksum of the length, sequence,
* and input data, on the sending byte order!!
calc_cksum
= quad_cksum(q
,NULL
,p
-q
,0,key
);
printf("\ncalc_cksum = %u, received cksum = %u",
return RD_AP_OK
; /* OK == 0 */