示例#1
0
文件: server.c 项目: Jactry/shishi
static int
doit (Shishi * h, Shishi_ap * ap, int verbose)
{
  Shishi_asn1 asn1safe;
  Shishi_safe *safe;
  char *userdata;
  size_t userdatalen;
  int res;

  printf ("Application exchange start.  Press ^D to finish.\n");

  while ((res = shishi_safe_parse (h, stdin, &asn1safe)) == SHISHI_OK)
    {
      if (res != SHISHI_OK)
	{
	  fprintf (stderr, "Could not read SAFE:\n%s\n%s\n",
		   shishi_strerror (res), shishi_error (h));
	  return 1;
	}

      res = shishi_safe (h, &safe);
      if (res != SHISHI_OK)
	{
	  fprintf (stderr, "Could not create SAFE:\n%s\n%s\n",
		   shishi_strerror (res), shishi_error (h));
	  return 1;
	}

      shishi_safe_safe_set (safe, asn1safe);

      res = shishi_safe_verify (safe, shishi_ap_key (ap));
      if (res != SHISHI_OK)
	{
	  fprintf (stderr, "Could not verify SAFE:\n%s\n%s\n",
		   shishi_strerror (res), shishi_error (h));
	  return 1;
	}

      printf ("Verified SAFE successfully...\n");

      res = shishi_safe_user_data (h, asn1safe, &userdata, &userdatalen);
      if (res != SHISHI_OK)
	{
	  fprintf (stderr, "Could not extract user data:\n%s\n%s\n",
		   shishi_strerror (res), shishi_error (h));
	  return 1;
	}
      userdata[userdatalen] = '\0';
      printf ("user data: `%s'\n", userdata);

    }

  if (ferror (stdin))
    {
      printf ("error reading stdin\n");
      return 1;
    }

  return 0;
}
示例#2
0
文件: tgs.c 项目: Jactry/shishi
/**
 * shishi_tgs:
 * @handle: shishi handle as allocated by shishi_init().
 * @tgs: holds pointer to newly allocate Shishi_tgs structure.
 *
 * Allocate a new TGS exchange variable.
 *
 * Return value: Returns SHISHI_OK iff successful.
 **/
