summaryrefslogtreecommitdiffstats
path: root/src/kadmin.old/server/adm_nego.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/kadmin.old/server/adm_nego.c')
-rw-r--r--src/kadmin.old/server/adm_nego.c314
1 files changed, 314 insertions, 0 deletions
diff --git a/src/kadmin.old/server/adm_nego.c b/src/kadmin.old/server/adm_nego.c
new file mode 100644
index 000000000..abde3419a
--- /dev/null
+++ b/src/kadmin.old/server/adm_nego.c
@@ -0,0 +1,314 @@
+/*
+ * kadmin/server/adm_nego.c
+ *
+ * Copyright 1990,1991 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.
+ *
+ * Sandia National Laboratories also makes no representations about the
+ * suitability of the modifications, or additions to this software for
+ * any purpose. It is provided "as is" without express or implied warranty.
+ *
+ * Modify the Kerberos Database
+ */
+
+
+#include "com_err.h"
+#include <sys/types.h>
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#ifndef hpux
+#include <arpa/inet.h>
+#endif
+
+#include <stdio.h>
+
+#include "k5-int.h"
+#include "adm_extern.h"
+
+krb5_error_code
+adm_negotiate_key(context, auth_context, prog, new_passwd)
+ krb5_context context;
+ krb5_auth_context *auth_context;
+ char const * prog;
+ char * new_passwd;
+{
+ krb5_replay_data replaydata;
+ krb5_data msg_data, inbuf;
+ krb5_error_code retval;
+#if defined(MACH_PASS) || defined(SANDIA) /* Machine-generated passwords. */
+ krb5_pwd_data *pwd_data;
+ krb5_pwd_data encodable_data;
+ krb5_data *encoded_pw_string;
+ passwd_phrase_element **next_passwd_phrase_element;
+ char *tmp_passwd, *tmp_phrase;
+ krb5_authenticator *client_auth_data;
+ int count, i, j, k;
+ int legit_passwd = 0;
+#endif
+ extern int errno;
+
+#if defined(MACH_PASS) || defined(SANDIA) /* Machine-generated passwords. */
+
+#define clear_encodable_data() \
+{ encodable_data.sequence_count = 0; \
+ encodable_data.element = 0; \
+}
+
+#define free_seq_list() \
+{ free(encodable_data.element); \
+}
+
+#define free_pwd_and_phrase_structures() \
+{ next_passwd_phrase_element = encodable_data.element; \
+ for (k = 0; \
+ *next_passwd_phrase_element != 0 && k < encodable_data.sequence_count; \
+ k++) { \
+ free(*next_passwd_phrase_element); \
+ *next_passwd_phrase_element = 0; \
+ next_passwd_phrase_element++; } \
+}
+
+#define free_passwds() \
+{ next_passwd_phrase_element = encodable_data.element; \
+ for (k = 0; \
+ *next_passwd_phrase_element != 0 && k < encodable_data.sequence_count; \
+ k++) { \
+ memset((char *) (*next_passwd_phrase_element)->passwd->data, \
+ 0, (*next_passwd_phrase_element)->passwd->length); \
+ free((*next_passwd_phrase_element)->passwd->data); \
+ next_passwd_phrase_element++; } \
+}
+
+#define free_phrases() \
+{ next_passwd_phrase_element = encodable_data.element; \
+ for (k = 0; \
+ *next_passwd_phrase_element != 0 && k < encodable_data.sequence_count; \
+ k++) { \
+ memset((char *) (*next_passwd_phrase_element)->phrase->data, \
+ 0, (*next_passwd_phrase_element)->phrase->length); \
+ free((*next_passwd_phrase_element)->phrase->data); \
+ next_passwd_phrase_element++; } \
+}
+
+ encodable_data.sequence_count =
+ ADM_MAX_PW_CHOICES * ADM_MAX_PW_ITERATIONS;
+
+ /* Allocate List of Password and Phrase Addresses Pointers */
+ if ((encodable_data.element = (passwd_phrase_element **) calloc(
+ encodable_data.sequence_count + 1,
+ sizeof(passwd_phrase_element *))) ==
+ (passwd_phrase_element **) 0) {
+ clear_encodable_data();
+ com_err("adm_negotiate_key", 0,
+ "No Memory for Password and Phrase List");
+ return(1);
+ }
+
+ next_passwd_phrase_element = encodable_data.element;
+
+ /* Allow for ADM_MAX_PW_ITERATIONS Sets of Five Passwords/Phrases */
+ for ( i = 0; i < ADM_MAX_PW_ITERATIONS; i++) {
+ if ( i == ADM_MAX_PW_ITERATIONS ) {
+ com_err("adm_negotiate_key", 0,
+ "Excessive Password List Requests");
+ return(1);
+ }
+
+ /* Allocate passwd_phrase_element structures */
+ for (j = 0; j < ADM_MAX_PW_CHOICES; j++) {
+ if ((*next_passwd_phrase_element =
+ (passwd_phrase_element *) calloc(1,
+ sizeof(passwd_phrase_element))) ==
+ (passwd_phrase_element *) 0) {
+ free_pwd_and_phrase_structures();
+ free_seq_list();
+ clear_encodable_data();
+ com_err("adm_negotiate_key", 0,
+ "No Memory for Additional Password and Phrase Structures");
+ return(1);
+ }
+
+ if ((retval = get_pwd_and_phrase("adm_negotiate_key",
+ &tmp_passwd, &tmp_phrase))) {
+ free_pwd_and_phrase_structures();
+ free_seq_list();
+ clear_encodable_data();
+ com_err("adm_negotiate_key", 0, "Unable to get_pwd_and_phrase");
+ return(1);
+ }
+
+ if (((*next_passwd_phrase_element)->passwd =
+ (krb5_data *) calloc(1,
+ sizeof(krb5_data))) == (krb5_data *) 0) {
+ free_pwd_and_phrase_structures();
+ free_seq_list();
+ clear_encodable_data();
+ com_err("adm_negotiate_key", 0,
+ "No Memory for Additional Password and Phrase Structures");
+ return(1);
+ }
+
+ if (((*next_passwd_phrase_element)->passwd->data =
+ (char *) calloc (1,
+ strlen(tmp_passwd))) == (char *) 0) {
+ free_pwd_and_phrase_structures();
+ free_seq_list();
+ clear_encodable_data();
+ com_err("adm_negotiate_key", ENOMEM,
+ "for Additional Passwords");
+ }
+
+ strcpy((*next_passwd_phrase_element)->passwd->data, tmp_passwd);
+ (*next_passwd_phrase_element)->passwd->length = strlen(tmp_passwd);
+
+ if (((*next_passwd_phrase_element)->phrase =
+ (krb5_data *) calloc(1,
+ sizeof(krb5_data))) == (krb5_data *) 0) {
+ free_pwd_and_phrase_structures();
+ free_seq_list();
+ clear_encodable_data();
+ com_err("adm_negotiate_key", 0,
+ "No Memory for Additional Password and Phrase Structures");
+ return(1);
+ }
+
+ if (((*next_passwd_phrase_element)->phrase->data =
+ (char *) calloc (1,
+ strlen(tmp_phrase))) == (char *) 0) {
+ free_pwd_and_phrase_structures();
+ free_seq_list();
+ clear_encodable_data();
+ com_err("adm_negotiate_key", ENOMEM,
+ "for Additional Passwords");
+ return(1);
+ }
+
+ strcpy((*next_passwd_phrase_element)->phrase->data, tmp_phrase);
+ (*next_passwd_phrase_element)->phrase->length = strlen(tmp_phrase);
+
+ free(tmp_passwd);
+ free(tmp_phrase);
+
+ next_passwd_phrase_element++;
+ }
+ } /* for i <= KADM_MAX_PW_CHOICES */
+
+ /* Asn.1 Encode the Passwords and Phrases */
+ if ((retval = encode_krb5_pwd_data(&encodable_data,
+ &encoded_pw_string))) {
+ com_err("adm_negotiate_key", 0,
+ "Unable to encode Password and Phrase Data");
+ return(1);
+ }
+
+ /* Free Phrases But Hold onto Passwds for Awhile*/
+ free_phrases();
+
+ /* Encrypt Password/Phrases Encoding */
+ retval = krb5_mk_priv(context, auth_context, encoded_pw_string,
+ &msg_data, &replaydata);
+ if (retval ) {
+ free_passwds();
+ free_pwd_and_phrase_structures();
+ free_seq_list();
+ clear_encodable_data();
+ com_err("adm_negotiate_key", retval, "during mk_priv");
+ return(1);
+ }
+
+ /* Send Encrypted/Encoded Passwords and Phrases to Client */
+ if (krb5_write_message(context, &client_server_info.client_socket, &msg_data)){
+ free(msg_data.data);
+ free_passwds();
+ free_pwd_and_phrase_structures();
+ free_seq_list();
+ clear_encodable_data();
+ com_err("adm_negotiate_key", 0, "Error Performing Password Write");
+ return(1);
+ }
+ free(msg_data.data);
+
+#endif /* MACH_PASS - Machine-gen. passwords */
+ /* Read Client Response */
+ if (krb5_read_message(context, &client_server_info.client_socket, &inbuf)){
+#if defined(MACH_PASS) || defined(SANDIA)
+ free_passwds();
+ free_pwd_and_phrase_structures();
+ free_seq_list();
+ clear_encodable_data();
+#endif
+ com_err("adm_negotiate_key", errno, "Error Performing Password Read");
+ return(1);
+ }
+
+ /* Decrypt Client Response */
+ if ((retval = krb5_rd_priv(context, auth_context, &inbuf,
+ &msg_data, &replaydata))) {
+ free(inbuf.data);
+#if defined(MACH_PASS) || defined(SANDIA)
+ free_passwds();
+ free_pwd_and_phrase_structures();
+ free_seq_list();
+ clear_encodable_data();
+#endif
+ com_err("adm_negotiate_key", retval, "krb5_rd_priv error %s",
+ error_message(retval));
+ return(1);
+ }
+ free(inbuf.data);
+
+#if defined(MACH_PASS) || defined(SANDIA) /* Machine-generated passwords */
+ legit_passwd = 0;
+ next_passwd_phrase_element = encodable_data.element;
+ /* Compare Response with Acceptable Passwords */
+ for (j = 0;
+ j < ADM_MAX_PW_CHOICES * ADM_MAX_PW_ITERATIONS;
+ j++) {
+ if ((retval = memcmp(msg_data.data,
+ (*next_passwd_phrase_element)->passwd->data,
+ strlen((*next_passwd_phrase_element)->passwd->data))) == 0) {
+ legit_passwd++;
+ break; /* Exit Loop - Match Found */
+ }
+ next_passwd_phrase_element++;
+ }
+ /* Now Free Passwds */
+ free_passwds();
+
+ /* free password_and_phrase structures */
+ free_pwd_and_phrase_structures();
+
+ /* free passwd_phrase_element list */
+ free_seq_list();
+
+ /* clear krb5_pwd_data */
+ clear_encodable_data();
+
+ if (!(legit_passwd)) {
+ com_err("adm_negotiate_key", 0, "Invalid Password Entered");
+ return(1);
+ }
+#endif
+ strncpy(new_passwd, msg_data.data, msg_data.length);
+ free(msg_data.data);
+
+ return(0);
+}
+