From: Paul Park Date: Wed, 26 Apr 1995 20:59:51 +0000 (+0000) Subject: New admistrative protocol read/write routines X-Git-Tag: krb5-1.0-beta5~245 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=db593b69a5349db9aebbf1a05fd5b0698fe3b638;p=krb5.git New admistrative protocol read/write routines git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@5504 dc483132-0cff-0310-8789-dd5450dbe970 --- diff --git a/src/lib/krb5/krb/adm_rw.c b/src/lib/krb5/krb/adm_rw.c new file mode 100644 index 000000000..6155f8f73 --- /dev/null +++ b/src/lib/krb5/krb/adm_rw.c @@ -0,0 +1,523 @@ +/* + * lib/krb5/krb/adm_rw.c + * + * Copyright 1995 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + */ + +/* + * Routines to engage in the administrative (password changing) protocol. + */ +#include "k5-int.h" +#include "auth_con.h" +#include "adm_proto.h" + +/* + * Routines to [de]serialize integers. + * + * kadm_copyin_int32 - Move a 32-bit integer fron network byte order to + * host byte order. + * kadm_copyout_int32 - Move a 32-bit integer from host byte order to + * network byte order. + */ +#define ALIGNMENT_PARANOID 1 +#ifdef ALIGNMENT_PARANOID +static void +kadm_copyin_int32(cp, ip) + char *cp; + krb5_int32 *ip; +{ + int i; + krb5_int32 inbuf; + char *tmp; + + tmp = (char *) &inbuf; + for (i=0; i 0)) + krb5_xfree(datap[i].data); + + krb5_xfree(datap); + } +} + +/* + * krb5_send_adm_cmd() - Send an administrative command. + * + * Send a list of data in a KRB_PRIV message. Data takes the format: + * nargs (4 octets in network order) + * arg size 1 (4 octets in network order) + * arg data 1 ("arg size 1" octets) + * . + * . + * . + */ +krb5_error_code INTERFACE +krb5_send_adm_cmd(kcontext, sock, ctx, nargs, arglist) + krb5_context kcontext; /* Context handle (In ) */ + krb5_pointer sock; /* Socket to write to (In ) */ + krb5_auth_context *ctx; /* Auth context (In ) */ + int nargs; /* Number of arguments (In ) */ + krb5_data *arglist; /* Components to write (In ) */ +{ + int writebufsize; + int i; + char *writebuf; + krb5_error_code ret; + + /* + * First check that our auth context has the right flags in it. + */ + if ((ctx->auth_context_flags & (KRB5_AUTH_CONTEXT_RET_SEQUENCE| + KRB5_AUTH_CONTEXT_DO_SEQUENCE)) != + (KRB5_AUTH_CONTEXT_RET_SEQUENCE|KRB5_AUTH_CONTEXT_DO_SEQUENCE)) { + /* XXX - need a better error */ + return(KRB5KRB_AP_ERR_MSG_TYPE); + } + + ret = 0; + /* Calculate write buffer size */ + writebufsize = sizeof(krb5_int32); + for (i=0; iauth_context_flags & (KRB5_AUTH_CONTEXT_RET_SEQUENCE| + KRB5_AUTH_CONTEXT_DO_SEQUENCE)) != + (KRB5_AUTH_CONTEXT_RET_SEQUENCE|KRB5_AUTH_CONTEXT_DO_SEQUENCE)) { + /* XXX - need a better error */ + return(KRB5KRB_AP_ERR_MSG_TYPE); + } + + ret = 0; + /* Calculate write buffer size */ + writebufsize = 2 * sizeof(krb5_int32); + for (i=0; iauth_context_flags & (KRB5_AUTH_CONTEXT_RET_SEQUENCE| + KRB5_AUTH_CONTEXT_DO_SEQUENCE)) != + (KRB5_AUTH_CONTEXT_RET_SEQUENCE|KRB5_AUTH_CONTEXT_DO_SEQUENCE)) { + /* XXX - need a better error */ + return(KRB5KRB_AP_ERR_MSG_TYPE); + } + + if (!(ret = krb5_read_message(kcontext, sock, &read_data))) { + if (!(ret = krb5_rd_priv(kcontext, + ctx, + &read_data, + &msg_data, + &replay_data))) { + char *curr; + int replyok; + int i; + + replyok = 0; + /* We'd better have at least one reply component */ + if (msg_data.length >= sizeof(krb5_int32)) { + curr = msg_data.data; + kadm_copyin_int32(curr, nargs); + curr += sizeof(krb5_int32); + + /* Are there any components to copy? */ + if (*nargs > 0) { + + /* Get the memory for the list */ + if (*arglist = (krb5_data *) + malloc((*nargs) * sizeof(krb5_data))) { + krb5_data *xarglist; + + xarglist = *arglist; + memset((char *) (xarglist), 0, + (*nargs) * sizeof(krb5_data)); + + replyok = 1; + /* Copy out each list entry */ + for (i=0; i<*nargs; i++) { + + /* First get the length of the reply component */ + if (curr + sizeof(krb5_int32) - msg_data.data <= + msg_data.length) { + kadm_copyin_int32(curr, + &xarglist[i].length); + curr += sizeof(krb5_int32); + + /* Then get the memory for the actual data */ + if ((curr + xarglist[i].length - + msg_data.data <= msg_data.length) && + (xarglist[i].data = (char *) + malloc(xarglist[i].length+1))) { + + /* Then copy it out */ + memcpy(xarglist[i].data, + curr, + xarglist[i].length); + curr += xarglist[i].length; + + /* Null terminate for convenience */ + xarglist[i].data[xarglist[i].length] + = '\0'; + } + else { + /* Not enough remaining data. */ + replyok = 0; + break; + } + } + else { + /* Not enough remaining data */ + replyok = 0; + break; + } + } + if (!replyok) + krb5_free_adm_data(kcontext, *nargs, *arglist); + } + } + else { + if (*nargs == 0) { + *arglist = (krb5_data *) NULL; + replyok = 1; + } + } + } + if (!replyok) { + ret = KRB5KRB_AP_ERR_MSG_TYPE; /* syntax error */ + } + memset(msg_data.data, 0, msg_data.length); + krb5_xfree(msg_data.data); + } + krb5_xfree(read_data.data); + } + return(ret); +} + +/* + * krb5_read_adm_reply() - Read an administrative protocol response. + * + * Expect to read them out in the same format as send_adm_reply shoots them + * in. + * + * It is the caller's responsibility to free the memory allocated for + * the read in component list. + */ +krb5_error_code INTERFACE +krb5_read_adm_reply(kcontext, sock, ctx, cmd_stat, ncomps, complist) + krb5_context kcontext; /* Context handle (In ) */ + krb5_pointer sock; /* Socket to read from (In ) */ + krb5_auth_context *ctx; /* Auth context (In ) */ + krb5_int32 *cmd_stat; /* Command status (Out) */ + krb5_int32 *ncomps; /* # of reply components(Out) */ + krb5_data **complist; /* List of components (Out) */ +{ + krb5_data read_data; + krb5_error_code ret; + krb5_data msg_data; + krb5_replay_data replay_data; + + /* + * First check that our auth context has the right flags in it. + */ + if ((ctx->auth_context_flags & (KRB5_AUTH_CONTEXT_RET_SEQUENCE| + KRB5_AUTH_CONTEXT_DO_SEQUENCE)) != + (KRB5_AUTH_CONTEXT_RET_SEQUENCE|KRB5_AUTH_CONTEXT_DO_SEQUENCE)) { + /* XXX - need a better error */ + return(KRB5KRB_AP_ERR_MSG_TYPE); + } + + if (!(ret = krb5_read_message(kcontext, sock, &read_data))) { + if (!(ret = krb5_rd_priv(kcontext, + ctx, + &read_data, + &msg_data, + &replay_data))) { + char *curr; + int replyok; + int i; + + replyok = 0; + /* We'd better have at least two reply components */ + if (msg_data.length >= (2*sizeof(krb5_int32))) { + curr = msg_data.data; + kadm_copyin_int32(curr, cmd_stat); + curr += sizeof(krb5_int32); + kadm_copyin_int32(curr, ncomps); + curr += sizeof(krb5_int32); + + /* Are there any components to copy? */ + if (*ncomps > 0) { + + /* Get the memory for the list */ + if (*complist = (krb5_data *) + malloc((*ncomps) * sizeof(krb5_data))) { + krb5_data *xcomplist; + + xcomplist = *complist; + memset((char *) (xcomplist), 0, + (*ncomps) * sizeof(krb5_data)); + + replyok = 1; + /* Copy out each list entry */ + for (i=0; i<*ncomps; i++) { + + /* First get the length of the reply component */ + if (curr + sizeof(krb5_int32) - msg_data.data <= + msg_data.length) { + kadm_copyin_int32(curr, + &xcomplist[i].length); + curr += sizeof(krb5_int32); + + /* Then get the memory for the actual data */ + if ((curr + xcomplist[i].length - + msg_data.data <= msg_data.length) && + (xcomplist[i].data = (char *) + malloc(xcomplist[i].length+1))) { + + /* Then copy it out */ + memcpy(xcomplist[i].data, + curr, + xcomplist[i].length); + curr += xcomplist[i].length; + + /* Null terminate for convenience */ + xcomplist[i].data[xcomplist[i].length] + = '\0'; + } + else { + /* Not enough remaining data. */ + replyok = 0; + break; + } + } + else { + /* Not enough remaining data */ + replyok = 0; + break; + } + } + if (!replyok) + krb5_free_adm_data(kcontext, *ncomps, *complist); + } + } + else { + if (*ncomps == 0) { + *complist = (krb5_data *) NULL; + replyok = 1; + } + } + } + if (!replyok) { + ret = KRB5KRB_AP_ERR_MSG_TYPE; /* syntax error */ + } + memset(msg_data.data, 0, msg_data.length); + krb5_xfree(msg_data.data); + } + krb5_xfree(read_data.data); + } + return(ret); +}