Exemple #1
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;
}
Exemple #2
0
/* read encrypted data on socket */
int
readenc (Shishi * h, int sock, char *buf, int *len, char *iv, int *ivlen,
	 Shishi_key * enckey)
{
  char *out;
  char *outbis;
  char *iv2;

  int rc;
  int val;
  int outlen;
  int dlen = 0, blocksize, enctype, hashsize;

  /* read size of message */
  read (sock, &dlen, sizeof (int));

  dlen = ntohl (dlen);
  /* if 0 put read size to 0 */
  if (!dlen)
    {
      *len = dlen;
      return SHISHI_OK;
    }

  /* convert size to encryption size */
  enctype = shishi_key_type (enckey);

  blocksize = shishi_cipher_blocksize (enctype);
  hashsize =
    shishi_checksum_cksumlen (shishi_cipher_defaultcksumtype (enctype));

  dlen += blocksize - 1 + 4;
  if (shishi_key_type (enckey) != SHISHI_DES3_CBC_HMAC_SHA1_KD)
    dlen += hashsize;
  else
    dlen += blocksize;

  dlen /= blocksize;
  dlen *= blocksize;

  if (shishi_key_type (enckey) == SHISHI_DES3_CBC_HMAC_SHA1_KD)
    dlen += hashsize;

  /* read encrypted data */
  outbis = malloc (dlen);
  if (outbis == NULL)
    {
      printf ("Malloc error!\n");
      return 1;
    }

  rc = read (sock, outbis, dlen);
  if (rc != dlen)
    {
      printf ("Error during read socket\n");
      return 1;
    }

  /* decrypt it */
  rc =
    shishi_decrypt_ivupdate (h, enckey, 1026, iv, *ivlen, &iv2, ivlen, outbis,
			     dlen, &out, &outlen);
  if (rc != SHISHI_OK)
    {
      printf ("decryption error\n");
      return 1;
    }

  /* len = first 4 bytes of decrypted data */
  *len = ntohl (*((int *) out));

  /* update iv */
  memcpy (iv, iv2, *ivlen);

  /* Temp patch to remove 5 unidentified bytes data from server */
  memset (buf, 0, BUFLEN);
  if ((unsigned char) out[4] == 255)
    val = 5 + sizeof (int);
  else
    val = sizeof (int);

  /* copy decrypted data to output */
  memcpy (buf, out + val, strlen (out + val));


  free (out);
  free (outbis);

  return SHISHI_OK;
}
Exemple #3
0
int
main (int argc, char **argv)
{
  int index;
  struct passwd *pw;
  struct servent *sp;
  sigset_t sigs, osigs;
  int asrsh, rem;
  pid_t pid = 0;
  uid_t uid;
  char *args, *host;

  set_program_name (argv[0]);

  asrsh = 0;
  host = user = NULL;

  /* If called as something other than "rsh", use it as the host name */
  {
    char *p = strrchr (argv[0], '/');
    if (p)
      ++p;
    else
      p = argv[0];
    if (strcmp (p, "rsh"))
      host = p;
    else
      asrsh = 1;
  }

  /* Parse command line */
  iu_argp_init ("rsh", default_program_authors);
  argp_parse (&argp, argc, argv, ARGP_IN_ORDER, &index, NULL);

  if (index < argc)
    host = argv[index++];

  /* To few args.  */
  if (!host)
    error (EXIT_FAILURE, 0, "host not specified");

  /* If no further arguments, must have been called as rlogin. */
  if (!argv[index])
    {
      if (asrsh)
	*argv = (char *) "rlogin";
      seteuid (getuid ());
      setuid (getuid ());
      execv (PATH_RLOGIN, argv);
      error (EXIT_FAILURE, errno, "cannot execute %s", PATH_RLOGIN);
    }

  argc -= index;
  argv += index;

  /* We must be setuid root.  */
  if (geteuid ())
    error (EXIT_FAILURE, 0, "must be setuid root.\n");

  if (!(pw = getpwuid (uid = getuid ())))
    error (EXIT_FAILURE, 0, "unknown user id");

  /* Accept user1@host format, though "-l user2" overrides user1 */
  {
    char *p = strchr (host, '@');
    if (p)
      {
	*p = '\0';
	if (!user && p > host)
	  user = host;
	host = p + 1;
	if (*host == '\0')
	  error (EXIT_FAILURE, 0, "empty host name");
      }
  }

#if defined KERBEROS || defined SHISHI
# ifdef ENCRYPTION
  /* -x turns off -n */
  if (doencrypt)
    null_input_option = 0;
# endif
#endif

  args = copyargs (argv);

  sp = NULL;
#ifdef KERBEROS
  if (use_kerberos)
    {
      sp = getservbyname ((doencrypt ? "ekshell" : "kshell"), "tcp");
      if (sp == NULL)
	{
	  use_kerberos = 0;
	  warning ("can't get entry for %s/tcp service",
		   doencrypt ? "ekshell" : "kshell");
	}
    }
#elif defined(SHISHI)
  if (use_kerberos)
    {
      sp = getservbyname ("kshell", "tcp");
      if (sp == NULL)
	{
	  use_kerberos = 0;
	  warning ("can't get entry for %s/tcp service", "kshell");
	}
    }
#endif
  if (sp == NULL)
    sp = getservbyname ("shell", "tcp");
  if (sp == NULL)
    error (EXIT_FAILURE, 0, "shell/tcp: unknown service");


#if defined KERBEROS || defined SHISHI
try_connect:
  if (use_kerberos)
    {
      struct hostent *hp;

      /* fully qualify hostname (needed for krb_realmofhost) */
      hp = gethostbyname (host);
      if (hp != NULL && !(host = strdup (hp->h_name)))
	error (EXIT_FAILURE, errno, "strdup");

# if defined KERBEROS
      rem = KSUCCESS;
      errno = 0;
      if (dest_realm == NULL)
	dest_realm = krb_realmofhost (host);
# elif defined (SHISHI)
      rem = SHISHI_OK;
      errno = 0;
# endif

# ifdef ENCRYPTION
      if (doencrypt)
#  if defined SHISHI
	{
	  int i;
	  char *term;

	  term = xmalloc (strlen (args) + 4);
	  strcpy (term, "-x ");
	  strcat (term, args);

	  rem = krcmd_mutual (&h, &host, sp->s_port, &user, term, &rfd2,
			      dest_realm, &enckey);
	  if (rem > 0)
	    {
	      keytype = shishi_key_type (enckey);
	      keylen = shishi_cipher_blocksize (keytype);

	      ivtab[0] = &iv1;
	      ivtab[1] = &iv2;
	      ivtab[2] = &iv3;
	      ivtab[3] = &iv4;

	      for (i = 0; i < 4; i++)
		{
		  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:
		      ivtab[i]->keyusage = SHISHI_KEYUSAGE_KCMD_DES;
		      ivtab[i]->iv = malloc (ivtab[i]->ivlen);
		      memset (ivtab[i]->iv,
			      2 * i + 1 * (i < 2) - 4 * (i >= 2),
			      ivtab[i]->ivlen);
		      ivtab[i]->ctx =
			shishi_crypto (h, enckey, ivtab[i]->keyusage,
				       shishi_key_type (enckey), ivtab[i]->iv,
				       ivtab[i]->ivlen);
		      break;
		    case SHISHI_ARCFOUR_HMAC:
		    case SHISHI_ARCFOUR_HMAC_EXP:
		      ivtab[i]->keyusage =
			SHISHI_KEYUSAGE_KCMD_DES + 2 + 4 * i;
		      ivtab[i]->ctx =
			shishi_crypto (h, enckey, ivtab[i]->keyusage,
				       shishi_key_type (enckey), NULL, 0);
		      break;
		    default:
		      ivtab[i]->keyusage =
			SHISHI_KEYUSAGE_KCMD_DES + 2 + 4 * i;
		      ivtab[i]->iv = malloc (ivtab[i]->ivlen);
		      memset (ivtab[i]->iv, 0, ivtab[i]->ivlen);
		      ivtab[i]->ctx =
			shishi_crypto (h, enckey, ivtab[i]->keyusage,
				       shishi_key_type (enckey), ivtab[i]->iv,
				       ivtab[i]->ivlen);
		    }
		}
	    }
	  free (term);
	}
      else
#  else
	rem = krcmd_mutual (&host, sp->s_port, user, args, &rfd2,
			    dest_realm, &cred, schedule);
      else
#  endif
# endif
	rem = krcmd (
# if defined SHISHI
		      &h, &host, sp->s_port, &user, args, &rfd2, dest_realm);
# else
		      &host, sp->s_port, user, args, &rfd2, dest_realm);
