Ejemplo n.º 1
1
QString stringPrepare(const Stringprep_profile *AProfile, const QString &AString)
{
	QByteArray buffer = AString.toUtf8();
	if (!buffer.isEmpty() && buffer.size()<1024)
	{
		buffer.reserve(1024);
		if (stringprep(buffer.data(),buffer.capacity(),(Stringprep_profile_flags)0, AProfile) == STRINGPREP_OK)
			return QString::fromUtf8(buffer.constData());
	}
	return QString::null;
}
Ejemplo n.º 2
0
/*!
 * \brief if necessary libraries are present this function converts the input 
 * to utf8 and normalizes it.
 * \param s The input string
 * \return Returns a newly allocated zero-terminated string.
 */
char *normalize( char *s )
{
	char *buf;
#ifdef HAVE_LIBIDN
	int	bufsize, rc;
	char	*utf8;


	traceLog(LOG_INFO,"Doing stringprep on %s", s);
	/* stringprep_locale_charset(); */
	utf8 = stringprep_locale_to_utf8(s);

	bufsize = strlen(utf8) * 2;
	buf = (char *) Malloc ( bufsize * sizeof( char ) );
	strcpy(buf,utf8);

	rc = stringprep (buf, bufsize, 0, stringprep_nameprep);
	if (rc != STRINGPREP_OK) {
		traceLog(LOG_INFO,"Stringprep failed with rc %d", rc);
		Free(buf);
		buf = utf8;
	} else 
		Free(utf8);
	
	traceLog(LOG_INFO,"result %s", buf);
#else
	buf = Strdup(s);
#endif

	return buf;
}
Ejemplo n.º 3
0
/* Given a UTF-8 password string, convert it to the canonical form
 * defined by SASLprep (RFC 4013).  This is a permissive implementation,
 * suitable for verifying existing passwords but not for creating new
 * ones -- if you want to create a new password, you'll need to add a
 * strict mode that returns stringprep errors to the user, and uses the
 * STRINGPREP_NO_UNASSIGNED flag to disallow unassigned characters.
 * <string> .saslprep <string> */
static int
zsaslprep(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    uint input_size = r_size(op);
    byte *buffer;
    uint buffer_size;
    uint output_size;
    Stringprep_rc err;

    check_read_type(*op, t_string);

    /* According to http://unicode.org/faq/normalization.html, converting
     * a UTF-8 string to normalization form KC has a worst-case expansion
     * factor of 11, so we allocate 11 times the length of the string plus
     * 1 for the NUL terminator.  If somehow that's still not big enough,
     * stringprep will return STRINGPREP_TOO_SMALL_BUFFER; there's no
     * danger of corrupting memory. */
    buffer_size = input_size * 11 + 1;
    buffer = ialloc_string(buffer_size, "saslprep result");
    if (buffer == 0)
        return_error(e_VMerror);

    memcpy(buffer, op->value.bytes, input_size);
    buffer[input_size] = '\0';

    err = stringprep((char *)buffer, buffer_size, 0, stringprep_saslprep);
    if (err != STRINGPREP_OK) {
        ifree_string(buffer, buffer_size, "saslprep result");

        /* Since we're just verifying the password to an existing
         * document here, we don't care about "invalid input" errors
         * like STRINGPREP_CONTAINS_PROHIBITED.  In these cases, we
         * ignore the error and return the original string unchanged --
         * chances are it's not the right password anyway, and if it
         * is we shouldn't gratuitously fail to decrypt the document.
         *
         * On the other hand, errors like STRINGPREP_NFKC_FAILED are
         * real errors, and should be returned to the user.
         *
         * Fortunately, the stringprep error codes are sorted to make
         * this easy: the errors we want to ignore are the ones with
         * codes less than 100. */
        if ((int)err < 100)
            return 0;

        return_error(e_ioerror);
    }

    output_size = strlen((char *)buffer);
    buffer = iresize_string(buffer, buffer_size, output_size,
        "saslprep result");	/* can't fail */
    make_string(op, a_all | icurrent_space, output_size, buffer);

    return 0;
}
Ejemplo n.º 4
0
    /**
     * Applies a Stringprep profile to a string. This function does the actual
     * work behind nodeprep, nameprep and resourceprep.
     * @param s The string to apply the profile to.
     * @param out Contains the prepped string if prepping was successful, else untouched.
     * @param profile The Stringprep profile to apply.
     * @return Returns @b true if prepping was successful, @b false otherwise.
     */
    static bool prepare( const std::string& s, std::string& out, const Stringprep_profile* profile )
    {
      if( s.empty() || s.length() > JID_PORTION_SIZE )
        return false;

      char* p = static_cast<char*>( calloc( JID_PORTION_SIZE, sizeof( char ) ) );
      strncpy( p, s.c_str(), s.length() );
      int rc = stringprep( p, JID_PORTION_SIZE, static_cast<Stringprep_profile_flags>( 0 ), profile );
      if( rc == STRINGPREP_OK )
        out = p;
      free( p );
      return rc == STRINGPREP_OK;
    }