int
shishi_tgs (Shishi * handle, Shishi_tgs ** tgs)
{
  Shishi_tgs *ltgs;
  int res;

  *tgs = xcalloc (1, sizeof (**tgs));
  ltgs = *tgs;

  ltgs->handle = handle;

  ltgs->tgsreq = shishi_tgsreq (handle);
  if (ltgs->tgsreq == NULL)
    {
      shishi_error_printf (handle, "Could not create TGS-REQ: %s\n",
			   shishi_error (handle));
      return SHISHI_ASN1_ERROR;
    }

  ltgs->tgsrep = shishi_tgsrep (handle);
  if (ltgs->tgsreq == NULL)
    {
      shishi_error_printf (handle, "Could not create TGS-REP: %s\n",
			   shishi_error (handle));
      return SHISHI_ASN1_ERROR;
    }

  ltgs->krberror = shishi_krberror (handle);
  if (ltgs->krberror == NULL)
    {
      shishi_error_printf (handle, "Could not create KRB-ERROR: %s\n",
			   shishi_error (handle));
      return SHISHI_ASN1_ERROR;
    }

  res = shishi_ap_nosubkey (handle, &ltgs->ap);
  if (res != SHISHI_OK)
    return res;

  res = shishi_authenticator_remove_subkey
    (handle, shishi_ap_authenticator (ltgs->ap));
  if (res != SHISHI_OK)
    return res;

  res = shishi_tkt (handle, &ltgs->tkt);
  if (res != SHISHI_OK)
    return res;

  return SHISHI_OK;
}
示例#3
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;
}
示例#4
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");
    }
}
示例#5
0
/* authentication, server side */
int
get_auth (int infd, krb5_context *ctx, krb5_auth_context *actx,
	  krb5_keyblock **key, const char **err_msg,
	  int *protoversion, int *cksumtype,
	  char **cksum, size_t *cksumlen, char *srvname)
{
  char *out;
  size_t outlen;
  char *buf;
  int buflen;
  int len;
  int rc;
  int error;
  /* KERBEROS 5 SENDAUTH MESSAGE */
  char krb5sendauth[] = "KRB5_SENDAUTH_V1.0";
  /* PROTOCOL VERSION */
  char krb5kcmd1[] = "KCMDV0.1";
  char krb5kcmd2[] = "KCMDV0.2";
  char *servername, *server = NULL, *realm = NULL;

  *err_msg = NULL;
  /* Get key for the server. */

# if 0
  /*
   * XXX: Taken straight from the version for libshishi.
   * XXX: No adaptions yet.
   */
  rc = shishi_init_server (handle);
  if (rc != SHISHI_OK)
    return rc;

  if (srvname && *srvname)
    {
      rc = shishi_parse_name (*handle, srvname, &server, &realm);
      if (rc != SHISHI_OK)
	{
	  *err_msg = shishi_strerror (rc);
	  return rc;
	}
    }

  if (server && *server)
    {
      char *p;

      servername = malloc (sizeof (SERVICE) + strlen (server) + 2);
      if (!servername)
	{
	  *err_msg = "Not enough memory";
	  return SHISHI_TOO_SMALL_BUFFER;
	}

      p = strchr (server, '/');
      if (p && (p != server))
	sprintf (servername, "%s", server);	/* Non-empty prefix.  */
      else
	sprintf (servername, "%s/%s", SERVICE,
		 server + (p ? 1 : 0));	/* Remove initial slash.  */
    }
  else
    servername = shishi_server_for_local_service (*handle, SERVICE);

  if (realm && *realm)
    shishi_realm_default_set (*handle, realm);

  free (server);
  free (realm);

  /* Enable use of `~/.k5login'.  */
  if (shishi_check_version ("1.0.2"))	/* Faulty in version 1.0.1.  */
    {
      rc = shishi_cfg_authorizationtype_set (*handle, "k5login basic");
      if (rc != SHISHI_OK)
	{
	  *err_msg = shishi_error (*handle);
	  return rc;
	}
    }

  key = shishi_hostkeys_for_serverrealm (*handle, servername,
					 shishi_realm_default (*handle));
  free (servername);
  if (!key)
    {
      *err_msg = shishi_error (*handle);
      return SHISHI_INVALID_KEY;
    }

  /* Read Kerberos 5 sendauth message */
  rc = read (infd, &len, sizeof (int));
  if (rc != sizeof (int))
    {
      *err_msg = "Error reading message size";
      return SHISHI_IO_ERROR;
    }

  buflen = ntohl (len);
  buf = malloc (buflen);
  if (!buf)
    {
      *err_msg = "Not enough memory";
      return SHISHI_TOO_SMALL_BUFFER;
    }

  rc = read (infd, buf, buflen);
  if (rc != buflen)
    {
      *err_msg = "Error reading authentication message";
      return SHISHI_IO_ERROR;
    }

  len = strlen (krb5sendauth);
  rc = strncmp (buf, krb5sendauth, buflen >= len ? len : buflen);
  if (rc)
    {
      *err_msg = "Invalid authentication type";
      /* Authentication type is wrong.  */
      write (infd, "\001", 1);
      return SHISHI_VERIFY_FAILED;
    }

  free (buf);

  /* Read protocol version */
  rc = read (infd, &len, sizeof (int));
  if (rc != sizeof (int))
    {
      *err_msg = "Error reading protocol message size";
      return SHISHI_IO_ERROR;
    }
  buflen = ntohl (len);
  buf = malloc (buflen);
  if (!buf)
    {
      *err_msg = "Not enough memory";
      return SHISHI_TOO_SMALL_BUFFER;
    }

  rc = read (infd, buf, buflen);
  if (rc != buflen)
    {
      *err_msg = "Error reading protocol message";
      return SHISHI_IO_ERROR;
    }

  len = strlen (krb5kcmd1);
  rc = strncmp (buf, krb5kcmd1, buflen >= len ? len : buflen);
  if (rc)
    {
      len = strlen (krb5kcmd2);
      rc = strncmp (buf, krb5kcmd2, buflen >= len ? len : buflen);
      if (rc)
	{
	  *err_msg = "Protocol version not supported";
	  /* Protocol version is wrong.  */
	  write (infd, "\002", 1);
	  return SHISHI_VERIFY_FAILED;
	}
      *protoversion = 2;
    }
  else
    *protoversion = 1;

  free (buf);

  /* Authentication type is ok */

  write (infd, "\0", 1);

  /* Read Authentication request from client */

  rc = read (infd, &len, sizeof (int));
  if (rc != sizeof (int))
    {
      *err_msg = "Error reading authentication request size";
      return SHISHI_IO_ERROR;
    }

  buflen = ntohl (len);
  buf = malloc (buflen);
  if (!buf)
    {
      *err_msg = "Not enough memory";
      return SHISHI_TOO_SMALL_BUFFER;
    }

  rc = read (infd, buf, buflen);
  if (rc != buflen)
    {
      *err_msg = "Error reading authentication request";
      return SHISHI_IO_ERROR;
    }

  /* Create Authentication context */

  rc = shishi_ap_nosubkey (*handle, ap);
  if (rc != SHISHI_OK)
    return rc;

  /* Store request in context */

  rc = shishi_ap_req_der_set (*ap, buf, buflen);
  if (rc != SHISHI_OK)
    return rc;

  free (buf);

  /* Process authentication request */

  rc = shishi_ap_req_process (*ap, key);
  if (rc != SHISHI_OK)
    return rc;

# ifdef ENCRYPTION

  /* extract subkey if present from ap exchange for secure connection */
  if (*protoversion == 2)
    {
      *enckey = NULL;
      shishi_authenticator_get_subkey (*handle,
				       shishi_ap_authenticator (*ap), enckey);
    }

# endif

  /* Get authenticator checksum */
  rc = shishi_authenticator_cksum (*handle,
				   shishi_ap_authenticator (*ap),
				   cksumtype, cksum, cksumlen);
  if (rc != SHISHI_OK)
    return rc;

  /* User is authenticated.  */
  error = 0;
  write (infd, &error, sizeof (int));

  /* Authenticate ourself to client, if requested.  */

  if (shishi_apreq_mutual_required_p (*handle, shishi_ap_req (*ap)))
    {
      int len;

      rc = shishi_ap_rep_der (*ap, &out, &outlen);
      if (rc != SHISHI_OK)
	return rc;

      len = outlen;
      len = htonl (len);
      rc = write (infd, &len, sizeof (len));
      if (rc != sizeof (int))
	{
	  *err_msg = "Error sending AP-REP";
	  free (out);
	  return SHISHI_IO_ERROR;
	}

      rc = write (infd, out, ntohl (len));
      if (rc != (int) ntohl (len))
	{
	  *err_msg = "Error sending AP-REP";
	  free (out);
	  return SHISHI_IO_ERROR;
	}

      free (out);

      /* We are authenticated to client */
    }

# ifdef ENCRYPTION
  if (*protoversion == 1)
    {
      Shishi_tkt *tkt;

      tkt = shishi_ap_tkt (*ap);
      if (tkt == NULL)
	{
	  *err_msg = "Could not get tkt from AP-REQ";
	  return SHISHI_INVALID_TICKET;
	}

      rc = shishi_encticketpart_get_key (*handle,
					 shishi_tkt_encticketpart (tkt),
					 enckey);
      if (rc != SHISHI_OK)
	return rc;
    }
# endif /* ENCRYPTION */

  return 0;
# else
  return -1;
# endif
}
示例#6
0
文件: server.c 项目: Jactry/shishi
static Shishi_ap *
auth (Shishi * h, int verbose, const char *cname, const char *sname)
{
  Shishi_key *key;
  Shishi_ap *ap;
  Shishi_asn1 apreq;
  char *buf;
  size_t buflen;
  int rc;

  printf ("Client: %s\n", cname);
  printf ("Server: %s\n", sname);

  /* Get key for the server. */

  key = shishi_hostkeys_for_server (h, sname);
  if (!key)
    {
      printf ("could not find key: %s\n", shishi_error (h));
      return NULL;
    }

  if (verbose)
    shishi_key_print (h, stderr, key);

  /* Read Authentication request from client */

  printf ("Waiting for client to authenticate itself...\n");

  rc = shishi_apreq_parse (h, stdin, &apreq);
  if (rc != SHISHI_OK)
    {
      printf ("could not read AP-REQ: %s\n", shishi_strerror (rc));
      return NULL;
    }

  /* Create Authentication context */

  rc = shishi_ap (h, &ap);
  if (rc != SHISHI_OK)
    {
      printf ("Could not create AP: %s\n", shishi_strerror (rc));
      return NULL;
    }

  /* Store request in context */

  shishi_ap_req_set (ap, apreq);

  /* Process authentication request */

  rc = shishi_ap_req_process (ap, key);
  if (rc != SHISHI_OK)
    {
      printf ("Could not process AP-REQ: %s\n", shishi_strerror (rc));
      return NULL;
    }

  if (verbose)
    shishi_authenticator_print (h, stderr, shishi_ap_authenticator (ap));

  rc = shishi_authenticator_client (h, shishi_ap_authenticator (ap),
				    &buf, &buflen);
  printf ("Client name (from authenticator): %.*s\n", (int) buflen, buf);
  free (buf);

  rc = shishi_encticketpart_clientrealm
    (h, shishi_tkt_encticketpart (shishi_ap_tkt (ap)), &buf, &buflen);
  printf ("Client name (from encticketpart): %.*s\n", (int) buflen, buf);
  free (buf);

  rc = shishi_ticket_server (h, shishi_tkt_ticket (shishi_ap_tkt (ap)),
			     &buf, &buflen);
  printf ("Server name (from ticket): %.*s\n", (int) buflen, buf);
  free (buf);

  /* User is authenticated. */

  printf ("User authenticated.\n");

  /* Authenticate ourself to client, if request */

  if (shishi_apreq_mutual_required_p (h, apreq))
    {
      Shishi_asn1 aprep;

      printf ("Mutual authentication required.\n");

      rc = shishi_ap_rep_asn1 (ap, &aprep);
      if (rc != SHISHI_OK)
	{
	  printf ("Error creating AP-REP: %s\n", shishi_strerror (rc));
	  return NULL;
	}

      if (verbose)
	shishi_encapreppart_print (h, stderr, shishi_ap_encapreppart (ap));

      shishi_aprep_print (h, stdout, aprep);

      /* We are authenticated to client */
    }

  return ap;
}
示例#7
0
int
get_auth (int infd, Shishi ** handle, Shishi_ap ** ap,
	  Shishi_key ** enckey, const char **err_msg, int *protoversion,
	  int *cksumtype, char **cksum, int *cksumlen)
{
  Shishi_key *key;
  char *out;
  int outlen;
  char *buf;
  int buflen;
  int len;
  int rc;
  int i;
  int error;
  /* KERBEROS 5 SENDAUTH MESSAGE */
  char krb5sendauth[] = "KRB5_SENDAUTH_V1.0";
  /* PROTOCOL VERSION */
  char krb5kcmd1[] = "KCMDV0.1";
  char krb5kcmd2[] = "KCMDV0.2";
  int auth_correct = 0;
  char *servername;

  *err_msg = NULL;
  /* Get key for the server. */

  if (!shishi_check_version (SHISHI_VERSION))
    {
      *err_msg =
	"shishi_check_version() failed: header file incompatible with shared library.";
      return 1;
    }

  rc = shishi_init_server (handle);
  if (rc != SHISHI_OK)
    return rc;

  servername = shishi_server_for_local_service (*handle, SERVICE);

  key = shishi_hostkeys_for_server (*handle, servername);
  if (!key)
    {
      *err_msg = shishi_error (*handle);
      return 1;
    }

  /* Read Kerberos 5 sendauth message */
  rc = read (infd, &len, sizeof (int));
  if (rc != sizeof (int))
    {
      *err_msg = "Error reading message size";
      return 1;
    }

  buflen = ntohl (len);
  buf = malloc (buflen);
  if (!buf)
    {
      *err_msg = "Not enough memory";
      return 1;
    }

  rc = read (infd, buf, buflen);
  if (rc != buflen)
    {
      *err_msg = "Error reading authentication message";
      return 1;
    }

  len = strlen (krb5sendauth);
  rc = strncmp (buf, krb5sendauth, buflen >= len ? len : buflen);
  if (rc)
    {
      *err_msg = "Invalid authentication type";
      return 1;
    }

  free (buf);

  /* Read protocol version */
  rc = read (infd, &len, sizeof (int));
  if (rc != sizeof (int))
    {
      *err_msg = "Error reading protocol message size";
      return 1;
    }
  buflen = ntohl (len);
  buf = malloc (buflen);
  if (!buf)
    {
      *err_msg = "Not enough memory";
      return 1;
    }

  rc = read (infd, buf, buflen);
  if (rc != buflen)
    {
      *err_msg = "Error reading protocol message";
      return 1;
    }

  len = strlen (krb5kcmd1);
  rc = strncmp (buf, krb5kcmd1, buflen >= len ? len : buflen);
  if (rc)
    {
      len = strlen (krb5kcmd2);
      rc = strncmp (buf, krb5kcmd2, buflen >= len ? len : buflen);
      if (rc)
	{
	  *err_msg = "Protocol version not supported";
	  return 1;
	}
      *protoversion = 2;
    }
  else
    *protoversion = 1;

  free (buf);

  /* Authentication type is ok */

  write (infd, "\0", 1);

  /* Read Authentication request from client */

  rc = read (infd, &len, sizeof (int));
  if (rc != sizeof (int))
    {
      *err_msg = "Error reading authentication request size";
      return 1;
    }

  buflen = ntohl (len);
  buf = malloc (buflen);
  if (!buf)
    {
      *err_msg = "Not enough memory";
      return 1;
    }

  rc = read (infd, buf, buflen);
  if (rc != buflen)
    {
      *err_msg = "Error reading authentication request";
      return 1;
    }

  /* Create Authentication context */

  rc = shishi_ap_nosubkey (*handle, ap);
  if (rc != SHISHI_OK)
    return rc;

  /* Store request in context */

  shishi_ap_req_der_set (*ap, buf, buflen);
  if (rc != SHISHI_OK)
    return rc;

  free (buf);

  /* Process authentication request */

  rc = shishi_ap_req_process (*ap, key);
  if (rc != SHISHI_OK)
    return rc;

# ifdef ENCRYPTION

  /* extract subkey if present from ap exchange for secure connection */
  if (*protoversion == 2)
    {
      *enckey = NULL;
      shishi_authenticator_get_subkey (*handle,
				       shishi_ap_authenticator (*ap), enckey);
    }

# endif

  /* Get authenticator checksum */
  rc = shishi_authenticator_cksum (*handle,
				   shishi_ap_authenticator (*ap),
				   cksumtype, cksum, cksumlen);
  if (rc != SHISHI_OK)
    return rc;

  /* User is authenticated. */
  error = 0;
  write (infd, &error, sizeof (int));

  /* Authenticate ourself to client, if request */

  if (shishi_apreq_mutual_required_p (*handle, shishi_ap_req (*ap)))
    {
      rc = shishi_ap_rep_der (*ap, &out, &outlen);
      if (rc != SHISHI_OK)
	return rc;

      outlen = htonl (outlen);
      rc = write (infd, &outlen, sizeof (int));
      if (rc != sizeof (int))
	{
	  *err_msg = "Error sending AP-REP";
	  free (out);
	  return 1;
	}

      rc = write (infd, out, ntohl (outlen));
      if (rc != ntohl (outlen))
	{
	  *err_msg = "Error sending AP-REP";
	  free (out);
	  return 1;
	}

      free (out);

      /* We are authenticated to client */
    }

# ifdef ENCRYPTION
  if (*protoversion == 1)
    {
      Shishi_tkt *tkt;

      tkt = shishi_ap_tkt (*ap);
      if (tkt == NULL)
	{
	  *err_msg = "Could not get tkt from AP-REQ";
	  return 1;
	}

      rc = shishi_encticketpart_get_key (*handle,
					 shishi_tkt_encticketpart (tkt),
					 enckey);
      if (rc != SHISHI_OK)
	return rc;
    }
# endif

  return SHISHI_OK;
}