Example #1
0
File: sshurl.c Project: AnthraX1/rk
/*
 * Decode url coding. If url_out is NULL then decode inplace, and modify url.
 * Otherwise return new allocated string containing the decoded buffer. Returns
 * TRUE if decoding was successfull and FALSE otherwise. Len is the length of
 * the input url and length of the returned url is in stored in the len_out
 * if it is not NULL. The decoded url is returned even if the decoding fails.
 */
Boolean ssh_url_decode_bin(char *url, size_t len,
                           char **url_out, size_t *len_out)
{
  char *src, *dst;
  unsigned int x;
  Boolean ok = TRUE;
  size_t src_len, dst_len;

  if (url_out != NULL)
    {
      *url_out = ssh_xmemdup(url, len);
      url = *url_out;
    }

  src = url;
  src_len = len;
  dst = url;
  dst_len = 0;
  while (src_len > 0)
    {
      if (*src == '%')
        {
          if (src_len >= 3 && isxdigit(src[1]) && isxdigit(src[2]))
            {
              if (isdigit(src[1]))
                x = src[1] - '0';
              else
                x = tolower(src[1]) - 'a' + 10;
              x *= 16;

              if (isdigit(src[2]))
                x += src[2] - '0';
              else
                x += tolower(src[2]) - 'a' + 10;

              *dst++ = x;
              dst_len++;
              src += 3;
              src_len -= 3;
            }
          else
            {
              src_len--;
              dst_len++;
              *dst++ = *src++;
              ok = FALSE;
            }
        }
      else
        {
          src_len--;
          dst_len++;
          *dst++ = *src++;
        }
    }
  *dst = 0;
  if (len_out != NULL)
    *len_out = dst_len;
  return ok;
}
Example #2
0
Boolean
ssh2_key_blob_encode(unsigned long magic,
                     const char *subject, const char *comment,
                     const unsigned char *key, size_t keylen,
                     unsigned char **encoded, size_t *encoded_len)
{
  SshBufferStruct buffer;
  char *base64;
  unsigned int key_index;

  /* Translate to index. */
  switch (magic)
    {
    case SSH_KEY_MAGIC_PUBLIC:            key_index = 0; break;
    case SSH_KEY_MAGIC_PRIVATE:           key_index = 1; break;
    case SSH_KEY_MAGIC_PRIVATE_ENCRYPTED: key_index = 2; break;
    default:                                             return FALSE;
    }

  ssh_buffer_init(&buffer);

  /* Add the head for the key. */
  ssh_key_blob_dump_line_str(&buffer,
                             ssh2_pk_format_name_list[key_index].head);
  ssh_key_blob_dump_lf(&buffer);

  /* Handle key words. */
  if (subject)
    {
      ssh_key_blob_dump_line_str(&buffer, "Subject: ");
      ssh_key_blob_dump_line_str(&buffer, subject);
      ssh_key_blob_dump_lf(&buffer);
    }

  if (comment)
    {
      ssh_key_blob_dump_line_str(&buffer, "Comment: ");
      ssh_key_blob_dump_quoted_str(&buffer, 9, comment);
      ssh_key_blob_dump_lf(&buffer);
    }

  /* Now add the base64 formatted stuff. */
  base64 = (char *)ssh_buf_to_base64(key, keylen);
  ssh_key_blob_dump_str(&buffer, base64);
  ssh_key_blob_dump_lf(&buffer);
  ssh_xfree(base64);

  /* Add the tail for the key. */
  ssh_key_blob_dump_line_str(&buffer,
                             ssh2_pk_format_name_list[key_index].tail);
  ssh_key_blob_dump_lf(&buffer);

  *encoded_len = ssh_buffer_len(&buffer);
  *encoded = ssh_xmemdup(ssh_buffer_ptr(&buffer), ssh_buffer_len(&buffer));
  ssh_buffer_uninit(&buffer);
  return TRUE;
}
Example #3
0
char *ssh_snlist_get_name(const char *namelist)
{
  int len = ssh_snlist_name_len(namelist);
  char *name = NULL;

  if (len > 0)
    name = ssh_xmemdup(namelist, len);
  return name;
}
Example #4
0
static char *
parse_img_src(char *data, size_t len)
{
  int i;

  for (i = 0; i < len - 7; i++)
    {
      if ((data[i] == 's' || data[i] == 'S')
          && (data[i + 1] == 'r' || data[i + 1] == 'R')
          && (data[i + 2] == 'c' || data[i + 2] == 'C')
          && data[i + 3] == '='
          && data[i + 4] == '"')
        {
          int start = i + 5;

          for (i += 6; i < len && data[i] != '"'; i++)
            ;

          return ssh_xmemdup(data + start, i - start);
        }
    }

  return "???";
}
Example #5
0
File: sshurl.c Project: AnthraX1/rk
/*
 * Parses url given in format
 * [<scheme>:][//[<user>[:<password>]@]<host>[:<port>]]/[<path>]
 * Returns true if the url is syntactically valid, false otherwise.
 * If the incorrect url format "www.ssh.fi" is given then returns FALSE and
 * sets host to contain whole url. If some piece of url is not given it is
 * set to NULL. If some of the pieces are not needed they can be NULL and
 * those pieces will be skipped.
 */
