summaryrefslogtreecommitdiffstats
path: root/eBones/lib/libkdb/krb_kdb_utils.c
blob: 1f52cc614c83c2a8a6f2f5c8e0d6c5de23d330d2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/*
 * Copyright 1988 by the Massachusetts Institute of Technology.
 * For copying and distribution information, please see the file
 * <Copyright.MIT>.
 *
 * Utility routines for Kerberos programs which directly access
 * the database.  This code was duplicated in too many places
 * before I gathered it here.
 *
 * Jon Rochlis, MIT Telecom, March 1988
 *
 *	from: krb_kdb_utils.c,v 4.1 89/07/26 11:01:12 jtkohl Exp $
 *	$FreeBSD$
 */

#if 0
#ifndef	lint
static char rcsid[] =
"$FreeBSD$";
#endif	lint
#endif

#include <des.h>
#include <krb.h>
#include <krb_db.h>
#include <kdc.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/file.h>

long
kdb_get_master_key(prompt, master_key, master_key_sched)
     int prompt;
     C_Block master_key;
     Key_schedule master_key_sched;
{
  int kfile;

  if (prompt)  {
#ifdef NOENCRYPTION
      placebo_read_password(master_key,
			    "\nEnter Kerberos master key: ", 0);
#else
      des_read_password((des_cblock *)master_key,
			     "\nEnter Kerberos master key: ", 0);
#endif
      printf ("\n");
  }
  else {
    kfile = open(MKEYFILE, O_RDONLY, 0600);
    if (kfile < 0) {
      /* oh, for com_err_ */
      return (-1);
    }
    if (read(kfile, (char *) master_key, 8) != 8) {
      return (-1);
    }
    close(kfile);
  }

#ifndef NOENCRYPTION
  key_sched((des_cblock *)master_key,master_key_sched);
#endif
  return (0);
}

/* The caller is reasponsible for cleaning up the master key and sched,
   even if we can't verify the master key */

/* Returns master key version if successful, otherwise -1 */

long
kdb_verify_master_key (master_key, master_key_sched, out)
     C_Block master_key;
     Key_schedule master_key_sched;
     FILE *out;  /* setting this to non-null be do output */
{
  C_Block key_from_db;
  Principal principal_data[1];
  int n, more = 0;
  long master_key_version;

  /* lookup the master key version */
  n = kerb_get_principal(KERB_M_NAME, KERB_M_INST, principal_data,
			 1 /* only one please */, &more);
  if ((n != 1) || more) {
    if (out != (FILE *) NULL)
      fprintf(out,
	      "verify_master_key: %s, %d found.\n",
	      "Kerberos error on master key version lookup",
	      n);
    return (-1);
  }

  master_key_version = (long) principal_data[0].key_version;

  /* set up the master key */
  if (out != (FILE *) NULL)  /* should we punt this? */
    fprintf(out, "Current Kerberos master key version is %d.\n",
	    principal_data[0].kdc_key_ver);

  /*
   * now use the master key to decrypt the key in the db, had better
   * be the same!
   */
  bcopy(&principal_data[0].key_low, key_from_db, 4);
  bcopy(&principal_data[0].key_high, ((long *) key_from_db) + 1, 4);
  kdb_encrypt_key (key_from_db, key_from_db,
		   master_key, master_key_sched, DECRYPT);

  /* the decrypted database key had better equal the master key */
  n = bcmp((char *) master_key, (char *) key_from_db,
	   sizeof(master_key));
  /* this used to zero the master key here! */
  bzero(key_from_db, sizeof(key_from_db));
  bzero(principal_data, sizeof (principal_data));

  if (n && (out != (FILE *) NULL)) {
    fprintf(out, "\n\07\07verify_master_key: Invalid master key; ");
    fprintf(out, "does not match database.\n");
    return (-1);
  }
  if (out != (FILE *) NULL) {
    fprintf(out, "\nMaster key entered.  BEWARE!\07\07\n");
    fflush(out);
  }

  return (master_key_version);
}

/* The old algorithm used the key schedule as the initial vector which
   was byte order depedent ... */

void
kdb_encrypt_key (in, out, master_key, master_key_sched, e_d_flag)
     C_Block in, out, master_key;
     Key_schedule master_key_sched;
     int e_d_flag;
{

#ifdef NOENCRYPTION
  bcopy(in, out, sizeof(C_Block));
#else
  pcbc_encrypt((des_cblock*)in,(des_cblock*)out,(long)sizeof(C_Block),
	master_key_sched,(des_cblock*)master_key,e_d_flag);
#endif
}
OpenPOWER on IntegriCloud