예제 #1
0
파일: krb5.c 프로젝트: jeremyroman/pyceo
int ceo_read_password(char *password, unsigned int size, int use_stdin) {
    int tries = 0;
    unsigned int len;

    do {
        if (use_stdin) {
            if (fgets(password, size, stdin) == NULL)
                fatal("eof while reading password");

            size = strlen(password);

            if (password[size - 1] == '\n')
                password[size - 1] = '\0';
        } else {
            len = size;
            int retval = krb5_read_password(context, "New password", "Confirm password", password, &len);
            if (retval == KRB5_LIBOS_PWDINTR) {
                error("interrupted");
                return -1;
            } else if (retval == KRB5_LIBOS_BADPWDMATCH) {
                fputs("Passwords do not match.\n", stderr);
            } else if (!password || !*password) {
                fputs("Please enter a password.\n", stderr);
            }
        }
    } while (++tries < 3 && !*password);

    if (!*password) {
        error("maximum tries exceeded reading password");
        return -1;
    }

    return 0;
}
예제 #2
0
파일: kdb5.c 프로젝트: aosm/Kerberos
krb5_error_code
krb5_db_fetch_mkey(krb5_context context,
		   krb5_principal mname,
		   krb5_enctype etype,
		   krb5_boolean fromkeyboard,
		   krb5_boolean twice,
		   char *db_args, krb5_data * salt, krb5_keyblock * key)
{
    krb5_error_code retval;
    char    password[BUFSIZ];
    krb5_data pwd;
    unsigned int size = sizeof(password);
    int     kvno;
    krb5_keyblock tmp_key;

    memset(&tmp_key, 0, sizeof(tmp_key));

    if (fromkeyboard) {
	krb5_data scratch;

	if ((retval = krb5_read_password(context, krb5_mkey_pwd_prompt1,
					 twice ? krb5_mkey_pwd_prompt2 : 0,
					 password, &size))) {
	    goto clean_n_exit;
	}

	pwd.data = password;
	pwd.length = size;
	if (!salt) {
	    retval = krb5_principal2salt(context, mname, &scratch);
	    if (retval)
		goto clean_n_exit;
	}
	retval =
	    krb5_c_string_to_key(context, etype, &pwd, salt ? salt : &scratch,
				 key);

	if (!salt)
	    krb5_xfree(scratch.data);
	memset(password, 0, sizeof(password));	/* erase it */

    } else {
	kdb5_dal_handle *dal_handle;

	if (context->db_context == NULL) {
	    retval = kdb_setup_lib_handle(context);
	    if (retval) {
		goto clean_n_exit;
	    }
	}

	dal_handle = (kdb5_dal_handle *) context->db_context;
	retval = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
	if (retval) {
	    goto clean_n_exit;
	}

	tmp_key.enctype = key->enctype;
	retval = dal_handle->lib_handle->vftabl.fetch_master_key(context,
								 mname,
								 &tmp_key,
								 &kvno,
								 db_args);
	get_errmsg(context, retval);
	kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);

	if (retval) {
	    goto clean_n_exit;
	}

	key->contents = malloc(tmp_key.length);
	if (key->contents == NULL) {
	    retval = ENOMEM;
	    goto clean_n_exit;
	}

	key->magic = tmp_key.magic;
	key->enctype = tmp_key.enctype;
	key->length = tmp_key.length;
	memcpy(key->contents, tmp_key.contents, tmp_key.length);
    }

  clean_n_exit:
    if (tmp_key.contents) {
	memset(tmp_key.contents, 0, tmp_key.length);
	krb5_db_free(context, tmp_key.contents);
    }
    return retval;
}
예제 #3
0
void
kdb5_add_mkey(int argc, char *argv[])
{
    int optchar;
    krb5_error_code retval;
    char *mkey_fullname;
    char *pw_str = 0;
    unsigned int pw_size = 0;
    int do_stash = 0;
    krb5_data pwd;
    krb5_kvno new_mkey_kvno;
    krb5_keyblock new_mkeyblock;
    krb5_enctype new_master_enctype = ENCTYPE_UNKNOWN;
    char *new_mkey_password;
    krb5_db_entry *master_entry;
    krb5_timestamp now;

    /*
     * The command table entry for this command causes open_db_and_mkey() to be
     * called first to open the KDB and get the current mkey.
     */

    memset(&new_mkeyblock, 0, sizeof(new_mkeyblock));
    memset(&master_princ, 0, sizeof(master_princ));
    master_salt.data = NULL;

    while ((optchar = getopt(argc, argv, "e:s")) != -1) {
        switch(optchar) {
        case 'e':
            if (krb5_string_to_enctype(optarg, &new_master_enctype)) {
                com_err(progname, EINVAL, _("%s is an invalid enctype"),
                        optarg);
                exit_status++;
                return;
            }
            break;
        case 's':
            do_stash++;
            break;
        case '?':
        default:
            usage();
            return;
        }
    }

    if (new_master_enctype == ENCTYPE_UNKNOWN)
        new_master_enctype = global_params.enctype;

    /* assemble & parse the master key name */
    if ((retval = krb5_db_setup_mkey_name(util_context,
                                          global_params.mkey_name,
                                          global_params.realm,
                                          &mkey_fullname, &master_princ))) {
        com_err(progname, retval, _("while setting up master key name"));
        exit_status++;
        return;
    }

    retval = krb5_db_get_principal(util_context, master_princ, 0,
                                   &master_entry);
    if (retval != 0) {
        com_err(progname, retval, _("while getting master key principal %s"),
                mkey_fullname);
        exit_status++;
        goto cleanup_return;
    }

    printf(_("Creating new master key for master key principal '%s'\n"),
           mkey_fullname);

    printf(_("You will be prompted for a new database Master Password.\n"));
    printf(_("It is important that you NOT FORGET this password.\n"));
    fflush(stdout);

    pw_size = 1024;
    pw_str = malloc(pw_size);
    if (pw_str == NULL) {
        com_err(progname, ENOMEM, _("while creating new master key"));
        exit_status++;
        goto cleanup_return;
    }

    retval = krb5_read_password(util_context, KRB5_KDC_MKEY_1, KRB5_KDC_MKEY_2,
                                pw_str, &pw_size);
    if (retval) {
        com_err(progname, retval,
                _("while reading new master key from keyboard"));
        exit_status++;
        goto cleanup_return;
    }
    new_mkey_password = pw_str;

    pwd.data = new_mkey_password;
    pwd.length = strlen(new_mkey_password);
    retval = krb5_principal2salt(util_context, master_princ, &master_salt);
    if (retval) {
        com_err(progname, retval, _("while calculating master key salt"));
        exit_status++;
        goto cleanup_return;
    }

    retval = krb5_c_string_to_key(util_context, new_master_enctype,
                                  &pwd, &master_salt, &new_mkeyblock);
    if (retval) {
        com_err(progname, retval,
                _("while transforming master key from password"));
        exit_status++;
        goto cleanup_return;
    }

    new_mkey_kvno = get_next_kvno(util_context, master_entry);
    retval = add_new_mkey(util_context, master_entry, &new_mkeyblock,
                          new_mkey_kvno);
    if (retval) {
        com_err(progname, retval,
                _("adding new master key to master principal"));
        exit_status++;
        goto cleanup_return;
    }

    if ((retval = krb5_timeofday(util_context, &now))) {
        com_err(progname, retval, _("while getting current time"));
        exit_status++;
        goto cleanup_return;
    }

    if ((retval = krb5_dbe_update_mod_princ_data(util_context, master_entry,
                                                 now, master_princ))) {
        com_err(progname, retval, _("while updating the master key principal "
                                    "modification time"));
        exit_status++;
        goto cleanup_return;
    }

    if ((retval = krb5_db_put_principal(util_context, master_entry))) {
        (void) krb5_db_fini(util_context);
        com_err(progname, retval, _("while adding master key entry to the "
                                    "database"));
        exit_status++;
        goto cleanup_return;
    }

    if (do_stash) {
        retval = krb5_db_store_master_key(util_context,
                                          global_params.stash_file,
                                          master_princ,
                                          new_mkey_kvno,
                                          &new_mkeyblock,
                                          mkey_password);
        if (retval) {
            com_err(progname, errno, _("while storing key"));
            printf(_("Warning: couldn't stash master key.\n"));
        }
    }

cleanup_return:
    /* clean up */
    (void) krb5_db_fini(util_context);
    zap((char *)master_keyblock.contents, master_keyblock.length);
    free(master_keyblock.contents);
    zap((char *)new_mkeyblock.contents, new_mkeyblock.length);
    free(new_mkeyblock.contents);
    if (pw_str) {
        zap(pw_str, pw_size);
        free(pw_str);
    }
    free(master_salt.data);
    krb5_free_unparsed_name(util_context, mkey_fullname);
    return;
}
예제 #4
0
/*
 * This routine is the "obtain" function for the SAM_CHALLENGE
 * preauthentication type.  It presents the challenge...
 */
