예제 #1
0
파일: keys.c 프로젝트: dmr0605/Kerberos
/**
 * shishi_keys_remove:
 * @keys: key set handle as allocated by shishi_keys().
 * @keyno: key number of key in the set to remove.  The first
 *   key is key number 0.
 *
 * Remove a key, indexed by @keyno, in given key set.
 **/
void
shishi_keys_remove (Shishi_keys * keys, int keyno)
{
  shishi_key_done (keys->keys[keyno]);

  if (keyno < keys->nkeys)
    memmove (&keys->keys[keyno], &keys->keys[keyno + 1],
	     sizeof (*keys->keys) * (keys->nkeys - keyno - 1));

  --keys->nkeys;

  keys->keys = xrealloc (keys->keys, sizeof (*keys->keys) * keys->nkeys);
}
예제 #2
0
/**
 * shishi_authenticator_add_random_subkey_etype:
 * @handle: shishi handle as allocated by shishi_init().
 * @authenticator: authenticator as allocated by shishi_authenticator().
 * @etype: encryption type of random key to generate.
 *
 * Generate random subkey of indicated encryption type, and store it
 * in the authenticator.
 *
 * Return value: Returns SHISHI_OK iff successful.
 **/
int
shishi_authenticator_add_random_subkey_etype (Shishi * handle,
        Shishi_asn1 authenticator,
        int etype)
{
    int res;
    Shishi_key *subkey;

    res = shishi_key_random (handle, etype, &subkey);
    if (res != SHISHI_OK)
        return res;

    res = shishi_authenticator_add_subkey (handle, authenticator, subkey);

    shishi_key_done (subkey);

    return res;
}
예제 #3
0
파일: keys.c 프로젝트: dmr0605/Kerberos
/**
 * shishi_keys_for_serverrealm_in_file
 * @handle: Shishi library handle create by shishi_init().
 * @filename: file to read keys from.
 * @server: server name to get key for.
 * @realm: realm of server to get key for.
 *
 * Get keys that match specified @server and @realm from the key set
 * file @filename.
 *
 * Return value: Returns the key for specific server and realm, read
 *   from the indicated file, or NULL if no key could be found or an
 *   error encountered.
 **/
Shishi_key *
shishi_keys_for_serverrealm_in_file (Shishi * handle,
				     const char *filename,
				     const char *server, const char *realm)
{
  Shishi_key *key = NULL;
  FILE *fh;
  int res;

  fh = fopen (filename, "r");
  if (fh == NULL)
    return NULL;

  res = SHISHI_OK;
  while (!feof (fh))
    {
      res = shishi_key_parse (handle, fh, &key);
      if (res != SHISHI_OK || key == NULL)
	break;

      if (VERBOSENOISE (handle))
	{
	  printf ("Read key:\n");
	  shishi_key_print (handle, stdout, key);
	}

      if ((!server ||
	   (shishi_key_principal (key) &&
	    strcmp (server, shishi_key_principal (key)) == 0)) &&
	  (!realm ||
	   (shishi_key_realm (key) &&
	    strcmp (realm, shishi_key_realm (key)) == 0)))
	break;

      shishi_key_done (key);
      key = NULL;
    }

  res = fclose (fh);
  if (res != 0)
    return NULL;

  return key;
}
예제 #4
0
파일: keys.c 프로젝트: dmr0605/Kerberos
/**
 * shishi_keys_done:
 * @keys: key set handle as allocated by shishi_keys().
 *
 * Deallocates all resources associated with key set.  The key set
 * handle must not be used in calls to other shishi_keys_*() functions
 * after this.
 **/