Ejemplo n.º 5
0
int
main (void)
{
  char buf[BUFSIZ];
  char *p;
  int rc;
  size_t i;

  setlocale (LC_ALL, "");

  printf ("Input string encoded as `%s': ", stringprep_locale_charset ());
  fflush (stdout);
  if (!fgets (buf, BUFSIZ, stdin))
    perror ("fgets");
  buf[strlen (buf) - 1] = '\0';

  printf ("Before locale2utf8 (length %ld): ", (long int) strlen (buf));
  for (i = 0; i < strlen (buf); i++)
    printf ("%02x ", buf[i] & 0xFF);
  printf ("\n");

  p = stringprep_locale_to_utf8 (buf);
  if (p)
    {
      strcpy (buf, p);
      free (p);
    }
  else
    printf ("Could not convert string to UTF-8, continuing anyway...\n");

  printf ("Before stringprep (length %ld): ", (long int) strlen (buf));
  for (i = 0; i < strlen (buf); i++)
    printf ("%02x ", buf[i] & 0xFF);
  printf ("\n");

  rc = stringprep (buf, BUFSIZ, 0, stringprep_nameprep);
  if (rc != STRINGPREP_OK)
    printf ("Stringprep failed (%d): %s\n", rc, stringprep_strerror (rc));
  else
    {
      printf ("After stringprep (length %ld): ", (long int) strlen (buf));
      for (i = 0; i < strlen (buf); i++)
	printf ("%02x ", buf[i] & 0xFF);
      printf ("\n");
    }

  return 0;
}
Ejemplo n.º 6
0
char *
getdns_convert_ulabel_to_alabel(const char *ulabel)
{
#ifdef HAVE_LIBIDN
    int ret;
    char *buf;
    char *prepped;
    char *prepped2;

    if (ulabel == NULL)
	return 0;
    prepped2 = malloc(BUFSIZ);
    if(!prepped2)
	    return 0;
    setlocale(LC_ALL, "");
    if ((prepped = stringprep_locale_to_utf8(ulabel)) == 0) {
	/* convert to utf8 fails, which it can, but continue anyway */
	if(strlen(ulabel)+1 > BUFSIZ) {
	    free(prepped2);
	    return 0;
	}
	memcpy(prepped2, ulabel, strlen(ulabel)+1);
    } else {
	if(strlen(prepped)+1 > BUFSIZ) {
	    free(prepped);
	    free(prepped2);
	    return 0;
	}
	memcpy(prepped2, prepped, strlen(prepped)+1);
	free(prepped);
    }
    if ((ret = stringprep(prepped2, BUFSIZ, 0, stringprep_nameprep)) != STRINGPREP_OK) {
	free(prepped2);
	return 0;
    }
    if ((ret = idna_to_ascii_8z(prepped2, &buf, 0)) != IDNA_SUCCESS)  {
	free(prepped2);
	return 0;
    }
    free(prepped2);
    return buf;
#else
    return NULL;
#endif
}
Ejemplo n.º 7
0
/**
 * stringprep_profile - prepare internationalized string
 * @in: input array with UTF-8 string to prepare.
 * @out: output variable with pointer to newly allocate string.
 * @profile: name of stringprep profile to use.
 * @flags: a #Stringprep_profile_flags value, or 0.
 *
 * Prepare the input zero terminated UTF-8 string according to the
 * stringprep profile, and return the result in a newly allocated
 * variable.
 *
 * Note that you must convert strings entered in the systems locale
 * into UTF-8 before using this function, see
 * stringprep_locale_to_utf8().
 *
 * The output @out variable must be deallocated by the caller.
 *
 * The @flags are one of #Stringprep_profile_flags values, or 0.
 *
 * The @profile specifies the name of the stringprep profile to use.
 * It must be one of the internally supported stringprep profiles.
 *
 * Return value: Returns %STRINGPREP_OK iff successful, or an error code.
 **/