Boolean ssh_url_parse(const char *url, char **scheme, char **host,
                      char **port, char **username, char **password,
                      char **path)
{
  const char *p, *q, *start;

  p = url;

  if (scheme)
    *scheme = NULL;
  if (host)
    *host = NULL;
  if (port)
    *port = NULL;
  if (username)
    *username = NULL;
  if (password)
    *password = NULL;
  if (path)
    *path = NULL;

  while (isspace(*p))
    p++;

  if (!*p)
    {
      return FALSE;
    }

  start = p;
  while (isalpha(*p) || isdigit(*p) || *p == '+' || *p == '-' || *p == '.')
    p++;

  /* Check for scheme */
  if (*p == ':')
    {
      if (scheme != NULL)
        *scheme = ssh_xmemdup(start, p - start);
      p++;
      start = p;
    }

  p = start;
  /* Do we have host name part */
  if (p[0] == '/' && p[1] == '/')
    {
      start += 2;

      p = start;
      /* Check for username and password */
      while (*p && *p != '@' && *p != '/')
        p++;

      if (*p == '@')
        {
          /* User name (and possible password found) */

          q = p;
          while (q > start && *q != ':')
            q--;

          if (*q == ':')
            {
              /* Password found */
              if (username != NULL)
                *username = ssh_xmemdup(start, q - start);
              if (password != NULL)
                *password = ssh_xmemdup(q + 1, p - (q + 1));
            }
          else
            {
              /* Only username found */
              if (username != NULL)
                *username = ssh_xmemdup(start, p - start);
            }
          p++;
          start = p;
        }

      p = start;
      /* Check for host name */
      while (*p && *p != ':' && *p != '/')
        p++;

      if (host != NULL)
        *host = ssh_xmemdup(start, p - start);
      start = p;

      if (*p == ':')
        {
          start = ++p;

          while (isdigit(*p))
            p++;

          if (port != NULL)
            *port = ssh_xmemdup(start, p - start);

          start = p;
        }
    }

  if (!*p)
    {
      return TRUE;
    }

  if (*p != '/')
    {
      if (host != NULL && *host == NULL)
        *host = ssh_xstrdup(p);
      else
        if (path != NULL)
          *path = ssh_xstrdup(p);
      return FALSE;
    }
  else
    {
      if (path != NULL)
        *path = ssh_xstrdup(p + 1);
      return TRUE;
    }
}
void test_variant(const char *postfix)
{
  SshCipher cipher;
  SshCryptoStatus status;
  unsigned char *iv, *key, *src, *plain;
  unsigned char *aad, *ciph, *auth_tag, digest_len;
  size_t key_len, iv_len, aad_len, src_len, src_len_block, ciph_len, 
    auth_tag_len, orig_len;
  unsigned char *orig;
  unsigned char iv_buf[16], *digest;
  unsigned char *ciph_name;
  size_t blocklen;
  int i;

  for (i = 0; combined_test_vectors[i].key != NULL; i++)
    {
      hex_string_to_buf(combined_test_vectors[i].key, &key, &key_len);
      hex_string_to_buf(combined_test_vectors[i].iv, &iv, &iv_len);
      hex_string_to_buf(combined_test_vectors[i].aad, &aad, &aad_len);
      hex_string_to_buf(combined_test_vectors[i].plaintext, &plain, &src_len);
      hex_string_to_buf(combined_test_vectors[i].plaintext, &src, &src_len);
      orig = ssh_xmemdup(src, src_len);
      orig_len = src_len;
      hex_string_to_buf(combined_test_vectors[i].ciphertext, &ciph, &ciph_len);
      hex_string_to_buf(combined_test_vectors[i].auth_tag, &auth_tag, 
			&auth_tag_len);
      digest = NULL;

      ciph_name = ssh_string_concat_2(combined_test_vectors[i].name, postfix);
      SSH_ASSERT(ciph_name);
      status = ssh_cipher_allocate(ciph_name,
				   key, key_len, TRUE, &cipher);
      if (status != SSH_CRYPTO_OK)
	{ 
	  fprintf(stderr, "Cannot allocate cipher \"%s\" (status is %s)\n", 
		  ciph_name, ssh_crypto_status_message(status));
	  exit(1);
	}




      if (iv_len != 12)
	{
	  SSH_DEBUG(1, ("Skipping test %d with IV not equal to 12 bytes", i));
	  goto dealloc_and_continue;
	}

      if (!ssh_cipher_is_auth_cipher(combined_test_vectors[i].name))
	{
	  SSH_DEBUG(1, ("Skipping test %d with non-auth cipher", i));
	  goto dealloc_and_continue;
	}

      digest_len = 
	ssh_cipher_auth_digest_length(combined_test_vectors[i].name);
      digest = ssh_xmalloc(digest_len);

      ssh_cipher_auth_reset(cipher);
      
      if (aad != NULL)
	ssh_cipher_auth_update(cipher, aad, aad_len);
      



      SSH_ASSERT(iv_len == 12);
      memcpy(iv_buf, iv, 12);
      SSH_PUT_32BIT(iv_buf + 12, 1);
      
      status = ssh_cipher_set_iv(cipher, iv_buf);
      SSH_VERIFY(status == SSH_CRYPTO_OK);

      blocklen = ssh_cipher_get_block_length(combined_test_vectors[i].name);

      src_len_block = src_len - (src_len % blocklen);
      status = ssh_cipher_transform(cipher, src, src, src_len_block);
	
      /* Process remaining bytes if test was not multiple of block size. */
      if (status == SSH_CRYPTO_OK && (src_len > src_len_block))
	{
	  status = ssh_cipher_transform_remaining(cipher, 
						  src + src_len_block,
						  src + src_len_block,
						  src_len - src_len_block);
	}

      SSH_VERIFY(status == SSH_CRYPTO_OK);
      
      SSH_VERIFY(ssh_cipher_auth_final(cipher, digest) == SSH_CRYPTO_OK);
      
      if (src_len != ciph_len || memcmp(src, ciph, src_len))
	{
	  fprintf(stderr, 
		  "Test vectors ciphertext (ciph=%s) do not agree test=%d\n", 
		  ciph_name, i);
	  SSH_DEBUG_HEXDUMP(1, ("cipher computed"), src, src_len);
	  SSH_DEBUG_HEXDUMP(1, ("cipher expected"), ciph, ciph_len);
	  exit(1);
	}

      if (digest_len != auth_tag_len ||
	  memcmp(digest, auth_tag, digest_len)) 
	{
	  fprintf(stderr, 
		  "Test vectors digest (ciph=%s) do not agree test=%d\n", 
		  ciph_name, i);
	  SSH_DEBUG_HEXDUMP(1, ("digest computed"), digest, digest_len);
	  SSH_DEBUG_HEXDUMP(1, ("digest expected"), auth_tag, auth_tag_len);
	  exit(1);
	}
      
      /* Redo operation, now decryption */
      ssh_cipher_free(cipher);

      status = ssh_cipher_allocate(ciph_name,
				   key, key_len, FALSE, &cipher);
      if (status != SSH_CRYPTO_OK)
	{ 
	  fprintf(stderr, "Cannot allocate cipher \"%s\" (status is %s)\n", 
		  ciph_name, ssh_crypto_status_message(status));
	  exit(1);
	}

      SSH_ASSERT(digest_len == 
		 ssh_cipher_auth_digest_length(combined_test_vectors[i].name));

      ssh_cipher_auth_reset(cipher);
      
      if (aad != NULL)
	ssh_cipher_auth_update(cipher, aad, aad_len);
      



      SSH_ASSERT(iv_len == 12);
      memcpy(iv_buf, iv, 12);
      SSH_PUT_32BIT(iv_buf + 12, 1);
      
      status = ssh_cipher_set_iv(cipher, iv_buf);
      SSH_VERIFY(status == SSH_CRYPTO_OK);

      src_len_block = src_len - (src_len % blocklen);
      status = ssh_cipher_transform(cipher, orig, src, src_len_block);
	
      /* Process remaining bytes if test was not multiple of block size. */
      if (status == SSH_CRYPTO_OK && (src_len > src_len_block))
	{
	  status = ssh_cipher_transform_remaining(cipher, 
						  orig + src_len_block,
						  src + src_len_block,
						  src_len - src_len_block);
	}

      SSH_VERIFY(status == SSH_CRYPTO_OK);
      
      SSH_VERIFY(ssh_cipher_auth_final(cipher, digest) == SSH_CRYPTO_OK);
      
      if (orig_len != ciph_len || memcmp(orig, plain, src_len))
	{
	  fprintf(stderr, 
		  "Test vectors plaintext (ciph=%s) do not agree test=%d\n", 
		  ciph_name, i);
	  SSH_DEBUG_HEXDUMP(1, ("plain computed"), orig, orig_len);
	  SSH_DEBUG_HEXDUMP(1, ("plain expected"), plain, ciph_len);
	  exit(1);
	}

      if (digest_len != auth_tag_len ||
	  memcmp(digest, auth_tag, digest_len)) 
	{
	  fprintf(stderr, 
		  "Test vectors digest (ciph=%s) do not agree test=%d\n", 
		  ciph_name, i);
	  SSH_DEBUG_HEXDUMP(1, ("digest computed"), digest, digest_len);
	  SSH_DEBUG_HEXDUMP(1, ("digest expected"), auth_tag, auth_tag_len);
	  exit(1);
	}
      
      /* Reset cipher and redo decryption */
      ssh_cipher_auth_reset(cipher);

      if (aad != NULL)
	ssh_cipher_auth_update(cipher, aad, aad_len);
      
      status = ssh_cipher_set_iv(cipher, iv_buf);
      SSH_VERIFY(status == SSH_CRYPTO_OK);

      status = ssh_cipher_transform(cipher, orig, src, src_len_block);
	
      /* Process remaining bytes if test was not multiple of block size. */
      if (status == SSH_CRYPTO_OK && (src_len > src_len_block))
	{
	  status = ssh_cipher_transform_remaining(cipher, 
						  orig + src_len_block,
						  src + src_len_block,
						  src_len - src_len_block);
	}

      SSH_VERIFY(status == SSH_CRYPTO_OK);
      
      SSH_VERIFY(ssh_cipher_auth_final(cipher, digest) == SSH_CRYPTO_OK);
      
      if (orig_len != ciph_len || memcmp(orig, plain, src_len))
	{
	  fprintf(stderr, 
		  "Test vectors plaintext (ciph=%s) do not agree test=%d\n", 
		  ciph_name, i);
	  SSH_DEBUG_HEXDUMP(1, ("plain computed"), orig, orig_len);
	  SSH_DEBUG_HEXDUMP(1, ("plain expected"), plain, ciph_len);
	  exit(1);
	}

      if (digest_len != auth_tag_len ||
	  memcmp(digest, auth_tag, digest_len)) 
	{
	  fprintf(stderr, 
		  "Test vectors digest (ciph=%s) do not agree test=%d\n", 
		  ciph_name, i);
	  SSH_DEBUG_HEXDUMP(1, ("digest computed"), digest, digest_len);
	  SSH_DEBUG_HEXDUMP(1, ("digest expected"), auth_tag, auth_tag_len);
	  exit(1);
	}
      
      SSH_DEBUG(2, ("Test %d (cipher=`%s') successful", i, 
		    combined_test_vectors[i].name));

    dealloc_and_continue:
      if (cipher) 
	ssh_cipher_free(cipher);

      ssh_xfree(digest);
      ssh_xfree(key); 
      ssh_xfree(iv);  
      ssh_xfree(aad);
      ssh_xfree(src); 
      ssh_xfree(orig); 
      ssh_xfree(plain); 
      ssh_xfree(ciph); 
      ssh_xfree(auth_tag);
      ssh_xfree(ciph_name);
    }

}
Example #7
0
Boolean ssh2_find_pgp_secret_key_internal(SshUser uc,
                                          const char *fn,
                                          const char *name,
                                          const char *fingerprint,
                                          SshUInt32 id,
                                          unsigned char **blob,
                                          size_t *blob_len,
                                          char **comment)
{
  struct stat st;
  SshUserFile uf;
  SshFileBuffer fb;
  SshPgpPacket pp;
  Boolean found;
  char *key_comment = NULL;

  if (ssh_userfile_stat(ssh_user_uid(uc), fn, &st) < 0)
    {
      SSH_DEBUG(2, ("file %s does not exist", fn));
      return FALSE;
    }
  if ((uf = ssh_userfile_open(ssh_user_uid(uc), fn, O_RDONLY, 0)) == NULL) 
    {
      SSH_DEBUG(2, ("could not open %s", fn));
      return FALSE;
    }
  ssh_file_buffer_init(&fb);
  if (ssh_file_buffer_attach_userfile(&fb, uf) == FALSE)
    {
      SSH_DEBUG(2, ("could not attach %s userfile to file buffer", fn));
      ssh_userfile_close(uf);
      ssh_file_buffer_uninit(&fb);
      return FALSE;
    }
  if (fingerprint != NULL)
    found = ssh_pgp_find_secret_key_with_fingerprint(&fb, 
                                                     fingerprint, 
                                                     &pp,
                                                     (comment ? 
                                                      &key_comment :
                                                      NULL));
  else if (name != NULL)
    found = ssh_pgp_find_secret_key_with_name(&fb, 
                                              name, 
                                              TRUE, 
                                              &pp,
                                              (comment ? 
                                               &key_comment :
                                               NULL));
  else
    found = ssh_pgp_find_secret_key_with_key_id(&fb, 
                                                id, 
                                                &pp,
                                                (comment ? 
                                                 &key_comment :
                                                 NULL));
  ssh_file_buffer_detach(&fb);
  ssh_file_buffer_uninit(&fb);
  ssh_userfile_close(uf);
  if (found == FALSE)
    {
      SSH_DEBUG(2, ("pgp library didn't find secret key"));
      return FALSE;
    }
  *blob = ssh_xmemdup(pp->data, pp->len);
  if (blob_len)
    *blob_len = pp->len;
  ssh_pgp_packet_free(pp);
  if (comment)
    *comment = key_comment;
  return TRUE;
}
Example #8
0
/* Encodes terminal modes for the terminal referenced by fd in a
   portable manner, and appends the modes to a buffer being
   constructed. Stores constructed buffers len to buf_len. This call
   always succeeds, but if an error happens during encoding, buf will
   be empty and buf_len will be 0 */