void
shishi_keys_done (Shishi_keys ** keys)
{
  size_t i;

  if (!keys || !*keys)
    return;

  if ((*keys)->nkeys > 0)
    for (i = (*keys)->nkeys; i > 0; i--)
      shishi_key_done ((*keys)->keys[i - 1]);

  if ((*keys)->keys)
    free ((*keys)->keys);

  free (*keys);

  *keys = NULL;

  return;
}
예제 #5
0
int
rlogind_mainloop (int infd, int outfd)
{
  socklen_t size;
  struct auth_data auth_data;
  int true;
  char c;
  int authenticated;
  pid_t pid;
  int master;

  memset (&auth_data, 0, sizeof auth_data);
  size = sizeof auth_data.from;
  if (getpeername (infd, (struct sockaddr *) &auth_data.from, &size) < 0)
    {
      syslog (LOG_ERR, "Can't get peer name of remote host: %m");
      fatal (outfd, "Can't get peer name of remote host", 1);
    }

  syslog (LOG_INFO, "Connect from %s:%d",
	  inet_ntoa (auth_data.from.sin_addr),
	  ntohs (auth_data.from.sin_port));

  true = 1;
  if (keepalive
      && setsockopt (infd, SOL_SOCKET, SO_KEEPALIVE, &true, sizeof true) < 0)
    syslog (LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m");

#if defined (IP_TOS) && defined (IPPROTO_IP) && defined (IPTOS_LOWDELAY)
  true = IPTOS_LOWDELAY;
  if (setsockopt (infd, IPPROTO_IP, IP_TOS, (char *) &true, sizeof true) < 0)
    syslog (LOG_WARNING, "setsockopt (IP_TOS): %m");
#endif

  alarm (60);			/* Wait at most 60 seconds. FIXME: configurable? */

  /* Read the null byte */
  if (read (infd, &c, 1) != 1 || c != 0)
    {
      syslog (LOG_CRIT, "protocol error: expected 0 byte");
      exit (1);
    }

  alarm (0);

  authenticated = rlogind_auth (infd, &auth_data);

  pid = forkpty (&master, line, NULL, &win);

  if (pid < 0)
    {
      if (errno == ENOENT)
	{
	  syslog (LOG_ERR, "Out of ptys");
	  fatal (infd, "Out of ptys", 0);
	}
      else
	{
	  syslog (LOG_ERR, "forkpty: %m");
	  fatal (infd, "Forkpty", 1);
	}
    }

  if (pid == 0)
    {
      /* Child */
      if (infd > 2)
	close (infd);

      setup_tty (0, &auth_data);
      setup_utmp (line);

      exec_login (authenticated, &auth_data);
      fatal (infd, "can't execute login", 1);
    }

  /* Parent */
  true = 1;
  IF_NOT_ENCRYPT (ioctl (infd, FIONBIO, &true));
  ioctl (master, FIONBIO, &true);
  ioctl (master, TIOCPKT, &true);
  netf = infd;			/* Needed for cleanup() */
  signal (SIGCHLD, cleanup);
  protocol (infd, master, &auth_data);
  signal (SIGCHLD, SIG_IGN);
  cleanup (0);

#ifdef SHISHI
  if (kerberos)
    {
      int i;

      shishi_done (auth_data.h);
# ifdef ENCRYPTION
      if (encrypt_io)
	{
	  shishi_key_done (auth_data.enckey);
	  for (i = 0; i < 2; i++)
	    {
	      shishi_crypto_close (auth_data.ivtab[i]->ctx);
	      free (auth_data.ivtab[i]->iv);
	    }
	}
# endif
    }
#endif

  return 0;
}
예제 #6
0
파일: crypto.c 프로젝트: dmr0605/Kerberos
void
test (Shishi * handle)
{
  Shishi_key *key, *key2;
  char out[BUFSIZ];
  size_t i;
  int res;

  if (debug)
    shishi_cfg (handle, strdup ("verbose-crypto,verbose-crypto-noise"));

  for (i = 0; i < sizeof (drdk) / sizeof (drdk[0]); i++)
    {
      if (debug)
	printf ("DR entry %d\n", i);

      res = shishi_key_from_value (handle, drdk[i].type, drdk[i].key, &key);

      if (res == SHISHI_OK)
	res = shishi_dr (handle, key, drdk[i].usage, drdk[i].nusage,
			 out, strlen (drdk[i].dr));

      shishi_key_done (key);

      if (res != SHISHI_OK)
	{
	  fail ("shishi_dr() entry %d failed (%s)\n",
		i, shishi_error (handle));
	  continue;
	}

      if (debug)
	{
	  printf ("DR(%s, key, usage)\n", shishi_cipher_name (drdk[i].type));

	  printf ("key:\n");
	  escapeprint (drdk[i].key, strlen (drdk[i].key));
	  hexprint (drdk[i].key, strlen (drdk[i].key));
	  puts ("");
	  binprint (drdk[i].key, strlen (drdk[i].key));
	  puts ("");

	  printf ("usage:\n");
	  escapeprint (drdk[i].usage, drdk[i].nusage);
	  hexprint (drdk[i].usage, drdk[i].nusage);
	  puts ("");
	  binprint (drdk[i].usage, drdk[i].nusage);
	  puts ("");

	  printf ("computed DR:\n");
	  escapeprint (out, strlen (drdk[i].dr));
	  hexprint (out, strlen (drdk[i].dr));
	  puts ("");
	  binprint (out, strlen (drdk[i].dr));
	  puts ("");

	  printf ("expected DR:\n");
	  escapeprint (drdk[i].dr, strlen (drdk[i].dr));
	  hexprint (drdk[i].dr, strlen (drdk[i].dr));
	  puts ("");
	  binprint (drdk[i].dr, strlen (drdk[i].dr));
	  puts ("");
	}

      if (memcmp (drdk[i].dr, out, strlen (drdk[i].dr)) != 0)
	{
	  fail ("shishi_dr() entry %d failed\n", i);
	  if (debug)
	    printf ("ERROR\n");
	}
      else if (debug)
	success ("OK\n");

      res = shishi_key_from_value (handle, drdk[i].type, drdk[i].key, &key);

      if (res == SHISHI_OK)
	res = shishi_key_from_value (handle, drdk[i].type, NULL, &key2);

      if (res == SHISHI_OK)
	res = shishi_dk (handle, key, drdk[i].usage, drdk[i].nusage, key2);

      shishi_key_done (key);

      if (res != SHISHI_OK)
	{
	  fail ("shishi_dk() entry %d failed (%s)\n",
		i, shishi_error (handle));
	  continue;
	}

      if (debug)
	{
	  printf ("DK(%s, key, usage)\n", shishi_cipher_name (drdk[i].type));

	  printf ("key:\n");
	  escapeprint (drdk[i].key, strlen (drdk[i].key));
	  hexprint (drdk[i].key, strlen (drdk[i].key));
	  puts ("");
	  binprint (drdk[i].key, strlen (drdk[i].key));
	  puts ("");

	  printf ("usage:\n");
	  escapeprint (drdk[i].usage, drdk[i].nusage);
	  hexprint (drdk[i].usage, drdk[i].nusage);
	  puts ("");
	  binprint (drdk[i].usage, drdk[i].nusage);
	  puts ("");

	  printf ("computed DK:\n");
	  escapeprint (shishi_key_value (key2), shishi_key_length (key2));
	  hexprint (shishi_key_value (key2), shishi_key_length (key2));
	  puts ("");
	  binprint (shishi_key_value (key2), shishi_key_length (key2));
	  puts ("");

	  printf ("expected DK:\n");
	  escapeprint (drdk[i].dk, strlen (drdk[i].dk));
	  hexprint (drdk[i].dk, strlen (drdk[i].dk));
	  puts ("");
	  binprint (drdk[i].dk, strlen (drdk[i].dk));
	  puts ("");
	}

      if (!(shishi_key_length (key2) == strlen (drdk[i].dk) &&
	    memcmp (drdk[i].dk, shishi_key_value (key2),
		    strlen (drdk[i].dk)) == 0))
	{
	  fail ("shishi_dk() entry %d failed\n", i);
	  if (debug)
	    printf ("ERROR\n");
	}
      else if (debug)
	success ("OK\n");

      shishi_key_done (key2);
    }

  for (i = 0; i < sizeof (nfold) / sizeof (nfold[0]); i++)
    {
      if (debug)
	printf ("N-FOLD entry %d\n", i);

      res = shishi_n_fold (handle,
			   nfold[i].in, strlen (nfold[i].in),
			   out, nfold[i].n / 8);
      if (res != SHISHI_OK)
	{
	  fail ("shishi_n_fold() entry %d failed (%s)\n",
		i, shishi_error (handle));
	  continue;
	}

      if (debug)
	{
	  printf ("in:\n");
	  escapeprint (nfold[i].in, strlen (nfold[i].in));
	  hexprint (nfold[i].in, strlen (nfold[i].in));
	  puts ("");
	  binprint (nfold[i].in, strlen (nfold[i].in));
	  puts ("");

	  printf ("out:\n");
	  escapeprint (out, nfold[i].n / 8);
	  hexprint (out, nfold[i].n / 8);
	  puts ("");
	  binprint (out, nfold[i].n / 8);
	  puts ("");

	  printf ("expected out:\n");
	  escapeprint (nfold[i].out, nfold[i].n / 8);
	  hexprint (nfold[i].out, nfold[i].n / 8);
	  puts ("");
	  binprint (nfold[i].out, nfold[i].n / 8);
	  puts ("");
	}

      if (memcmp (nfold[i].out, out, nfold[i].n / 8) != 0)
	{
	  fail ("shishi_n_fold() entry %d failed\n", i);
	  if (debug)
	    printf ("ERROR\n");
	}
      else if (debug)
	success ("OK\n");
    }

  for (i = 0; i < sizeof (str2key) / sizeof (str2key[0]); i++)
    {
      int n_password = strlen (str2key[i].password);
      int saltlen = strlen (str2key[i].salt);
      int keylen = sizeof (key);
      const char *name = shishi_cipher_name (str2key[i].etype);

      if (debug)
	printf ("STRING-TO-KEY entry %d (key type %s)\n", i,
		name ? name : "NO NAME");

      res = shishi_key_from_string (handle, str2key[i].etype,
				    str2key[i].password, n_password,
				    str2key[i].salt, saltlen,
				    str2key[i].parameters, &key);
      if (res != SHISHI_OK)
	{
	  fail ("shishi_string_to_key() entry %d failed (%s)\n",
		i, shishi_error (handle));
	  continue;
	}

      if (debug)
	{
	  printf ("password:\n");
	  escapeprint (str2key[i].password, n_password);
	  hexprint (str2key[i].password, n_password);
	  puts ("");
	  binprint (str2key[i].password, n_password);
	  puts ("");

	  printf ("salt:\n");
	  escapeprint (str2key[i].salt, saltlen);
	  hexprint (str2key[i].salt, saltlen);
	  puts ("");
	  binprint (str2key[i].salt, saltlen);
	  puts ("");

	  printf ("computed key:\n");
	  escapeprint (shishi_key_value (key), shishi_key_length (key));
	  hexprint (shishi_key_value (key), shishi_key_length (key));
	  puts ("");
	  binprint (shishi_key_value (key), shishi_key_length (key));
	  puts ("");

	  printf ("expected key:\n");
	  escapeprint (str2key[i].key, strlen (str2key[i].key));
	  hexprint (str2key[i].key, strlen (str2key[i].key));
	  puts ("");
	  binprint (str2key[i].key, strlen (str2key[i].key));
	  puts ("");
	}

      if (memcmp (str2key[i].key, shishi_key_value (key), keylen) != 0)
	{
	  fail ("shishi_string_to_key() entry %d failed\n", i);

	  if (debug)
	    printf ("ERROR\n");
	}
      else if (debug)
	success ("OK\n");

      shishi_key_done (key);
    }

  for (i = 0; i < sizeof (pkcs5) / sizeof (pkcs5[0]); i++)
    {
      if (debug)
	printf ("PKCS5 entry %d\n", i);

      res = shishi_pbkdf2_sha1 (handle,
				pkcs5[i].password, strlen (pkcs5[i].password),
				pkcs5[i].salt, strlen (pkcs5[i].salt),
				pkcs5[i].iterations, pkcs5[i].dklen, out);
      if (res != SHISHI_OK)
	{
	  fail ("PKCS5 entry %d failed fatally: %d\n", i, res);
	  continue;
	}

      if (debug)
	{
	  printf ("password:\n");
	  escapeprint (pkcs5[i].password, strlen (pkcs5[i].password));
	  hexprint (pkcs5[i].password, strlen (pkcs5[i].password));
	  puts ("");
	  binprint (pkcs5[i].password, strlen (pkcs5[i].password));
	  puts ("");

	  printf ("salt:\n");
	  escapeprint (pkcs5[i].salt, strlen (pkcs5[i].salt));
	  hexprint (pkcs5[i].salt, strlen (pkcs5[i].salt));
	  puts ("");
	  binprint (pkcs5[i].salt, strlen (pkcs5[i].salt));
	  puts ("");

	  printf ("computed key:\n");
	  escapeprint (out, pkcs5[i].dklen);
	  hexprint (out, pkcs5[i].dklen);
	  puts ("");
	  binprint (out, pkcs5[i].dklen);
	  puts ("");

	  printf ("expected key:\n");
	  escapeprint (pkcs5[i].expected, pkcs5[i].dklen);
	  hexprint (pkcs5[i].expected, pkcs5[i].dklen);
	  puts ("");
	  binprint (pkcs5[i].expected, pkcs5[i].dklen);
	  puts ("");
	}

      if (memcmp (pkcs5[i].expected, out, pkcs5[i].dklen) != 0)
	{
	  fail ("PKCS5 entry %d failed\n", i);

	  if (debug)
	    printf ("ERROR\n");
	}
      else if (debug)
	success ("OK\n");
    }
}
예제 #7
0
파일: keytab.c 프로젝트: dmr0605/Kerberos
/**
 * shishi_keys_add_keytab_mem:
 * @handle: shishi handle as allocated by shishi_init().
 * @data: constant memory buffer with keytab of @len size.
 * @len: size of memory buffer with keytab data.
 * @keys: allocated key set to store keys in.
 *
 * Read keys from a MIT keytab data structure, and add them to the key
 * set.
 *
 * The format of keytab's is proprietary, and this function support
 * the 0x0501 and 0x0502 formats.  See the section The MIT Kerberos
 * Keytab Binary File Format in the Shishi manual for a description of
 * the reverse-engineered format.
 *
 * Returns: Returns %SHISHI_KEYTAB_ERROR if the data does not
 *   represent a valid keytab structure, and %SHISHI_OK on success.
 **/
int
shishi_keys_add_keytab_mem (Shishi * handle,
			    const char *data, size_t len,
			    Shishi_keys *keys)
{
  int rc;
  uint16_t file_format_version;
  size_t entrystartpos;
  uint16_t num_components;    /* sub 1 if version 0x501 */
  size_t i;
  Shishi_key *key;

  if (VERBOSENOISE (handle))
    {
      printf ("keytab len %d (0x%x)\n", len, len);
      _shishi_hexprint (data, len);
    }

  /* Check file format. */
  file_format_version = (data[0] << 8) | data[1];

  if (VERBOSENOISE (handle))
    printf ("keytab file_format_version %04X\n", file_format_version);

  if (file_format_version != 0x0501 && file_format_version != 0x0502)
    return SHISHI_KEYTAB_ERROR;

  /* Check file integrity first, to avoid error-checking below. */
  entrystartpos = 2;
  while (entrystartpos < len)
    {
      int32_t size = data[entrystartpos] << 24 | data[entrystartpos+1] << 16
	| data[entrystartpos+2] << 8 | data[entrystartpos+3];
      entrystartpos += 4;

      if (VERBOSENOISE (handle))
	{
	  printf ("keytab size %d (%x)\n", size, size);
	  printf ("keytab pos %d < %d\n", entrystartpos + size, len);
	}

      if (entrystartpos + size > len)
	return SHISHI_KEYTAB_ERROR;

      /* Go to next entry... */
      entrystartpos += size;
    }
  if (entrystartpos != len)
    return SHISHI_KEYTAB_ERROR;

  rc = shishi_key (handle, &key);
  if (rc != SHISHI_OK)
    return rc;

  entrystartpos = 2;
  while (entrystartpos < len)
    {
      size_t pos = entrystartpos;
      uint16_t size = data[pos] << 24 | data[pos+1] << 16
	| data[pos+2] << 8 | data[pos+3];
      pos += 4;

      if (VERBOSENOISE (handle))
	printf ("keytab size %d (%x)\n", size, size);

      /* Num_components */
      num_components = data[pos] << 8 | data[pos+1];
      pos += 2;

      if (file_format_version == 0x0501)
	num_components--;

      /* Realm */
      {
	uint16_t realmlen = data[pos] << 8 | data[pos+1];
	char *realm = xstrndup (&data[pos + 2], realmlen);;

	pos += 2 + realmlen;

	shishi_key_realm_set (key, realm);
	free (realm);
      }

      /* Principal components. */
      {
	char *name = NULL;
	size_t namelen = 0;

	for (i = 0; i < num_components; i++)
	  {
	    size_t l;

	    l = data[pos] << 8 | data[pos+1];
	    pos += 2;

	    name = xrealloc (name, namelen + l + 1);
	    memcpy (name + namelen, &data[pos], l);
	    name[namelen + l] = '/';

	    namelen += l + 1;
	    pos += l;

	  }
	name[namelen - 1] = '\0';
	shishi_key_principal_set (key, name);
	free (name);
      }

      /* Name_type */
      {
	uint32_t name_type   /* not present if version 0x501 */
	  = data[pos] << 24 | data[pos+1] << 16
	  | data[pos+2] << 8 | data[pos+3];
	pos += 4;

	if (VERBOSENOISE (handle))
	  printf ("keytab nametype %d (0x%08x)\n", name_type, name_type);
      }

      /* Timestamp */
      {
	uint32_t timestamp = data[pos] << 24 | data[pos+1] << 16
	  | data[pos+2] << 8 | data[pos+3];
	pos += 4;

	if (VERBOSENOISE (handle))
	  printf ("keytab timestamp %u (0x%08ux)\n", timestamp, timestamp);
      }

      /* keyvno8 */
      {
	uint8_t vno8 = data[pos++];

	if (VERBOSENOISE (handle))
	  printf ("keytab kvno8 %d (0x%02x)\n", vno8, vno8);

	shishi_key_version_set (key, vno8);
      }

      /* key, keytype */
      {
	uint32_t keytype = data[pos] << 8 | data[pos+1];
	pos += 2;

	if (VERBOSENOISE (handle))
	  printf ("keytab keytype %d (0x%x)\n", keytype, keytype);

	shishi_key_type_set (key, keytype);
      }

      /* key, length and data */
      {
	uint16_t keylen = data[pos] << 8 | data[pos+1];
	pos += 2;

	if (VERBOSENOISE (handle))
	  printf ("keytab keylen %d (0x%x) eq? %d\n", keylen, keylen,
		  shishi_key_length (key));

	if (VERBOSENOISE (handle))
	  _shishi_hexprint (data + pos, keylen);

	shishi_key_value_set (key, data + pos);
	pos += keylen;
      }

      if (pos - entrystartpos < (size_t) size + 4)
	{
	  uint32_t vno /* only present if >= 4 bytes left in entry */
	    = data[pos] << 24 | data[pos+1] << 16
	    | data[pos+2] << 8 | data[pos+3];
	  pos += 4;

	  if (VERBOSENOISE (handle))
	    printf ("keytab kvno %d (0x%08x)\n", vno, vno);

	  shishi_key_version_set (key, vno);
	}

      if (VERBOSECRYPTONOISE (handle))
	shishi_key_print (handle, stdout, key);

      rc = shishi_keys_add (keys, key);
      if (rc != SHISHI_OK)
	goto done;

      /* Go to next entry... */
      entrystartpos += size + 4;
    }

  rc = SHISHI_OK;

 done:
  shishi_key_done (key);

  return rc;
}