int
stringprep_profile (const char *in,
		    char **out,
		    const char *profile, Stringprep_profile_flags flags)
{
  const Stringprep_profiles *p;
  char *str = NULL;
  size_t len = strlen (in) + 1;
  int rc;

  for (p = &stringprep_profiles[0]; p->name; p++)
    if (strcmp (p->name, profile) == 0)
      break;

  if (!p || !p->name || !p->tables)
    return STRINGPREP_UNKNOWN_PROFILE;

  do
    {
      if (str)
	free (str);
      str = (char *) malloc (len);
      if (str == NULL)
	return STRINGPREP_MALLOC_ERROR;

      strcpy (str, in);

      rc = stringprep (str, len, flags, p->tables);
      len += 50;
    }
  while (rc == STRINGPREP_TOO_SMALL_BUFFER);

  if (rc == STRINGPREP_OK)
    *out = str;
  else
    free (str);

  return rc;
}
Ejemplo n.º 8
0
char *jabber_saslprep(const char *in)
{
#ifdef USE_IDN
	char *out;

	g_return_val_if_fail(in != NULL, NULL);
	g_return_val_if_fail(strlen(in) <= sizeof(idn_buffer) - 1, NULL);

	strncpy(idn_buffer, in, sizeof(idn_buffer) - 1);
	idn_buffer[sizeof(idn_buffer) - 1] = '\0';

	if (STRINGPREP_OK != stringprep(idn_buffer, sizeof(idn_buffer), 0,
	                                stringprep_saslprep)) {
		memset(idn_buffer, 0, sizeof(idn_buffer));
		return NULL;
	}

	out = g_strdup(idn_buffer);
	memset(idn_buffer, 0, sizeof(idn_buffer));
	return out;
#else /* USE_IDN */
	/* TODO: Something better than disallowing all non-ASCII characters */
	/* TODO: Is this even correct? */
	const guchar *c;

	c = (const guchar *)in;
	for ( ; *c; ++c) {
		if (*c > 0x7f || /* Non-ASCII characters */
				*c == 0x7f || /* ASCII Delete character */
				(*c < 0x20 && *c != '\t' && *c != '\n' && *c != '\r'))
					/* ASCII control characters */
			return NULL;
	}

	return g_strdup(in);
#endif /* USE_IDN */
}
Ejemplo n.º 9
0
Archivo: jid.c Proyecto: named-data/muc
/**
 * caching wrapper around a stringprep function
 *
 * @param in_out_buffer buffer containing what has to be stringpreped and that gets the result
 * @param max_len size of the buffer
 * @param cache the used cache, defining also the used stringprep profile
 * @return the return code of the stringprep call
 */
