Пример #1
0
/**
 * shishi_authenticator_to_file:
 * @handle: shishi handle as allocated by shishi_init().
 * @authenticator: Authenticator to save.
 * @filetype: input variable specifying type of file to be written,
 *            see Shishi_filetype.
 * @filename: input variable with filename to write to.
 *
 * Write Authenticator to file in specified TYPE.  The file will be
 * truncated if it exists.
 *
 * Return value: Returns SHISHI_OK iff successful.
 **/
int
shishi_authenticator_to_file (Shishi * handle, Shishi_asn1 authenticator,
                              int filetype, const char *filename)
{
    FILE *fh;
    int res;

    if (VERBOSE (handle))
        printf (_("Writing Authenticator to %s...\n"), filename);

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

    if (VERBOSE (handle))
        printf (_("Writing Authenticator in %s format...\n"),
                filetype == SHISHI_FILETYPE_TEXT ? "TEXT" : "DER");

    if (filetype == SHISHI_FILETYPE_TEXT)
        res = shishi_authenticator_print (handle, fh, authenticator);
    else
        res = shishi_authenticator_save (handle, fh, authenticator);
    if (res != SHISHI_OK)
        return res;

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

    if (VERBOSE (handle))
        printf (_("Writing Authenticator to %s...done\n"), filename);

    return SHISHI_OK;
}
Пример #2
0
/* shishi authentication */
int
auth (Shishi * h, int verbose, const char *cname, const char *sname, int sock,
      char *cmd, char *port, Shishi_key ** enckey, Shishi_key * deckey)
{
  Shishi_ap *ap;
  Shishi_tkt *tkt;
  Shishi_tkts_hint hint;

  int rc;
  char *out;
  int outlen;
  int krb5len, msglen;
  char auth;
  /* KERBEROS 5 SENDAUTH MESSAGE */
  char krb5sendauth[] = "KRB5_SENDAUTH_V1.0";
  /* PROTOCOL VERSION */
  char krb5sendclient[] = "KCMDV0.2";
  /* to store error msg sent by server */
  char errormsg[101];
  char cksumdata[101];

  /* size of KRB5 auth message */
  krb5len = strlen (krb5sendauth) + 1;
  msglen = htonl (krb5len);
  safewrite (sock, &msglen, sizeof (int));
  /* KRB5 authentication message */
  safewrite (sock, krb5sendauth, krb5len);
  /* size of client message */
  krb5len = strlen (krb5sendclient) + 1;
  msglen = htonl (krb5len);
  safewrite (sock, &msglen, sizeof (int));
  /* KRB5 client message */
  safewrite (sock, krb5sendclient, krb5len);

  /* get answer from server 0 = ok, 1 = error with message */
  read (sock, &auth, 1);
  if (auth)
    {
      read (sock, errormsg, 100);
      errormsg[100] = '\0';

      printf ("Error during server authentication : %s\n", errormsg);
      return 1;
    }

  if (verbose)
    {
      printf ("Client: %s\n", cname);
      printf ("Server: %s\n", sname);
    }

  /* Get a ticket for the server. */

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

  hint.client = (char *) cname;
  hint.server = (char *) sname;

  tkt = shishi_tkts_get (shishi_tkts_default (h), &hint);
  if (!tkt)
    {
      printf ("cannot find ticket for \"%s\"\n", sname);
      return 1;
    }

  if (verbose)
    shishi_tkt_pretty_print (tkt, stderr);

  /* Create Authentication context */

  rc = shishi_ap_tktoptions (h, &ap, tkt, SHISHI_APOPTIONS_MUTUAL_REQUIRED);
  if (rc != SHISHI_OK)
    {
      printf ("cannot create authentication context\n");
      return 1;
    }


  /* checksum = port: terminal name */

  snprintf (cksumdata, 100, "%s:%s%s", port, cmd, cname);

  /* add checksum to authenticator */

  shishi_ap_authenticator_cksumdata_set (ap, cksumdata, strlen (cksumdata));
  /* To be compatible with MIT rlogind */
  shishi_ap_authenticator_cksumtype_set (ap, SHISHI_RSA_MD5);

  /* create der encoded AP-REQ */

  rc = shishi_ap_req_der (ap, &out, &outlen);
  if (rc != SHISHI_OK)
    {
      printf ("cannot build authentication request: %s\n",
	      shishi_strerror (rc));

      return 1;
    }

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

  /* extract subkey if present from ap exchange for secure connection */

  shishi_authenticator_get_subkey (h, shishi_ap_authenticator (ap), enckey);

  /* send size of AP-REQ to the server */

  msglen = htonl (outlen);
  safewrite (sock, (char *) &msglen, sizeof (int));

  /* send AP-REQ to the server */

  safewrite (sock, out, outlen);

  /* read a respond from server - what ? */

  read (sock, &auth, sizeof (int));

  /* For mutual authentication, wait for server reply. */

  if (shishi_apreq_mutual_required_p (h, shishi_ap_req (ap)))
    {
      if (verbose)
	printf ("Waiting for server to authenticate itself...\n");

      /* read size of the AP-REP */

      read (sock, (char *) &outlen, sizeof (int));

      /* read AP-REP */
      outlen = ntohl (outlen);
      outlen = read (sock, out, outlen);

      rc = shishi_ap_rep_verify_der (ap, out, outlen);
      if (rc == SHISHI_OK)
	{
	  if (verbose)
	    printf ("AP-REP verification OK...\n");
	}
      else
	{
	  if (rc == SHISHI_APREP_VERIFY_FAILED)
	    printf ("AP-REP verification failed...\n");
	  else
	    printf ("AP-REP verification error: %s\n", shishi_strerror (rc));
	  return 1;
	}

      /* The server is authenticated. */
      if (verbose)
	printf ("Server authenticated.\n");
    }

  /* We are now authenticated. */
  if (verbose)
    printf ("User authenticated.\n");

  return AUTH_OK;

}
Пример #3
0
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;
}
Пример #4
0
static Shishi_ap *
auth (Shishi * h, int verbose, const char *cname, const char *sname)
{
  Shishi_ap *ap;
  Shishi_tkt *tkt;
  Shishi_tkts_hint hint;
  int rc;

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

  /* Get a ticket for the server. */

  memset (&hint, 0, sizeof (hint));
  hint.client = (char *) cname;
  hint.server = (char *) sname;
  tkt = shishi_tkts_get (shishi_tkts_default (h), &hint);
  if (!tkt)
    {
      printf ("cannot find ticket for \"%s\"\n", sname);
      return NULL;
    }

  if (verbose)
    shishi_tkt_pretty_print (tkt, stderr);

  /* Create Authentication context */

  rc = shishi_ap_tktoptions (h, &ap, tkt, SHISHI_APOPTIONS_MUTUAL_REQUIRED);
  if (rc != SHISHI_OK)
    {
      printf ("cannot create authentication context\n");
      return NULL;
    }

  /* Build Authentication request */

  rc = shishi_ap_req_build (ap);
  if (rc != SHISHI_OK)
    {
      printf ("cannot build authentication request: %s\n",
	      shishi_strerror (rc));
      return NULL;
    }

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

  /* Authentication ourself to server */

  shishi_apreq_print (h, stdout, shishi_ap_req (ap));
  /* Note: to get the binary blob to send, use:
   *
   * char *out; int outlen;
   * ...
   * rc = shishi_ap_req_der (ap, &out, &outlen);
   * ...
   * write(fd, out, outlen);
   */

  /* For mutual authentication, wait for server reply. */

  if (shishi_apreq_mutual_required_p (h, shishi_ap_req (ap)))
    {
      Shishi_asn1 aprep;

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

      rc = shishi_aprep_parse (h, stdin, &aprep);
      if (rc != SHISHI_OK)
	{
	  printf ("Cannot parse AP-REP from server: %s\n",
		  shishi_strerror (rc));
	  return NULL;
	}

      rc = shishi_ap_rep_verify_asn1 (ap, aprep);
      if (rc == SHISHI_OK)
	printf ("AP-REP verification OK...\n");
      else
	{
	  if (rc == SHISHI_APREP_VERIFY_FAILED)
	    printf ("AP-REP verification failed...\n");
	  else
	    printf ("AP-REP verification error: %s\n", shishi_strerror (rc));
	  return NULL;
	}

      /* The server is authenticated. */
      printf ("Server authenticated.\n");
    }

  /* We are now authenticated. */
  printf ("User authenticated.\n");

  return ap;
}
Пример #5
0
void
test (Shishi * handle)
{
  Shishi_asn1 a;
  char *p, *buf, *buf2;
  int res;
  size_t n, m;
  int32_t t;
  uint32_t s;

  /* shishi_authenticator */
  a = shishi_authenticator (handle);
  if (debug)
    printf ("shishi_authenticator () => `%p'.\n", a);
  if (a)
    success ("shishi_authenticator() OK\n");
  else
    fail ("shishi_authenticator() failed\n");

  if (debug)
    shishi_authenticator_print (handle, stdout, a);

  res = shishi_authenticator_remove_subkey (handle, a);
  if (res == SHISHI_OK)
    success ("shishi_authenticator_remove_subkey() OK\n");
  else
    fail ("shishi_authenticator_remove_subkey() failed\n");

  /* shishi_authenticator_seqnumber_get */
  res = shishi_authenticator_seqnumber_get (handle, a, &s);
  if (res == SHISHI_OK)
    success ("shishi_authenticator_seqnumber_get() OK\n");
  else
    fail ("shishi_authenticator_seqnumber_get() failed\n");

  /* shishi_authenticator_seqnumber_set */
  res = shishi_authenticator_seqnumber_set (handle, a, 42);
  if (res == SHISHI_OK)
    success ("shishi_authenticator_seqnumber_set() OK\n");
  else
    fail ("shishi_authenticator_seqnumber_set() failed\n");

  /* shishi_authenticator_seqnumber_get */
  res = shishi_authenticator_seqnumber_get (handle, a, &s);
  if (res == SHISHI_OK && s == 42)
    success ("shishi_authenticator_seqnumber_get() OK\n");
  else
    fail ("shishi_authenticator_seqnumber_get() failed\n");

  /* shishi_authenticator_seqnumber_remove */
  res = shishi_authenticator_seqnumber_remove (handle, a);
  if (res == SHISHI_OK)
    success ("shishi_authenticator_seqnumber_remove() OK\n");
  else
    fail ("shishi_authenticator_seqnumber_remove() failed\n");

  /* shishi_authenticator_set_crealm */
  res = shishi_authenticator_set_crealm (handle, a, "foo");
  if (res == SHISHI_OK)
    success ("shishi_authenticator_set_crealm() OK\n");
  else
    fail ("shishi_authenticator_set_crealm() failed\n");

  /* shishi_authenticator_client_set */
  res = shishi_authenticator_client_set (handle, a, "foo/bar/baz");
  if (res == SHISHI_OK)
    success ("shishi_authenticator_client_set() OK\n");
  else
    fail ("shishi_authenticator_client_set() failed\n");

  /* shishi_authenticator_client */
  res = shishi_authenticator_client (handle, a, &buf, &n);
  if (debug)
    escapeprint (buf, n);
  if (res == SHISHI_OK &&
      n == strlen ("foo/bar/baz") && memcmp (buf, "foo/bar/baz", n) == 0)
    success ("shishi_authenticator_client() OK\n");
  else
    fail ("shishi_authenticator_client() failed\n");
  if (res == SHISHI_OK)
    free (buf);

  /* shishi_authenticator_client_set */
  res = shishi_authenticator_client_set (handle, a, "foo");
  if (res == SHISHI_OK)
    success ("shishi_authenticator_client_set() OK\n");
  else
    fail ("shishi_authenticator_client_set() failed\n");

  /* shishi_authenticator_client */
  res = shishi_authenticator_client (handle, a, &buf, &n);
  if (debug)
    escapeprint (buf, n);
  if (res == SHISHI_OK && n == strlen ("foo") && memcmp (buf, "foo", n) == 0)
    success ("shishi_authenticator_client() OK\n");
  else
    fail ("shishi_authenticator_client() failed\n");
  if (res == SHISHI_OK)
    free (buf);

  /* shishi_authenticator_set_crealm */
  res = shishi_authenticator_set_crealm (handle, a, "bar");
  if (res == SHISHI_OK)
    success ("shishi_authenticator_set_crealm() OK\n");
  else
    fail ("shishi_authenticator_set_crealm() failed\n");

  /* shishi_authenticator_clientrealm */
  res = shishi_authenticator_clientrealm (handle, a, &buf, &n);
  if (debug)
    escapeprint (buf, n);
  if (res == SHISHI_OK &&
      n == strlen ("foo@bar") && memcmp (buf, "foo@bar", n) == 0)
    success ("shishi_authenticator_clientrealm() OK\n");
  else
    fail ("shishi_authenticator_clientrealm() failed\n");
  if (res == SHISHI_OK)
    free (buf);

  /* shishi_authenticator_add_authorizationdata */
  res = shishi_authenticator_add_authorizationdata (handle, a, 42, "baz", 3);
  if (res == SHISHI_OK)
    success ("shishi_authenticator_add_authorizationdata() OK\n");
  else
    fail ("shishi_authenticator_add_authorizationdata() failed\n");

  /* shishi_authenticator_authorizationdata */
  res = shishi_authenticator_authorizationdata (handle, a, &t, &buf, &m, 1);
  if (debug)
    escapeprint (buf, m);
  if (res == SHISHI_OK && t == 42 && m == 3 && memcmp (buf, "baz", 3) == 0)
    success ("shishi_authenticator_authorizationdata() OK\n");
  else
    fail ("shishi_authenticator_authorizationdata() failed\n");
  if (res == SHISHI_OK)
    free (buf);

  /* shishi_authenticator_authorizationdata */
  res = shishi_authenticator_authorizationdata (handle, a, &t, &buf, &m, 2);
  if (res == SHISHI_OK)
    free (buf);
  if (res == SHISHI_OUT_OF_RANGE)
    success ("shishi_authenticator_authorizationdata() OK\n");
  else
    fail ("shishi_authenticator_authorizationdata() failed\n");

  /* shishi_authenticator_remove_cksum */
  res = shishi_authenticator_remove_cksum (handle, a);
  if (res == SHISHI_OK)
    success ("shishi_authenticator_remove_cksum() OK\n");
  else
    fail ("shishi_authenticator_remove_cksum() failed\n");

  /* shishi_asn1_to_der */
  res = shishi_asn1_to_der (handle, a, &buf, &n);
  if (res == SHISHI_OK)
    success ("shishi_asn1_to_der() OK\n");
  else
    n = 0, fail ("shishi_asn1_to_der() failed\n");

  /* shishi_authenticator_to_file */
  res = shishi_authenticator_to_file (handle, a, SHISHI_FILETYPE_TEXT,
				      "authenticator.tmp");
  if (res == SHISHI_OK)
    success ("shishi_authenticator_to_file() OK\n");
  else
    fail ("shishi_authenticator_to_file() failed\n");

  /* shishi_asn1_done */
  shishi_asn1_done (handle, a);
  success ("shishi_asn1_done() OK\n");

  a = NULL;

  /* shishi_authenticator_from_file */
  res = shishi_authenticator_from_file (handle, &a, SHISHI_FILETYPE_TEXT,
					"authenticator.tmp");
  if (res == SHISHI_OK)
    success ("shishi_authenticator_from_file() OK\n");
  else
    fail ("shishi_authenticator_from_file() failed\n");

  if (debug)
    {
      /* shishi_authenticator_print */
      res = shishi_authenticator_print (handle, stdout, a);
      if (res == SHISHI_OK)
	success ("shishi_authenticator_print() OK\n");
      else
	fail ("shishi_authenticator_print() failed\n");
    }

  /* shishi_asn1_to_der */
  res = shishi_asn1_to_der (handle, a, &buf2, &m);
  if (res == SHISHI_OK)
    success ("shishi_asn1_to_der() OK\n");
  else
    n = 0, fail ("shishi_asn1_to_der() failed\n");

  /* Compare DER encodings of authenticators */
  if (n > 0 && m > 0 && n == m && memcmp (buf, buf2, n) == 0)
    success ("DER comparison OK\n");
  else
    fail ("DER comparison failed\n");

  free (buf);
  free (buf2);

  /* shishi_authenticator_cusec_set */
  res = shishi_authenticator_cusec_set (handle, a, 4711);
  if (res == SHISHI_OK)
    success ("shishi_authenticator_cusec_set() OK\n");
  else
    fail ("shishi_authenticator_cusec_set() failed\n");

  /* shishi_authenticator_cusec_get */
  res = shishi_authenticator_cusec_get (handle, a, &s);
  if (debug)
    printf ("shishi_authenticator_cusec_get () => `%d'.\n", t);
  if (res == SHISHI_OK && s == 4711)
    success ("shishi_authenticator_cusec_get() OK\n");
  else
    fail ("shishi_authenticator_cusec_get() failed\n");

  /* shishi_authenticator_ctime_set */
  res = shishi_authenticator_ctime_set (handle, a, "19700101011831Z");
  if (res == SHISHI_OK)
    success ("shishi_authenticator_ctime_set() OK\n");
  else
    fail ("shishi_authenticator_ctime_set() failed\n");

  /* shishi_authenticator_ctime */
  res = shishi_authenticator_ctime (handle, a, &p);
  if (debug)
    escapeprint (p, strlen (p));
  if (res == SHISHI_OK && memcmp (p, "19700101011831Z", 15) == 0)
    success ("shishi_authenticator_ctime() OK\n");
  else
    fail ("shishi_authenticator_ctime() failed\n");
  if (res == SHISHI_OK)
    free (p);

  /* shishi_asn1_to_der */
  res = shishi_asn1_to_der (handle, a, &buf, &n);
  if (res == SHISHI_OK)
    success ("shishi_asn1_to_der() OK\n");
  else
    n = 0, fail ("shishi_asn1_to_der() failed\n");
  if (debug)
    {
      shishi_authenticator_print (handle, stdout, a);
      hexprint (buf, n);
      puts ("");
      hexprint (authenticator, sizeof (authenticator));
      puts ("");
    }
  if (n == sizeof (authenticator) &&
      n == AUTHENTICATOR_LEN && memcmp (authenticator, buf, n) == 0)
    success ("DER comparison OK\n");
  else
    fail ("DER comparison failed\n");

  free (buf);

  /* shishi_authenticator_clear_authorizationdata */
  res = shishi_authenticator_clear_authorizationdata (handle, a);
  if (res == SHISHI_OK)
    success ("shishi_authenticator_clear_authorizationdata() OK\n");
  else
    fail ("shishi_authenticator_clear_authorizationdata() failed\n");

  /* shishi_asn1_to_der */
  res = shishi_asn1_to_der (handle, a, &buf, &n);
  if (res == SHISHI_OK)
    success ("shishi_asn1_to_der() OK\n");
  else
    n = 0, fail ("shishi_asn1_to_der() failed\n");
  if (debug)
    {
      shishi_authenticator_print (handle, stdout, a);
      hexprint (buf, n);
      puts ("");
      hexprint (authenticator2, sizeof (authenticator2));
      puts ("");
    }
  if (n == sizeof (authenticator2) &&
      n == AUTHENTICATOR2_LEN && memcmp (authenticator2, buf, n) == 0)
    success ("DER comparison OK\n");
  else
    fail ("DER comparison failed\n");

  free (buf);

  /* unlink */
  res = unlink ("authenticator.tmp");
  if (res == 0)
    success ("unlink() OK\n");
  else
    fail ("unlink() failed\n");

  /* shishi_asn1_done */
  shishi_asn1_done (handle, a);
  success ("shishi_asn1_done() OK\n");
}