Example #1
0
static gint
lua_util_decode_base64 (lua_State *L)
{
	struct rspamd_lua_text *t;
	const gchar *s = NULL;
	gsize inlen, outlen;
	gboolean zero_copy = FALSE, grab_own = FALSE;
	gint state = 0;
	guint save = 0;

	if (lua_type (L, 1) == LUA_TSTRING) {
		s = luaL_checklstring (L, 1, &inlen);
	}
	else if (lua_type (L, 1) == LUA_TUSERDATA) {
		t = lua_check_text (L, 1);

		if (t != NULL) {
			s = t->start;
			inlen = t->len;
			zero_copy = TRUE;
			if (t->own) {
				t->own = FALSE;
				grab_own = TRUE;
			}
		}
	}

	if (s != NULL) {
		if (zero_copy) {
			/* Decode in place */
			outlen = g_base64_decode_step (s, inlen, (guchar *)s, &state, &save);
			t = lua_newuserdata (L, sizeof (*t));
			rspamd_lua_setclass (L, "rspamd{text}", -1);
			t->start = s;
			t->len = outlen;
			t->own = grab_own;
		}
		else {
			t = lua_newuserdata (L, sizeof (*t));
			rspamd_lua_setclass (L, "rspamd{text}", -1);
			t->len = (inlen / 4) * 3 + 3;
			t->start = g_malloc (t->len);
			outlen = g_base64_decode_step (s, inlen, (guchar *)t->start,
					&state, &save);
			t->len = outlen;
			t->own = TRUE;
		}
	}
	else {
		lua_pushnil (L);
	}

	return 1;
}
Example #2
0
static void
soap_sax_characters (gpointer _ctxt,
                     const xmlChar *ch,
                     gint len)
{
	xmlParserCtxt *ctxt = _ctxt;
	ESoapMessagePrivate *priv = ctxt->_private;

	if (priv->steal_fd == -1)
		xmlSAX2Characters (ctxt, ch, len);
	else if (!priv->steal_base64) {
		if (write (priv->steal_fd, (const gchar *) ch, len) != len) {
		write_err:
			/* Handle error better */
			g_warning ("Failed to write streaming data to file");
		}
	} else {
		guchar *bdata = g_malloc (len);
		gsize blen;

		blen = g_base64_decode_step ((const gchar *) ch, len,
					     bdata, &priv->steal_b64_state,
					     &priv->steal_b64_save);
		if (write (priv->steal_fd, (const gchar *) bdata, blen) != blen) {
			g_free (bdata);
			goto write_err;
		}
		g_free (bdata);
	}
}
Example #3
0
gchar *
kms_utils_generate_fingerprint_from_pem (const gchar * pem)
{
  guint i;
  gchar *line;
  guchar *der, *tmp;
  gchar **lines;
  gint state = 0;
  guint save = 0;
  gsize der_length = 0;
  GChecksum *checksum;
  guint8 *digest;
  gsize digest_length;
  GString *fingerprint;
  gchar *ret;

  if (pem == NULL) {
    GST_ERROR ("Pem certificate is null");
    return NULL;
  }
  der = tmp = g_new0 (guchar, (strlen (pem) / 4) * 3 + 3);
  lines = g_strsplit (pem, "\n", 0);

  for (i = 0, line = lines[i]; line; line = lines[++i]) {
    if (line[0] && g_str_has_prefix (line, BEGIN_CERTIFICATE)) {
      i++;
      break;
    }
  }

  for (line = lines[i]; line; line = lines[++i]) {
    if (line[0] && g_str_has_prefix (line, END_CERTIFICATE)) {
      break;
    }
    tmp += g_base64_decode_step (line, strlen (line), tmp, &state, &save);
  }
  der_length = tmp - der;
  checksum = g_checksum_new (G_CHECKSUM_SHA256);
  digest_length = g_checksum_type_get_length (G_CHECKSUM_SHA256);
  digest = g_new (guint8, digest_length);
  g_checksum_update (checksum, der, der_length);
  g_checksum_get_digest (checksum, digest, &digest_length);
  fingerprint = g_string_new (NULL);
  for (i = 0; i < digest_length; i++) {
    if (i)
      g_string_append (fingerprint, ":");
    g_string_append_printf (fingerprint, "%02X", digest[i]);
  }
  ret = g_string_free (fingerprint, FALSE);

  g_free (digest);
  g_checksum_free (checksum);
  g_free (der);
  g_strfreev (lines);

  return ret;
}
Example #4
0
/** Convert Base64 to pixbuf
 * @param b64 Base64 encoded data
 */