# endif
      if (rem < 0)
	{
	  use_kerberos = 0;
	  sp = getservbyname ("shell", "tcp");
	  if (sp == NULL)
	    error (EXIT_FAILURE, 0, "shell/tcp: unknown service");
	  if (errno == ECONNREFUSED)
	    warning ("remote host doesn't support Kerberos");
	  if (errno == ENOENT)
	    warning ("can't provide Kerberos auth data");
	  goto try_connect;
	}
    }
Exemple #4
0
/* read encrypted data on socket */
int
readenc (Shishi * h, int sock, char *buf, int *len, shishi_ivector * iv,
	 Shishi_key * enckey, int proto)
{
  char *out;
  char *outbis;

  int rc;
  int val;
  int outlen;
  int dlen = 0, blocksize, enctype, hashsize;

  /* read size of message */
  read (sock, &dlen, sizeof (int));

  dlen = ntohl (dlen);
  /* if 0 put read size to 0 */
  if (!dlen)
    {
      *len = dlen;
      return SHISHI_OK;
    }

  if (proto == 1)
    *len = dlen;

  /* convert size to encryption size */
  enctype = shishi_key_type (enckey);

  blocksize = shishi_cipher_blocksize (enctype);
  hashsize =
    shishi_checksum_cksumlen (shishi_cipher_defaultcksumtype (enctype));

  switch (enctype)
    {
    case SHISHI_AES128_CTS_HMAC_SHA1_96:
    case SHISHI_AES256_CTS_HMAC_SHA1_96:
      dlen += 4 + hashsize + blocksize;
      break;
    case SHISHI_ARCFOUR_HMAC:
    case SHISHI_ARCFOUR_HMAC_EXP:
      dlen += 4 + 8 + blocksize - 1;
      dlen /= blocksize;
      dlen *= blocksize;
      dlen += hashsize;
      break;
    case SHISHI_DES3_CBC_HMAC_SHA1_KD:
      dlen += 4 + 2 * blocksize - 1;
      dlen /= blocksize;
      dlen *= blocksize;
      dlen += hashsize;
      break;
    case SHISHI_DES_CBC_CRC:
      dlen += 2 * blocksize - 1;
      if (proto == 2)
	dlen += 4;
      dlen += hashsize;
      dlen /= blocksize;
      dlen *= blocksize;
      break;
    default:
      dlen += blocksize - 1;
      if (proto == 2)
	dlen += 4;
      dlen += hashsize;
      dlen /= blocksize;
      dlen *= blocksize;
      break;
    }

  /* read encrypted data */
  outbis = malloc (dlen);
  if (outbis == NULL)
    {
      perror ("readenc()");
      return 1;
    }

  rc = read (sock, outbis, dlen);
  if (rc != dlen)
    {
      fprintf (stderr, "Error during read socket\n");
      free (outbis);
      return 1;
    }

  if (proto == 1)
    {
      rc =
	shishi_decrypt (h, enckey, iv->keyusage, outbis, dlen, &out, &outlen);
      if (rc != SHISHI_OK)
	{
	  fprintf (stderr, "decryption error\n");
	  free (outbis);
	  return 1;
	}

      val = 0;
    }
  else
    {
      rc = shishi_crypto_decrypt (iv->ctx, outbis, dlen, &out, &outlen);
      if (rc != SHISHI_OK)
	{
	  fprintf (stderr, "decryption error\n");
	  free (outbis);
	  return 1;
	}

      /* in KCMDV0.2 first 4 bytes of decrypted data = len of data */
      *len = ntohl (*((int *) out));
      val = sizeof (int);
    }

  memset (buf, 0, BUFLEN);

  /* copy decrypted data to output */
  memcpy (buf, out + val, outlen - val);

  free (out);
  free (outbis);

  return SHISHI_OK;
}