void ssh_encode_tty_flags(int fd, unsigned char **buf, size_t *buf_len)
     /*void tty_make_modes(int fd)*/
{
  SshBuffer buffer;  
#ifdef USING_TERMIOS
  struct termios tio;
#endif
#ifdef USING_SGTTY
  struct sgttyb tio;
  struct tchars tiotc;
  struct ltchars tioltc;
  int tiolm;
#ifdef TIOCGSTAT
  struct tstatus tiots;
#endif /* TIOCGSTAT */
#endif /* USING_SGTTY */
  int baud;

  if (!isatty(fd))
    {
      SSH_TRACE(2, ("Not a tty. (fd = %d)", fd));
      *buf = ssh_xstrdup("");
      *buf_len = 0;
      return;
    }
  
  ssh_buffer_init(&buffer);

  /* Get the modes. */
#ifdef USING_TERMIOS
  if (tcgetattr(fd, &tio) < 0)
    {
      PUT_CHAR(TTY_OP_END);
      ssh_warning("tcgetattr: %.100s", strerror(errno));
      goto error;
    }
#endif /* USING_TERMIOS */
#ifdef USING_SGTTY
  if (ioctl(fd, TIOCGETP, &tio) < 0)
    {
      PUT_CHAR(TTY_OP_END);
      ssh_warning("ioctl(fd, TIOCGETP, ...): %.100s", strerror(errno));
      goto error;
    }
  if (ioctl(fd, TIOCGETC, &tiotc) < 0)
    {
      PUT_CHAR(TTY_OP_END);
      ssh_warning("ioctl(fd, TIOCGETC, ...): %.100s", strerror(errno));
      goto error;
    }
  if (ioctl(fd, TIOCLGET, &tiolm) < 0)
    {
      PUT_CHAR(TTY_OP_END);
      ssh_warning("ioctl(fd, TIOCLGET, ...): %.100s", strerror(errno));
      goto error;
    }
  if (ioctl(fd, TIOCGLTC, &tioltc) < 0)
    {
      PUT_CHAR(TTY_OP_END);
      ssh_warning("ioctl(fd, TIOCGLTC, ...): %.100s", strerror(errno));
      goto error;
    }
#ifdef TIOCGSTAT
  if (ioctl(fd, TIOCGSTAT, &tiots) < 0) 
    {
      PUT_CHAR(TTY_OP_END);
      ssh_warning("ioctl(fd, TIOCGSTAT, ...): %.100s", strerror(errno));
      goto error;
    }
#endif /* TIOCGSTAT */
  /* termio's ECHOE is really both LCRTBS and LCRTERA - so wire them
     together */
  if (tiolm & LCRTBS)
    tiolm |= LCRTERA;
#endif /* USING_SGTTY */

  /* Store input and output baud rates. */
  baud = speed_to_baud(cfgetospeed(&tio));
  PUT_CHAR(TTY_OP_OSPEED);
  PUT_UINT32(baud);
  baud = speed_to_baud(cfgetispeed(&tio));
  PUT_CHAR(TTY_OP_ISPEED);
  PUT_UINT32(baud);

  /* Store values of mode flags. */
#ifdef USING_TERMIOS
#define TTYCHAR(NAME, OP) \
  PUT_CHAR(OP); PUT_UINT32(tio.c_cc[NAME]);
#define TTYMODE(NAME, FIELD, OP) \
  PUT_CHAR(OP); PUT_UINT32((tio.FIELD & NAME) != 0);
#define SGTTYCHAR(NAME, OP)
#define SGTTYMODE(NAME, FIELD, OP)
#define SGTTYMODEN(NAME, FIELD, OP)
#endif /* USING_TERMIOS */

#ifdef USING_SGTTY
#define TTYCHAR(NAME, OP)
#define TTYMODE(NAME, FIELD, OP)
#define SGTTYCHAR(NAME, OP) \
  PUT_CHAR(OP); PUT_UINT32(NAME);
#define SGTTYMODE(NAME, FIELD, OP) \
  PUT_CHAR(OP); PUT_UINT32((FIELD & NAME) != 0);
#define SGTTYMODEN(NAME, FIELD, OP) \
  PUT_CHAR(OP); PUT_UINT32((FIELD & NAME) == 0);
#endif /* USING_SGTTY */

#include "sshttyflagsi.h"

#undef TTYCHAR
#undef TTYMODE
#undef SGTTYCHAR
#undef SGTTYMODE
#undef SGTTYMODEN

  /* Mark end of mode data. */
  PUT_CHAR(TTY_OP_END);

  *buf_len = ssh_buffer_len(&buffer);
  *buf = ssh_xmemdup(ssh_buffer_ptr(&buffer), *buf_len);
  ssh_buffer_uninit(&buffer);

  SSH_DEBUG_HEXDUMP(5, ("encoded tty-flags buffer"), *buf, *buf_len);
  
  return;

 error:
  ssh_buffer_uninit(&buffer);
  *buf = ssh_xstrdup("");
  *buf_len = 0;
}