GdkPixbuf *
pixbuf_decode_base64 (const gchar *b64)
{
  /* see lib/prop_pixbuf.c(data_pixbuf) for a very similar implementation */
  GdkPixbuf *pixbuf = NULL;
  GdkPixbufLoader *loader;
  GError *error = NULL;

  loader = gdk_pixbuf_loader_new ();
  if (loader) {
    gint state = 0;
    guint save = 0;
#   define BUF_SIZE 4096
    guchar buf[BUF_SIZE];
    gchar *in = (gchar *)b64; /* direct access, not involving another xmlStrDup/xmlFree */
    gssize len = strlen (b64);
	
    do {
      gsize step = g_base64_decode_step (in,
					 len > BUF_SIZE ? BUF_SIZE : len,
					 buf, &state, &save);
      if (!gdk_pixbuf_loader_write (loader, buf, step, &error))
	break;

      in += BUF_SIZE;
      len -= BUF_SIZE;
    } while (len > 0);
    if (gdk_pixbuf_loader_close (loader, error ? NULL : &error)) {
      GdkPixbufFormat *format = gdk_pixbuf_loader_get_format (loader);
      gchar  *format_name = gdk_pixbuf_format_get_name (format);
      gchar **mime_types = gdk_pixbuf_format_get_mime_types (format);

      dia_log_message ("Loaded pixbuf from '%s' with '%s'\n", format_name, mime_types[0]);
      pixbuf = g_object_ref (gdk_pixbuf_loader_get_pixbuf (loader));
      /* attach the mime-type to the pixbuf */
      g_object_set_data_full (G_OBJECT (pixbuf), "mime-type",
			      g_strdup (mime_types[0]),
			      (GDestroyNotify)g_free);
      g_strfreev (mime_types);
      g_free (format_name);
    } else {
      message_warning (_("Failed to load image form diagram:\n%s"), error->message);
      g_error_free (error);
    }

    g_object_unref (loader);
  }
  return pixbuf;
# undef BUF_SIZE
}
Example #5
0
GdkPixbuf *
data_pixbuf (DataNode data)
{
  GdkPixbuf *pixbuf = NULL;
  GdkPixbufLoader *loader;
  GError *error = NULL;
  AttributeNode attr = composite_find_attribute(data, "data");

  loader = gdk_pixbuf_loader_new ();
  if (loader) {
    xmlNode *node = attribute_first_data (attr);
    gint state = 0;
    guint save = 0;
#  define BUF_SIZE 4096
    guchar buf[BUF_SIZE];
    gchar *in = NULL; /* direct access, not involving another xmlStrDup/xmlFree */
    gssize len = 0;

    if (node->children && xmlStrcmp (node->children->name, (const xmlChar*)"text") == 0) {
      in = (gchar *)node->children->content;
      len = strlen ((char *)in);
    }

    do {
      gsize step = g_base64_decode_step (in,
					 len > BUF_SIZE ? BUF_SIZE : len,
					 buf, &state, &save);

      if (!gdk_pixbuf_loader_write (loader, buf, step, &error))
	break;

      in += BUF_SIZE;
      len -= BUF_SIZE;
    } while (len > 0);
    if (gdk_pixbuf_loader_close (loader, error ? NULL : &error)) {
      pixbuf = g_object_ref (gdk_pixbuf_loader_get_pixbuf (loader));
    } else {
      message_warning (_("Failed to load image form diagram:\n%s"), error->message);
      g_error_free (error);
    }

    g_object_unref (loader);
  }
#  undef BUF_SIZE
  return pixbuf;
}
Example #6
0
static gboolean
validate_key (const char *key)
{
	guchar buf[18];
	int state = 0;
	guint save = 0;

	/* The spec requires us to check that the key is "a
	 * base64-encoded value that, when decoded, is 16 bytes in
	 * length".
	 */
	if (strlen (key) != 24)
		return FALSE;
	if (g_base64_decode_step (key, 24, buf, &state, &save) != 16)
		return FALSE;
	return TRUE;
}
Example #7
0
static gchar *
generate_fingerprint_from_pem (const gchar * pem)
{
  guint i;
  gchar *line;
  guchar *der, *tmp;
  gchar **lines;
  gint state = 0;
  guint save = 0;
  gsize der_length = 0;
  GChecksum *checksum;
  guint8 *digest;
  gsize digest_length;
  GString *fingerprint;
  gchar *ret;

  der = tmp = g_new0 (guchar, (strlen (pem) / 4) * 3 + 3);
  lines = g_strsplit (pem, "\n", 0);
  for (i = 0, line = lines[i]; line; line = lines[++i]) {
    if (line[0] && !g_str_has_prefix (line, "-----"))
      tmp += g_base64_decode_step (line, strlen (line), tmp, &state, &save);
  }
  der_length = tmp - der;
  checksum = g_checksum_new (G_CHECKSUM_SHA256);
  digest_length = g_checksum_type_get_length (G_CHECKSUM_SHA256);
  digest = g_new (guint8, digest_length);
  g_checksum_update (checksum, der, der_length);
  g_checksum_get_digest (checksum, digest, &digest_length);
  fingerprint = g_string_new (NULL);
  for (i = 0; i < digest_length; i++) {
    if (i)
      g_string_append (fingerprint, ":");
    g_string_append_printf (fingerprint, "%02X", digest[i]);
  }
  ret = g_string_free (fingerprint, FALSE);

  g_free (digest);
  g_checksum_free (checksum);
  g_free (der);
  g_strfreev (lines);

  return ret;
}
Example #8
0
void got_dtls_certificate(GObject *media_session, GParamSpec *pspec, gpointer user_data)
{
	guint i;
	gchar *pem, *line;
	guchar *der, *tmp;
	gchar **lines;
	gint state = 0;
	guint save = 0;
	gsize der_length = 0;
	GChecksum *checksum;
	guint8 *digest;
	gsize digest_length;
	GString *fingerprint;

	g_object_get(media_session, "dtls-certificate", &pem, NULL);
	der = tmp = g_new0(guchar, (strlen(pem) / 4) * 3 + 3);
	lines = g_strsplit(pem, "\n", 0);
	for (i = 0, line = lines[i]; line; line = lines[++i]) {
		if (line[0] && !g_str_has_prefix(line, "-----"))
			tmp += g_base64_decode_step(line, strlen(line), tmp, &state, &save);
	}
	der_length = tmp - der;
	checksum = g_checksum_new(G_CHECKSUM_SHA256);
	digest_length = g_checksum_type_get_length(G_CHECKSUM_SHA256);
	digest = g_new(guint8, digest_length);
	g_checksum_update(checksum, der, der_length);
	g_checksum_get_digest(checksum, digest, &digest_length);
	fingerprint = g_string_new(NULL);
	for (i = 0; i < digest_length; i++) {
		if (i)
			g_string_append(fingerprint, ":");
		g_string_append_printf(fingerprint, "%02X", digest[i]);
	}
	gchar *fprint = g_string_free(fingerprint, FALSE);
	got_dtls_certificate_go(OWR_SESSION(media_session), fprint);

	g_free(fprint);
	g_free(digest);
	g_checksum_free(checksum);
	g_free(der);
	g_strfreev(lines);
}
Example #9
0
static GBytes *
base64_decode (GBytes *bytes)
{
  gconstpointer data;
  guchar *decoded;
  gsize length;
  gint state = 0;
  guint save = 0;

  data = g_bytes_get_data (bytes, &length);

  if (length == 0)
    return g_bytes_new_static ("", 0);

  /* We can use a smaller limit here, since we know the saved state is 0,
     +1 used to avoid calling g_malloc0(0), and hence returning NULL */
  decoded = g_malloc0 ((length / 4) * 3 + 3);
  length = g_base64_decode_step (data, length, decoded, &state, &save);

  return g_bytes_new_take (decoded, length);
}
Example #10
0
/** Convert Base64 to pixbuf
 * @param b64 Base64 encoded data
 */
