Beispiel #1
0
/**
 * shishi_authenticator_add_cksum_type:
 * @handle: shishi handle as allocated by shishi_init().
 * @authenticator: authenticator as allocated by shishi_authenticator().
 * @key: key to to use for encryption.
 * @keyusage: cryptographic key usage value to use in encryption.
 * @cksumtype: checksum to type to calculate checksum.
 * @data: input array with data to calculate checksum on.
 * @datalen: size of input array with data to calculate checksum on.
 *
 * Calculate checksum for data and store it in the authenticator.
 *
 * Return value: Returns SHISHI_OK iff successful.
 **/
int
shishi_authenticator_add_cksum_type (Shishi * handle,
                                     Shishi_asn1 authenticator,
                                     Shishi_key * key,
                                     int keyusage, int cksumtype,
                                     char *data, size_t datalen)
{
    int res;

    if (data && datalen > 0)
    {
        char *cksum;
        size_t cksumlen;

        res = shishi_checksum (handle, key, keyusage, cksumtype,
                               data, datalen, &cksum, &cksumlen);
        if (res != SHISHI_OK)
            return res;

        res = shishi_authenticator_set_cksum (handle, authenticator,
                                              cksumtype, cksum, cksumlen);
        free (cksum);
    }
    else
        res = shishi_authenticator_remove_cksum (handle, authenticator);

    return res;
}
Beispiel #2
0
int
do_shishi_login (int infd, struct auth_data *ad, const char **err_msg)
{
  int rc;
  int error = 0;
  int keylen, keytype;
  struct passwd *pwd = NULL;
  int cksumtype, cksumlen = 30;
  char *cksum;
  char *compcksum;
  size_t compcksumlen;
  char cksumdata[100];
  struct sockaddr_in sock;
  size_t socklen = sizeof (struct sockaddr_in);

#  ifdef ENCRYPTION
  rc = get_auth (infd, &ad->h, &ad->ap, &ad->enckey, err_msg, &ad->protocol,
		 &cksumtype, &cksum, &cksumlen);
#  else
  rc = get_auth (infd, &ad->h, &ad->ap, NULL, err_msg, &ad->protocol,
		 &cksumtype, &cksum, &cksumlen);
#  endif
  if (rc != SHISHI_OK)
    return rc;

#  ifdef ENCRYPTION
  /* init IV */
  if (encrypt_io)
    {
      int i;
      char *iv;

      ad->ivtab[0] = &ad->iv1;
      ad->ivtab[1] = &ad->iv2;

      keytype = shishi_key_type (ad->enckey);
      keylen = shishi_cipher_blocksize (keytype);

      for (i = 0; i < 2; i++)
	{
	  ad->ivtab[i]->ivlen = keylen;

	  switch (keytype)
	    {
	    case SHISHI_DES_CBC_CRC:
	    case SHISHI_DES_CBC_MD4:
	    case SHISHI_DES_CBC_MD5:
	    case SHISHI_DES_CBC_NONE:
	    case SHISHI_DES3_CBC_HMAC_SHA1_KD:
	      ad->ivtab[i]->keyusage = SHISHI_KEYUSAGE_KCMD_DES;
	      ad->ivtab[i]->iv = malloc (ad->ivtab[i]->ivlen);
	      memset (ad->ivtab[i]->iv, i, ad->ivtab[i]->ivlen);
	      ad->ivtab[i]->ctx =
		shishi_crypto (ad->h, ad->enckey, ad->ivtab[i]->keyusage,
			       shishi_key_type (ad->enckey), ad->ivtab[i]->iv,
			       ad->ivtab[i]->ivlen);
	      break;
	    case SHISHI_ARCFOUR_HMAC:
	    case SHISHI_ARCFOUR_HMAC_EXP:
	      ad->ivtab[i]->keyusage = SHISHI_KEYUSAGE_KCMD_DES + 6 - 4 * i;
	      ad->ivtab[i]->ctx =
		shishi_crypto (ad->h, ad->enckey, ad->ivtab[i]->keyusage,
			       shishi_key_type (ad->enckey), NULL, 0);
	      break;
	    default:
	      ad->ivtab[i]->keyusage = SHISHI_KEYUSAGE_KCMD_DES + 6 - 4 * i;
	      ad->ivtab[i]->iv = malloc (ad->ivtab[i]->ivlen);
	      memset (ad->ivtab[i]->iv, 0, ad->ivtab[i]->ivlen);
	      if (ad->protocol == 2)
		ad->ivtab[i]->ctx =
		  shishi_crypto (ad->h, ad->enckey, ad->ivtab[i]->keyusage,
				 shishi_key_type (ad->enckey),
				 ad->ivtab[i]->iv, ad->ivtab[i]->ivlen);
	    }
	}
    }
#  endif

  getstr (infd, &ad->lusername, NULL);
  getstr (infd, &ad->term, "TERM=");
  getstr (infd, &ad->rusername, NULL);

  rc = read (infd, &error, sizeof (int));
  if ((rc != sizeof (int)) && rc)
    {
      free (pwd);
      free (cksum);
      return 1;
    }

  /*
     getpwnam crash !!!!

     pwd = getpwnam (ad->lusername);
     if (pwd == NULL)
     {
     *err_msg = "getpwnam failed";
     syslog (LOG_ERR, "getpwnam failed: %m");
     return 1;
     }

     syslog (LOG_INFO | LOG_AUTH,
     "%sKerberos V login from %s on %s\n",
     (pwd->pw_uid == 0) ? "ROOT " : "",
     ad->lusername, ad->hostname);

   */

  free (pwd);

  syslog (LOG_INFO | LOG_AUTH,
	  "Kerberos V login from %s on %s\n", ad->lusername, ad->hostname);

  /* verify checksum */

  if (getsockname (infd, (struct sockaddr *) &sock, &socklen) < 0)
    {
      syslog (LOG_ERR, "Can't get sock name");
      fatal (infd, "Can't get sockname", 1);
    }

  snprintf (cksumdata, 100, "%u:%s%s", ntohs (sock.sin_port), ad->term + 5,
	    ad->lusername);
  rc = shishi_checksum (ad->h, ad->enckey, 0, cksumtype, cksumdata,
			strlen (cksumdata), &compcksum, &compcksumlen);
  free (cksum);
  if (rc != SHISHI_OK
      || compcksumlen != cksumlen || memcmp (compcksum, cksum, cksumlen) != 0)
    {
      /* err_msg crash ? */
      /* *err_msg = "checksum verify failed"; */
      syslog (LOG_ERR, "checksum verify failed: %s", shishi_error (ad->h));
      free (compcksum);
      return 1;
    }

  free (compcksum);

  rc = shishi_authorized_p (ad->h, shishi_ap_tkt (ad->ap), ad->lusername);
  if (!rc)
    {
      syslog (LOG_ERR, "User is not authorized to log in as: %s",
	      ad->lusername);
      shishi_ap_done (ad->ap);
      return 1;
    }

  shishi_ap_done (ad->ap);

  return SHISHI_OK;
}