static int _jid_cached_stringprep(char *in_out_buffer, int max_len, _jid_prep_cache_t cache) {
    _jid_prep_entry_t preped;
    int result = STRINGPREP_OK;

    /* check that the cache already exists
     * we can not do anything as we don't know which profile has to be used */
    if (cache == NULL) {
	return STRINGPREP_UNKNOWN_PROFILE;
    }

    /* is there something that has to be stringpreped? */
    if (in_out_buffer == NULL) {
	return STRINGPREP_OK;
    }

    /* acquire the lock on the cache */
    g_mutex_lock(cache->mutex);

    /* check if the requested preparation has already been done */
    preped = (_jid_prep_entry_t)g_hash_table_lookup(cache->hashtable, in_out_buffer);
    if (preped != NULL) {
	/* we already prepared this argument */
	if (preped->size <= max_len) {
	    /* we can use the result */

	    /* update the statistic */
	    preped->used_count++;
	    preped->last_used = time(NULL);

	    /* do we need to copy the result? */
	    if (preped->preped != NULL) {
		/* copy the result */
		strcpy(in_out_buffer, preped->preped);
	    }

	    result = STRINGPREP_OK;
	} else {
	    /* we need a bigger buffer */
	    result = STRINGPREP_TOO_SMALL_BUFFER;
	}
	
	/* we're done, release the lock on the cache */
	g_mutex_unlock(cache->mutex);
    } else {
	char *original;

	/* stringprep needs time, release the lock on the cache for the meantime */
	g_mutex_unlock(cache->mutex);

	/* we have to keep the key */
	original = strdup(in_out_buffer);
	
	/* try to prepare the string */
	result = stringprep(in_out_buffer, max_len, STRINGPREP_NO_UNASSIGNED, cache->profile);

	/* did we manage to prepare the string? */
	if (result == STRINGPREP_OK && original != NULL) {
	    /* generate an entry for the cache */
	    preped = (_jid_prep_entry_t)malloc(sizeof(struct _jid_prep_entry_st));
	    if (preped != NULL) {
		/* has there been modified something? */
		if (j_strcmp(in_out_buffer, original) == 0) {
		    /* no, we don't need to store a copy of the original string */
		    preped->preped = NULL;
		} else {
		    /* yes, store the stringpreped string */
		    preped->preped = strdup(in_out_buffer);
		}
		preped->last_used = time(NULL);
		preped->used_count = 1;
		preped->size = strlen(in_out_buffer)+1;

		/* acquire the lock on the cache again */
		g_mutex_lock(cache->mutex);

		/* store the entry in the cache */
		g_hash_table_insert(cache->hashtable, original, preped);

		/* we're done, release the lock on the cache */
		g_mutex_unlock(cache->mutex);
	    } else {
		/* we don't need the copy of the key, if there is no memory to store it */
		free(original);
	    }
	} else {
	    /* we don't need the copy of the original value */
	    if (original != NULL)
		free(original);
	}
    }

    return result;
}
Ejemplo n.º 10
0
SilcStringprepStatus
silc_stringprep(const unsigned char *bin, SilcUInt32 bin_len,
		SilcStringEncoding bin_encoding,
		const char *profile_name,
		SilcStringprepFlags flags,
		unsigned char **out, SilcUInt32 *out_len,
		SilcStringEncoding out_encoding)
{
  Stringprep_profile_flags f = 0;
  const Stringprep_profile *profile;
  unsigned char *utf8s;
  SilcUInt32 utf8s_len;
  int ret;

  SILC_LOG_DEBUG(("Preparing string"));

  if (!bin || !bin_len || !profile_name)
    return SILC_STRINGPREP_ERR;

  /* Convert string to UTF-8 */
  utf8s_len = silc_utf8_encoded_len(bin, bin_len, bin_encoding);
  if (!utf8s_len)
    return SILC_STRINGPREP_ERR_ENCODING;
  utf8s = silc_calloc(utf8s_len + 1, sizeof(*utf8s));
  if (!utf8s)
    return SILC_STRINGPREP_ERR_OUT_OF_MEMORY;
  silc_utf8_encode(bin, bin_len, bin_encoding, utf8s, utf8s_len);

  /* Check profile. */
  if (!strcmp(profile_name, SILC_IDENTIFIER_PREP))
    profile = stringprep_silc_identifier_prep;
  else if (!strcmp(profile_name, SILC_IDENTIFIER_CH_PREP))
    profile = stringprep_silc_identifier_ch_prep;
  else if (!strcmp(profile_name, SILC_IDENTIFIERC_PREP))
    profile = stringprep_silc_identifierc_prep;
  else if (!strcmp(profile_name, SILC_CASEFOLD_PREP))
    profile = stringprep_silc_casefold_prep;
  else
    return SILC_STRINGPREP_ERR_UNSUP_PROFILE;

  /* Translate flags */
  if (!(flags & SILC_STRINGPREP_ALLOW_UNASSIGNED))
    f |= STRINGPREP_NO_UNASSIGNED;

  /* Prepare */
  ret = stringprep((char *)utf8s, utf8s_len, f, profile);
  SILC_LOG_DEBUG(("stringprep() return %d", ret));

  /* Since the stringprep() doesn't allocate returned buffer, and
     stringprep_profile() doesn't do it correctly, we can't know how
     much space we must have for the conversion.  Allocate more if it
     fails, and try again. */
  if (ret == STRINGPREP_TOO_SMALL_BUFFER) {
    utf8s = silc_realloc(utf8s, sizeof(*utf8s) * ((utf8s_len * 2) + 1));
    if (!utf8s)
      return SILC_STRINGPREP_ERR_OUT_OF_MEMORY;
    memset(utf8s + utf8s_len + 1, 0, utf8s_len);
    ret = stringprep((char *)utf8s, utf8s_len * 2, f, profile);
    SILC_LOG_DEBUG(("stringprep() return %d", ret));
  }

  switch (ret) {
  case STRINGPREP_OK:
    ret = SILC_STRINGPREP_OK;
    break;

  case STRINGPREP_CONTAINS_UNASSIGNED:
    ret = SILC_STRINGPREP_ERR_UNASSIGNED;
    break;

  case STRINGPREP_CONTAINS_PROHIBITED:
    ret = SILC_STRINGPREP_ERR_PROHIBITED;
    break;

  case STRINGPREP_BIDI_BOTH_L_AND_RAL:
    ret = SILC_STRINGPREP_ERR_BIDI_RAL_WITH_L;
    break;

  case STRINGPREP_BIDI_LEADTRAIL_NOT_RAL:
    ret = SILC_STRINGPREP_ERR_BIDI_RAL;
    break;

  case STRINGPREP_BIDI_CONTAINS_PROHIBITED:
    ret = SILC_STRINGPREP_ERR_BIDI_PROHIBITED;
    break;

  case STRINGPREP_UNKNOWN_PROFILE:
    ret = SILC_STRINGPREP_ERR_UNSUP_PROFILE;
    break;

  case STRINGPREP_MALLOC_ERROR:
    ret = SILC_STRINGPREP_ERR_OUT_OF_MEMORY;
    break;

  default:
    ret = SILC_STRINGPREP_ERR;
    break;
  }

  /* Convert to desired output character encoding */
  if (ret == SILC_STRINGPREP_OK) {
    if (out && out_len) {
      if (out_encoding != SILC_STRING_UTF8) {
	*out_len = silc_utf8_decoded_len(utf8s, strlen(utf8s), out_encoding);
	if (*out_len) {
	  *out = silc_calloc(*out_len + 1, sizeof(**out));
	  if (*out) {
	    silc_utf8_decode(utf8s, strlen(utf8s), out_encoding, *out,
			     *out_len);
	  } else {
	    ret = SILC_STRINGPREP_ERR_OUT_OF_MEMORY;
	  }
	} else {
	  ret = SILC_STRINGPREP_ERR_ENCODING;
	}
      } else {
	*out_len = strlen(utf8s);
	*out = silc_memdup(utf8s, *out_len);
      }
    }
  }

  silc_free(utf8s);

  return (SilcStringprepStatus)ret;
}