static krb5_error_code
obtain_sam_padata(krb5_context context, krb5_pa_data *in_padata, krb5_etype_info etype_info, krb5_keyblock *def_enc_key, git_key_proc key_proc, krb5_const_pointer key_seed, krb5_creds *creds, krb5_kdc_req *request, krb5_pa_data **out_padata)
{
    krb5_error_code		retval;
    krb5_data *			scratch;
    krb5_data			tmpsam;
    krb5_pa_data *		pa;
    krb5_sam_challenge		*sam_challenge = 0;
    krb5_sam_response		sam_response;
    /* these two get encrypted and stuffed in to sam_response */
    krb5_enc_sam_response_enc	enc_sam_response_enc;
    krb5_keyblock *		sam_use_key = 0;
    char * prompt;

    tmpsam.length = in_padata->length;
    tmpsam.data = (char *) in_padata->contents;
    retval = decode_krb5_sam_challenge(&tmpsam, &sam_challenge);
    if (retval)
      return retval;

    if (sam_challenge->sam_flags & KRB5_SAM_MUST_PK_ENCRYPT_SAD) {
      return KRB5_SAM_UNSUPPORTED;
    }

    enc_sam_response_enc.sam_nonce = sam_challenge->sam_nonce;
    if (!sam_challenge->sam_nonce) {
      retval = krb5_us_timeofday(context,
                                 &enc_sam_response_enc.sam_timestamp,
                                 &enc_sam_response_enc.sam_usec);
      sam_response.sam_patimestamp = enc_sam_response_enc.sam_timestamp;
    }
    if (retval)
      return retval;
    if (sam_challenge->sam_flags & KRB5_SAM_SEND_ENCRYPTED_SAD) {
      /* encrypt passcode in key by stuffing it here */
      unsigned int pcsize = 256;
      char *passcode = malloc(pcsize+1);
      if (passcode == NULL)
	return ENOMEM;
      prompt = handle_sam_labels(sam_challenge);
      if (prompt == NULL) {
	free(passcode);
	return ENOMEM;
      }
      retval = krb5_read_password(context, prompt, 0, passcode, &pcsize);
      free(prompt);

      if (retval) {
	free(passcode);
	return retval;
      }
      enc_sam_response_enc.sam_sad.data = passcode;
      enc_sam_response_enc.sam_sad.length = pcsize;
    } else if (sam_challenge->sam_flags & KRB5_SAM_USE_SAD_AS_KEY) {
      prompt = handle_sam_labels(sam_challenge);
      if (prompt == NULL)
	return ENOMEM;
      retval = sam_get_pass_from_user(context, etype_info, key_proc, 
				      key_seed, request, &sam_use_key,
				      prompt);
      free(prompt);
      if (retval)
	return retval;      
      enc_sam_response_enc.sam_sad.length = 0;
    } else {
      /* what *was* it? */
      return KRB5_SAM_UNSUPPORTED;
    }

    /* so at this point, either sam_use_key is generated from the passcode
     * or enc_sam_response_enc.sam_sad is set to it, and we use 
     * def_enc_key instead. */
    /* encode the encoded part of the response */
    if ((retval = encode_krb5_enc_sam_response_enc(&enc_sam_response_enc,
						   &scratch)) != 0)
      return retval;

    if ((retval = krb5_encrypt_data(context, 
				    sam_use_key?sam_use_key:def_enc_key, 
				    0, scratch,
				    &sam_response.sam_enc_nonce_or_ts)))
      goto cleanup;

    krb5_free_data(context, scratch);
    scratch = 0;

    /* sam_enc_key is reserved for future use */
    sam_response.sam_enc_key.ciphertext.length = 0;

    /* copy things from the challenge */
    sam_response.sam_nonce = sam_challenge->sam_nonce;
    sam_response.sam_flags = sam_challenge->sam_flags;
    sam_response.sam_track_id = sam_challenge->sam_track_id;
    sam_response.sam_type = sam_challenge->sam_type;
    sam_response.magic = KV5M_SAM_RESPONSE;

    if ((retval = encode_krb5_sam_response(&sam_response, &scratch)) != 0)
	return retval;
    
    if ((pa = malloc(sizeof(krb5_pa_data))) == NULL) {
	retval = ENOMEM;
	goto cleanup;
    }

    pa->magic = KV5M_PA_DATA;
    pa->pa_type = KRB5_PADATA_SAM_RESPONSE;
    pa->length = scratch->length;
    pa->contents = (krb5_octet *) scratch->data;
    scratch = 0;		/* so we don't free it! */

    *out_padata = pa;

    retval = 0;
    
cleanup:
    if (scratch)
	krb5_free_data(context, scratch);
    if (sam_challenge)
        free(sam_challenge);
    return retval;
}