GdkPixbuf *
pixbuf_decode_base64 (const gchar *b64)
{
  /* see lib/prop_pixbuf.c(data_pixbuf) for a very similiar implementation */
  GdkPixbuf *pixbuf = NULL;
  GdkPixbufLoader *loader;
  GError *error = NULL;

  loader = gdk_pixbuf_loader_new ();
  if (loader) {
    gint state = 0;
    guint save = 0;
#   define BUF_SIZE 4096
    guchar buf[BUF_SIZE];
    gchar *in = (gchar *)b64; /* direct access, not involving another xmlStrDup/xmlFree */
    gssize len = strlen (b64);
	
    do {
      gsize step = g_base64_decode_step (in,
					 len > BUF_SIZE ? BUF_SIZE : len,
					 buf, &state, &save);
      if (!gdk_pixbuf_loader_write (loader, buf, step, &error))
	break;

      in += BUF_SIZE;
      len -= BUF_SIZE;
    } while (len > 0);
    if (gdk_pixbuf_loader_close (loader, error ? NULL : &error)) {
      pixbuf = g_object_ref (gdk_pixbuf_loader_get_pixbuf (loader));
    } else {
      message_warning (_("Failed to load image form diagram:\n%s"), error->message);
      g_error_free (error);
    }

    g_object_unref (loader);
  }
  return pixbuf;
# undef BUF_SIZE
}
GkmDataResult
gkm_ssh_openssh_parse_public_key (gconstpointer input, gsize n_data,
                                  gcry_sexp_t *sexp, gchar **comment)
{
	EggBuffer buf;
	const guchar *at;
	guchar *decoded;
	gsize n_decoded;
	gsize offset;
	gchar *val;
	gboolean ret;
	gint state, algo;
	guint save;
	const guchar *data = input;

	g_return_val_if_fail (data, FALSE);
	g_return_val_if_fail (sexp, FALSE);

	/* Look for a key line */
	for (;;) {
		/* Eat space at the front */
		while (n_data > 0 && g_ascii_isspace (data[0])) {
			++data;
			--n_data;
		}

		/* Not a comment or blank line? Then parse... */
		if (data[0] != '#')
			break;

		/* Skip to the next line */
		at = memchr (data, '\n', n_data);
		if (!at)
			return GKM_DATA_UNRECOGNIZED;
		at += 1;
		n_data -= (at - data);
		data = at;
	}

	/* Limit to use only the first line */
	at = memchr (data, '\n', n_data);
	if (at != NULL)
		n_data = at - data;

	/* Find the first space */
	at = memchr (data, ' ', n_data);
	if (!at) {
		g_message ("SSH public key missing space");
		return GKM_DATA_UNRECOGNIZED;
	}

	/* Parse the key type */
	val = g_strndup ((gchar*)data, at - data);
	algo = keytype_to_algo (val);
	if (!algo) {
		/* A number usually means an SSH1 key, just quietly ignore */
		if (atoi (val) == 0)
			g_message ("Unsupported or unknown SSH key algorithm: %s", val);
	}
	g_free (val);
	if (!algo)
		return GKM_DATA_UNRECOGNIZED;

	/* Skip more whitespace */
	n_data -= (at - data);
	data = at;
	while (n_data > 0 && (data[0] == ' ' || data[0] == '\t')) {
		++data;
		--n_data;
	}

	/* Find the next whitespace, or the end */
	at = memchr (data, ' ', n_data);
	if (at == NULL)
		at = data + n_data;

	/* Decode the base64 key */
	save = state = 0;
	decoded = g_malloc (n_data * 3 / 4);
	n_decoded = g_base64_decode_step ((gchar*)data, n_data, decoded, &state, &save);

	/* Parse the actual key */
	egg_buffer_init_static (&buf, decoded, n_decoded);
	offset = 0;
	ret = read_public (&buf, &offset, sexp, NULL);
	g_free (decoded);
	if (!ret) {
		g_message ("failed to parse base64 part of SSH key");
		return GKM_DATA_FAILURE;
	}

	/* Skip more whitespace */
	n_data -= (at - data);
	data = at;
	while (n_data > 0 && (data[0] == ' ' || data[0] == '\t')) {
		++data;
		--n_data;
	}

	/* If there's data left, its the comment */
	if (comment)
		*comment = n_data ? g_strndup ((gchar*)data, n_data) : NULL;

	return GKM_DATA_SUCCESS;
}
static GHashTable*
inf_gtk_certificate_manager_load_known_hosts(InfGtkCertificateManager* mgr,
                                             GError** error)
{
  InfGtkCertificateManagerPrivate* priv;
  GHashTable* table;
  gchar* content;
  gsize size;
  GError* local_error;

  gchar* out_buf;
  gsize out_buf_len;
  gchar* pos;
  gchar* prev;
  gchar* next;
  gchar* sep;

  gsize len;
  gsize out_len;
  gint base64_state;
  guint base64_save;

  gnutls_datum_t data;
  gnutls_x509_crt_t cert;
  int res;

  priv = INF_GTK_CERTIFICATE_MANAGER_PRIVATE(mgr);

  table = g_hash_table_new_full(
    g_str_hash,
    g_str_equal,
    g_free,
    (GDestroyNotify)gnutls_x509_crt_deinit
  );

  local_error = NULL;
  g_file_get_contents(priv->known_hosts_file, &content, &size, &local_error);
  if(local_error != NULL)
  {
    if(local_error->domain == G_FILE_ERROR &&
       local_error->code == G_FILE_ERROR_NOENT)
    {
      return table;
    }

    g_propagate_prefixed_error(
      error,
      local_error,
      _("Failed to open known hosts file \"%s\": "),
      priv->known_hosts_file
    );

    g_hash_table_destroy(table);
    return NULL;
  }

  out_buf = NULL;
  out_buf_len = 0;
  prev = content;
  for(prev = content; prev != NULL; prev = next)
  {
    pos = strchr(prev, '\n');
    next = NULL;

    if(pos == NULL)
      pos = content + size;
    else
      next = pos + 1;

    sep = inf_gtk_certificate_manager_memrchr(prev, ':', pos - prev);
    if(sep == NULL) continue; /* ignore line */

    *sep = '\0';
    if(g_hash_table_lookup(table, prev) != NULL)
    {
      g_set_error(
        error,
        g_quark_from_static_string("INF_GTK_CERTIFICATE_MANAGER_ERROR"),
        INF_GTK_CERTIFICATE_MANAGER_ERROR_DUPLICATE_HOST_ENTRY,
        _("Certificate for host \"%s\" appears twice in "
          "known hosts file \"%s\""),
        prev,
        priv->known_hosts_file
      );

      g_hash_table_destroy(table);
      g_free(out_buf);
      g_free(content);
      return NULL;
    }

    /* decode base64, import DER certificate */
    len = (pos - (sep + 1));
    out_len = len * 3 / 4;

    if(out_len > out_buf_len)
    {
      out_buf = g_realloc(out_buf, out_len);
      out_buf_len = out_len;
    }

    base64_state = 0;
    base64_save = 0;

    out_len = g_base64_decode_step(
      sep + 1,
      len,
      out_buf,
      &base64_state,
      &base64_save
    );

    cert = NULL;
    res = gnutls_x509_crt_init(&cert);
    if(res == GNUTLS_E_SUCCESS)
    {
      data.data = out_buf;
      data.size = out_len;
      res = gnutls_x509_crt_import(cert, &data, GNUTLS_X509_FMT_DER);
    }

    if(res != GNUTLS_E_SUCCESS)
    {
      inf_gnutls_set_error(&local_error, res);

      g_propagate_prefixed_error(
        error,
        local_error,
        _("Failed to read certificate for host \"%s\" from "
          "known hosts file \"%s\": "),
        prev,
        priv->known_hosts_file
      );

      if(cert != NULL)
        gnutls_x509_crt_deinit(cert);

      g_hash_table_destroy(table);
      g_free(out_buf);
      g_free(content);
      return NULL;
    }

    g_hash_table_insert(table, g_strdup(prev), cert);
  }

  g_free(out_buf);
  g_free(content);
  return table;
}
Example #13
0
static int parse_attribute_crypto(struct sdp_attribute *output) {
	PARSE_DECL;
	char *endp;
	struct attribute_crypto *c;
	int salt_key_len, enc_salt_key_len;
	int b64_state = 0;
	unsigned int b64_save = 0;
	gsize ret;
	str s;
	u_int32_t u32;
	const char *err;

	output->attr = ATTR_CRYPTO;

	PARSE_INIT;
	EXTRACT_TOKEN(u.crypto.tag_str);
	EXTRACT_TOKEN(u.crypto.crypto_suite_str);
	EXTRACT_TOKEN(u.crypto.key_params_str);

	c = &output->u.crypto;

	c->tag = strtoul(c->tag_str.s, &endp, 10);
	err = "invalid 'tag'";
	if (endp == c->tag_str.s)
		goto error;

	c->crypto_suite = crypto_find_suite(&c->crypto_suite_str);
	err = "unknown crypto suite";
	if (!c->crypto_suite)
		goto error;
	salt_key_len = c->crypto_suite->master_key_len
			+ c->crypto_suite->master_salt_len;
	enc_salt_key_len = ceil((double) salt_key_len * 4.0/3.0);

	err = "invalid key parameter length";
	if (c->key_params_str.len < 7 + enc_salt_key_len)
		goto error;
	err = "unknown key method";
	if (strncasecmp(c->key_params_str.s, "inline:", 7))
		goto error;
	c->key_base64_str = c->key_params_str;
	str_shift(&c->key_base64_str, 7);
	ret = g_base64_decode_step(c->key_base64_str.s, enc_salt_key_len,
			(guchar *) c->key_salt_buf, &b64_state, &b64_save);
	err = "invalid base64 encoding";
	if (ret != salt_key_len)
		goto error;

	c->master_key.s = c->key_salt_buf;
	c->master_key.len = c->crypto_suite->master_key_len;
	c->salt.s = c->master_key.s + c->master_key.len;
	c->salt.len = c->crypto_suite->master_salt_len;

	c->lifetime_str = c->key_params_str;
	str_shift(&c->lifetime_str, 7 + enc_salt_key_len);
	if (c->lifetime_str.len >= 2) {
		err = "invalid key parameter syntax";
		if (c->lifetime_str.s[0] != '|')
			goto error;
		str_shift(&c->lifetime_str, 1);
		str_chr_str(&c->mki_str, &c->lifetime_str, '|');
		if (!c->mki_str.s) {
			if (str_chr(&c->lifetime_str, ':')) {
				c->mki_str = c->lifetime_str;
				c->lifetime_str = STR_NULL;
			}
		}
		else {
			c->lifetime_str.len = c->mki_str.s - c->lifetime_str.s;
			str_shift(&c->mki_str, 1);
		}
	}
	else
		c->lifetime_str = STR_NULL;

	if (c->lifetime_str.s) {
		if (c->lifetime_str.len >= 3 && !memcmp(c->lifetime_str.s, "2^", 2)) {
			c->lifetime = strtoull(c->lifetime_str.s + 2, NULL, 10);
			err = "invalid key lifetime";
			if (!c->lifetime || c->lifetime > 64)
				goto error;
			c->lifetime = 1ULL << c->lifetime;
		}
		else
			c->lifetime = strtoull(c->lifetime_str.s, NULL, 10);

		err = "invalid key lifetime";
		if (!c->lifetime || c->lifetime > c->crypto_suite->srtp_lifetime
#ifdef STRICT_SDES_KEY_LIFETIME
				|| c->lifetime > c->crypto_suite->srtcp_lifetime
#endif
				)
			goto error;
	}

	if (c->mki_str.s) {
		str_chr_str(&s, &c->mki_str, ':');
		err = "invalid MKI specification";
		if (!s.s)
			goto error;
		u32 = htonl(strtoul(c->mki_str.s, NULL, 10));
		c->mki_len = strtoul(s.s + 1, NULL, 10);
		err = "MKI too long";
		if (c->mki_len > sizeof(c->mki))
			goto error;
		memset(c->mki, 0, c->mki_len);
		if (sizeof(u32) >= c->mki_len)
			memcpy(c->mki, ((void *) &u32) + (sizeof(u32) - c->mki_len), c->mki_len);
		else
			memcpy(c->mki + (c->mki_len - sizeof(u32)), &u32, sizeof(u32));
	}

	while (extract_token(&start, end, &s) == 0) {
		if (!str_cmp(&s, "UNENCRYPTED_SRTCP"))
			c->unencrypted_srtcp = 1;
		else if (!str_cmp(&s, "UNENCRYPTED_SRTP"))
			c->unencrypted_srtp = 1;
		else if (!str_cmp(&s, "UNAUTHENTICATED_SRTP"))
			c->unauthenticated_srtp = 1;
	}

	return 0;

error:
	ilog(LOG_ERROR, "Failed to parse a=crypto attribute: %s", err);
	return -1;
}
Example #14
0
/* called from the GMarkupParser */
static void
text_handler           (GMarkupParseContext  *markup_context,
                        const gchar          *text,
                        gsize                 text_len,
                        gpointer              user_data,
                        GError              **error)
{
  XMPParseContext *context = user_data;

  switch (context->state)
    {
    case STATE_INSIDE_PROPERTY:
      if (! is_whitespace_string (text))
        add_property_value (context, XMP_PTYPE_TEXT, NULL,
                            g_strndup (text, text_len));
      break;

    case STATE_INSIDE_STRUCT_ELEMENT:
    case STATE_INSIDE_ALT_LI:
    case STATE_INSIDE_BAG_LI:
    case STATE_INSIDE_SEQ_LI:
      if (! is_whitespace_string (text))
        update_property_value (context, g_strndup (text, text_len));
      break;

    case STATE_INSIDE_ALT_LI_RSC_IMG:
      {
        size_t  len, max_size;
        guchar *decoded;
        gint    decoded_size;
        gint    state;
        guint   save;

#ifdef DEBUG_XMP_PARSER
        /* g_print ("XMP: Pushing text:\n%s\n", text); */
#endif
        len = text_len - text_len;
        max_size = (len / 4) * 3 + 3;
        decoded = g_malloc (max_size);

        state = 0;
        save = 0;
        decoded_size = g_base64_decode_step (text, text_len,
                                             decoded,
                                             &state, &save);
#ifdef DEBUG_XMP_PARSER
        if (decoded_size > 0)
          {
            /* FIXME: remove this debugging code */
            /*
            FILE *ttt;

            ttt = fopen ("/tmp/xmp-thumb.jpg", "wb");
            fwrite (decoded, decoded_size, 1, ttt);
            fclose (ttt);
            */
            g_print ("XMP: Thumb text len: %d (1/4 = %d)\nMax size: %d\nUsed size: %d\n", (int) text_len, (int) text_len / 4, max_size, decoded_size);
          }
#endif
        if (decoded_size > 0)
          {
            gint  *size_p;

            size_p = g_new (gint, 1);
            *size_p = decoded_size;
            add_property_value (context, XMP_PTYPE_ALT_THUMBS,
                                (gchar *) size_p, (gchar *) decoded);
          }
        else
          add_property_value (context, XMP_PTYPE_ALT_THUMBS, NULL, NULL);
      }
      break;

    case STATE_INSIDE_QDESC_VALUE:
      if (! is_whitespace_string (text))
        {
          if (context->saved_state == STATE_INSIDE_PROPERTY)
            add_property_value (context, XMP_PTYPE_TEXT, NULL,
                                g_strndup (text, text_len));
          else
            update_property_value (context, g_strndup (text, text_len));
        }
      break;

    case STATE_INSIDE_QDESC_QUAL:
#ifdef DEBUG_XMP_PARSER
      g_print ("ignoring qualifier for part of \"%s\"[]: \"%.*s\"\n",
	       context->property,
	       (int)text_len, text);
#endif
      /* FIXME: notify the user? add a way to collect qualifiers? */
      break;

    case STATE_SKIPPING_UNKNOWN_ELEMENTS:
    case STATE_SKIPPING_IGNORED_ELEMENTS:
      break;

    default:
      if (! is_whitespace_string (text))
	parse_error (context, error, XMP_ERROR_INVALID_CONTENT,
			 _("The current element (<%s>) cannot contain text"),
                         g_markup_parse_context_get_element (markup_context));
      break;
    }
}
Example #15
0
static GInputStream *
soup_request_data_send (SoupRequest   *request,
			GCancellable  *cancellable,
			GError       **error)
{
	SoupRequestData *data = SOUP_REQUEST_DATA (request);
	SoupURI *uri = soup_request_get_uri (request);
	GInputStream *memstream;
	const char *comma, *start, *end;
	gboolean base64 = FALSE;
	char *uristr;

	uristr = soup_uri_to_string (uri, FALSE);
	start = uristr + 5;
	comma = strchr (start, ',');
	if (comma && comma != start) {
		/* Deal with MIME type / params */
		if (comma > start + BASE64_INDICATOR_LEN && !g_ascii_strncasecmp (comma - BASE64_INDICATOR_LEN, BASE64_INDICATOR, BASE64_INDICATOR_LEN)) {
			end = comma - BASE64_INDICATOR_LEN;
			base64 = TRUE;
		} else
			end = comma;

		if (end != start) {
			char *encoded_content_type = g_strndup (start, end - start);

			if (base64)
				data->priv->content_type = encoded_content_type;
			else {
				data->priv->content_type = soup_uri_decode (encoded_content_type);
				g_free (encoded_content_type);
			}
		}
	}

	memstream = g_memory_input_stream_new ();

	if (comma)
		start = comma + 1;

	if (*start) {
		guchar *buf;

		if (base64) {
			int inlen, state = 0;
			guint save = 0;

			inlen = strlen (start);
			buf = g_malloc0 (inlen * 3 / 4 + 3);
			data->priv->content_length =
				g_base64_decode_step (start, inlen, buf,
						      &state, &save);
			if (state != 0) {
				g_free (buf);
				goto fail;
			}
		} else {
			buf = (guchar *) soup_uri_decode (start);
			data->priv->content_length = strlen ((const char *) buf);
		}

		g_memory_input_stream_add_data (G_MEMORY_INPUT_STREAM (memstream),
						buf, data->priv->content_length,
						g_free);
	}
	g_free (uristr);

	return memstream;

 fail:
	g_free (uristr);
	g_set_error (error, SOUP_REQUESTER_ERROR, SOUP_REQUESTER_ERROR_BAD_URI,
		     _("Unable to decode URI: %s"), start);
	g_object_unref (memstream);
	return NULL;
}
static gboolean
pem_parse_block (const gchar *data, gsize n_data, guchar **decoded, gsize *n_decoded,
                 GHashTable **headers)
{
	const gchar *x, *hbeg, *hend;
	const gchar *p, *end;
	gint state = 0;
	guint save = 0;
	
	g_assert (data);
	g_assert (n_data);
	
	g_assert (decoded);
	g_assert (n_decoded);
	
	p = data;
	end = p + n_data;
	
	hbeg = hend = NULL;
	
	/* Try and find a pair of blank lines with only white space between */
	while (hend == NULL) {
		x = memchr (p, '\n', end - p);
		if (!x)
			break;
		++x;
		while (isspace (*x)) {
			/* Found a second line, with only spaces between */
			if (*x == '\n') {
				hbeg = data;
				hend = x;
				break;
			/* Found a space between two lines */
			} else {
				++x;
			}
		}
		
		/* Try next line */
		p = x;
	}

	/* Headers found? */	
	if (hbeg && hend) {
		data = hend;
		n_data = end - data;
	}
	
	*n_decoded = (n_data * 3) / 4 + 1;
	if (egg_secure_check (data))
		*decoded = egg_secure_alloc (*n_decoded);
	else
		*decoded = g_malloc0 (*n_decoded);
	g_return_val_if_fail (*decoded, FALSE);
	
	*n_decoded = g_base64_decode_step (data, n_data, *decoded, &state, &save);
	if (!*n_decoded) {
		egg_secure_free (*decoded);
		return FALSE;
	}
	
	if (headers && hbeg && hend) 
		parse_header_lines (hbeg, hend, headers);
	
	return TRUE;
}
Example #17
0
static void
test_incremental (gboolean line_break, 
		  gint     length)
{
  char *p;
  gsize len, decoded_len, max, input_len, block_size;
  int state, save;
  guint decoder_save;
  char *text;
  guchar *data2;

  data2 = g_malloc (length);
  text = g_malloc (length * 4);

  len = 0;
  state = 0;
  save = 0;
  input_len = 0;
  while (input_len < length)
    {
      block_size = MIN (BLOCK_SIZE, length - input_len);
      len += g_base64_encode_step (data + input_len, block_size,
				   line_break, text + len, &state, &save);
      input_len += block_size;
    }
  len += g_base64_encode_close (line_break, text + len, &state, &save);

  if (line_break)
    max = length * 4 / 3 + length * 4 / (3 * 72) + 7;
  else
    max = length * 4 / 3 + 6;
  if (len > max)
    {
      g_print ("Too long encoded length: got %d, expected max %d\n",
	       len, max);
      exit (1);
    }

  decoded_len = 0;
  state = 0;
  decoder_save = 0;
  p = text;
  while (len > 0)
    {
      int chunk_len = MIN (BLOCK_SIZE, len);
      decoded_len += g_base64_decode_step (p, 
					   chunk_len, 
					   data2 + decoded_len,
					   &state, &decoder_save);
      p += chunk_len;
      len -= chunk_len;
    }
 
  if (decoded_len != length)
    {
      g_print ("Wrong decoded length: got %d, expected %d\n",
	       decoded_len, length);
      exit (1);
    }

  if (memcmp (data, data2, length) != 0)
    {
      g_print ("Wrong decoded base64 data\n");
      exit (1);
    }

  g_free (text);
  g_free (data2);
}