Index: Makefile
===================================================================
--- Makefile	(revision 71f87bae7a18551af0e8692e1b588dea32c22483)
+++ Makefile	(revision 1522faf1c44fa65a3bd3e544561974f8b2b18b97)
@@ -159,5 +159,5 @@
 	x=$$(basename $$(pwd)); \
 	cd ..; \
-	tar czf $$x.tar.gz --exclude-from=.gitignore $$x
+	tar czf $$x.tar.gz --exclude=debian --exclude=.git* --exclude=.depend $$x
 
 $(subdirs):
Index: bitlbee.h
===================================================================
--- bitlbee.h	(revision 71f87bae7a18551af0e8692e1b588dea32c22483)
+++ bitlbee.h	(revision 1522faf1c44fa65a3bd3e544561974f8b2b18b97)
@@ -36,8 +36,8 @@
 
 #define PACKAGE "BitlBee"
-#define BITLBEE_VERSION "3.2.2"
+#define BITLBEE_VERSION "3.4"
 #define VERSION BITLBEE_VERSION
 #define BITLBEE_VER(a, b, c) (((a) << 16) + ((b) << 8) + (c))
-#define BITLBEE_VERSION_CODE BITLBEE_VER(3, 2, 2)
+#define BITLBEE_VERSION_CODE BITLBEE_VER(3, 4, 0)
 
 #define MAX_STRING 511
Index: doc/CHANGES
===================================================================
--- doc/CHANGES	(revision 71f87bae7a18551af0e8692e1b588dea32c22483)
+++ doc/CHANGES	(revision 1522faf1c44fa65a3bd3e544561974f8b2b18b97)
@@ -1,6 +1,49 @@
 This ChangeLog mostly lists changes relevant to users. A full log can be
-found in the bzr commit logs, for example you can try:
-
-http://bugs.bitlbee.org/bitlbee/timeline?daysback=90&changeset=on
+found in the git commit logs, for example you can try:
+
+https://github.com/bitlbee/bitlbee/commits/master
+
+Version 3.4:
+- First release pretty much fully prepared by dx instead of Wilmer. Just look
+  at the tightly structured changelog!
+- Main repository migrated from bzr to git
+- Some API/ABI changes. Recompiling third party plugins is required!
+- Important bugfixes:
+  * Fix memory leak when calling word_wrap() on groupchat messages (dx)
+  * Fix segfault after a file transfer is complete (dx)
+  * Fix bug where NSS would refuse to work in forkdaemon mode (dx)
+  * Fix several bugs with UTF8 nicks (dx)
+  * Fix some nasty deadlocks that appared mostly with libpurple (dx)
+- General changes:
+  * Add a 'pattern' parameter to the blist command, to filter it (tribut)
+  * Implemented /kick support, only supported by purple for now (jgeboski)
+  * Add a "special" state to show_users (mapped to the % prefix) (jgeboski)
+  * Improved support for cygwin, openbsd and darwin (jcopenha)
+  * Create temporary users instead of showing "Message from unknown
+    participant" (jgeboski)
+- purple:
+  * Local contact lists for gadugadu and whatsapp (dx)
+  * Add topic and name_hint to groupchats (seirl)
+  * Support for 'input' requests (such as telegram auth codes) (seirl)
+    Note that telegram-purple itself is rather unstable ATM, it may crash.
+- jabber:
+  * Handle compressed DNS responses in SRV lookup (jcopenha)
+  * Fix case sensitivity issues with JIDs (GRMrGecko, dx)
+  * Implement XEP-0203 style message timestamps (dx)
+  * Fix "Server claims your JID is X instead of Y" warnings (dx)
+  * Account-wide display_name setting, mostly for hipchat (dx)
+- twitter:
+  * Filter channels. Search by keyword/hashtag or a list of users (jgeboski)
+  * Fix bug in "reply" command which removed the first quote character (dx)
+  * Add "rawreply" command, like reply but bitlbee won't add @mention (WillP)
+  * Add support for The United States of America (favorite/fav aliases) (dx)
+  * Default show_old_mentions to 0 (dx)
+  * Start stream from last tweet on connect/reconnect (roger)
+- msn:
+  * Disabled module by default. The protocol we used (MSNP18) stopped working
+    last week. This is being worked on, but it's far from ready for release.
+- And lots of small bugfixes, too many to list here.
+
+Finished 25 Mar 2015
 
 Version 3.2.2:
Index: doc/user-guide/misc.xml
===================================================================
--- doc/user-guide/misc.xml	(revision 71f87bae7a18551af0e8692e1b588dea32c22483)
+++ doc/user-guide/misc.xml	(revision 1522faf1c44fa65a3bd3e544561974f8b2b18b97)
@@ -409,3 +409,27 @@
 </sect1>
 
+<sect1 id="whatsnew030400">
+<title>New stuff in BitlBee 3.4</title>
+
+<para>
+Lots of bugfixes! <emphasis>Important:</emphasis> Recompiling third party plugins such as bitlbee-steam or bitlbee-facebook is <emphasis>required</emphasis>!
+</para>
+
+<simplelist>
+	<member><emphasis>twitter:</emphasis> Filter channels - Search by keyword/hashtag or a list of users. See the <emphasis>HowtoTwitter</emphasis> wiki page for more details!</member>
+	<member><emphasis>twitter:</emphasis> Add "rawreply" command, like reply but bitlbee won't add @mention. Also add "favorite" / "fav" command aliases.</member>
+	<member><emphasis>twitter:</emphasis> Start stream from last tweet on connect/reconnect to avoid showing duplicate tweets</member>
+	<member><emphasis>jabber:</emphasis> Fixed crashes with file transfers (they still fail at bypassing NATs, but at least they fail without crashing)</member>
+	<member><emphasis>purple:</emphasis> Improved support for gadugadu, whatsapp and telegram.</member>
+	<member><emphasis>msn:</emphasis> disabled in this release since the protocol we used (MSNP18) stopped working.</member>
+	<member>Add a 'pattern' parameter to the blist command, to filter it.</member>
+	<member>The <emphasis>utf8_nicks</emphasis> setting should be more reliable now.</member>
+</simplelist>
+
+<para>
+See the full changelog for details!
+</para>
+
+</sect1>
+
 </chapter>
Index: irc_channel.c
===================================================================
--- irc_channel.c	(revision 71f87bae7a18551af0e8692e1b588dea32c22483)
+++ irc_channel.c	(revision 1522faf1c44fa65a3bd3e544561974f8b2b18b97)
@@ -588,14 +588,16 @@
 char *irc_channel_name_gen(bee_t *bee, const char *hint)
 {
-	char name[MAX_NICK_LENGTH + 1] = { 0 };
-
-	name[0] = '#';
-	strncpy(name + 1, hint, MAX_NICK_LENGTH - 1);
-	name[MAX_NICK_LENGTH] = '\0';
+	char *name, *final_name;
+	gsize bytes_written;
+
+	name = g_convert_with_fallback(hint, -1, "ASCII//TRANSLIT", "UTF-8", "", NULL, &bytes_written, NULL);
+	if (bytes_written > MAX_NICK_LENGTH) {
+		name[MAX_NICK_LENGTH] = '\0';
+	}
 
 	irc_channel_name_strip(name);
 
 	if (set_getbool(&bee->set, "lcnicks")) {
-		nick_lc(bee->ui_data, name + 1);
+		nick_lc(bee->ui_data, name);
 	}
 
@@ -604,5 +606,9 @@
 	}
 
-	return g_strdup(name);
+	final_name = g_strconcat("#", name, NULL);
+
+	g_free(name);
+
+	return final_name;
 }
 
Index: irc_im.c
===================================================================
--- irc_im.c	(revision 71f87bae7a18551af0e8692e1b588dea32c22483)
+++ irc_im.c	(revision 1522faf1c44fa65a3bd3e544561974f8b2b18b97)
@@ -235,5 +235,5 @@
 			} else {
 				/* Modules can swallow messages. */
-				return TRUE;
+				goto cleanup;
 			}
 		}
@@ -250,6 +250,7 @@
 	wrapped = word_wrap(msg, 425);
 	irc_send_msg(iu, "PRIVMSG", dst, wrapped, prefix);
-
 	g_free(wrapped);
+
+cleanup:
 	g_free(prefix);
 	g_free(msg);
@@ -291,4 +292,6 @@
 
 	irc_send_msg((irc_user_t *) bu->ui_data, "NOTICE", irc->user->nick, msg->str, NULL);
+
+	g_string_free(msg, TRUE);
 
 	return TRUE;
Index: lib/proxy.c
===================================================================
--- lib/proxy.c	(revision 71f87bae7a18551af0e8692e1b588dea32c22483)
+++ lib/proxy.c	(revision 1522faf1c44fa65a3bd3e544561974f8b2b18b97)
@@ -63,5 +63,14 @@
 static int proxy_connect_none(const char *host, unsigned short port_, struct PHB *phb);
 
-static gboolean gaim_io_connected(gpointer data, gint source, b_input_condition cond)
+static gboolean phb_close(struct PHB *phb)
+{
+	close(phb->fd);
+	phb->func(phb->data, -1, B_EV_IO_READ);
+	g_free(phb->host);
+	g_free(phb);
+	return FALSE;
+}
+
+static gboolean proxy_connected(gpointer data, gint source, b_input_condition cond)
 {
 	struct PHB *phb = data;
@@ -80,22 +89,16 @@
 				dup2(new_fd, source);
 				closesocket(new_fd);
-				phb->inpa = b_input_add(source, B_EV_IO_WRITE, gaim_io_connected, phb);
+				phb->inpa = b_input_add(source, B_EV_IO_WRITE, proxy_connected, phb);
 				return FALSE;
 			}
 		}
-		freeaddrinfo(phb->gai);
 		closesocket(source);
-		b_event_remove(phb->inpa);
-		phb->inpa = 0;
-		if (phb->proxy_func) {
-			phb->proxy_func(phb->proxy_data, -1, B_EV_IO_READ);
-		} else {
-			phb->func(phb->data, -1, B_EV_IO_READ);
-			g_free(phb);
-		}
-		return FALSE;
-	}
+		source = -1;
+		/* socket is dead, but continue to clean up */
+	} else {
+		sock_make_blocking(source);
+	}
+
 	freeaddrinfo(phb->gai);
-	sock_make_blocking(source);
 	b_event_remove(phb->inpa);
 	phb->inpa = 0;
@@ -160,5 +163,5 @@
 			continue;
 		} else {
-			phb->inpa = b_input_add(fd, B_EV_IO_WRITE, gaim_io_connected, phb);
+			phb->inpa = b_input_add(fd, B_EV_IO_WRITE, proxy_connected, phb);
 			phb->fd = fd;
 
@@ -206,10 +209,5 @@
 	}
 
-	close(source);
-	phb->func(phb->data, -1, B_EV_IO_READ);
-	g_free(phb->host);
-	g_free(phb);
-
-	return FALSE;
+	return phb_close(phb);
 }
 
@@ -226,9 +224,5 @@
 	len = sizeof(error);
 	if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
-		close(source);
-		phb->func(phb->data, -1, B_EV_IO_READ);
-		g_free(phb->host);
-		g_free(phb);
-		return FALSE;
+		return phb_close(phb);
 	}
 	sock_make_blocking(source);
@@ -237,9 +231,5 @@
 	           phb->host, phb->port);
 	if (send(source, cmd, strlen(cmd), 0) < 0) {
-		close(source);
-		phb->func(phb->data, -1, B_EV_IO_READ);
-		g_free(phb->host);
-		g_free(phb);
-		return FALSE;
+		return phb_close(phb);
 	}
 
@@ -252,9 +242,5 @@
 		g_free(t2);
 		if (send(source, cmd, strlen(cmd), 0) < 0) {
-			close(source);
-			phb->func(phb->data, -1, B_EV_IO_READ);
-			g_free(phb->host);
-			g_free(phb);
-			return FALSE;
+			return phb_close(phb);
 		}
 	}
@@ -262,9 +248,5 @@
 	g_snprintf(cmd, sizeof(cmd), "\r\n");
 	if (send(source, cmd, strlen(cmd), 0) < 0) {
-		close(source);
-		phb->func(phb->data, -1, B_EV_IO_READ);
-		g_free(phb->host);
-		g_free(phb);
-		return FALSE;
+		return phb_close(phb);
 	}
 
@@ -302,10 +284,5 @@
 	}
 
-	close(source);
-	phb->func(phb->data, -1, B_EV_IO_READ);
-	g_free(phb->host);
-	g_free(phb);
-
-	return FALSE;
+	return phb_close(phb);
 }
 
@@ -323,9 +300,5 @@
 	len = sizeof(error);
 	if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
-		close(source);
-		phb->func(phb->data, -1, B_EV_IO_READ);
-		g_free(phb->host);
-		g_free(phb);
-		return FALSE;
+		return phb_close(phb);
 	}
 	sock_make_blocking(source);
@@ -333,9 +306,5 @@
 	/* XXX does socks4 not support host name lookups by the proxy? */
 	if (!(hp = gethostbyname(phb->host))) {
-		close(source);
-		phb->func(phb->data, -1, B_EV_IO_READ);
-		g_free(phb->host);
-		g_free(phb);
-		return FALSE;
+		return phb_close(phb);
 	}
 
@@ -350,9 +319,5 @@
 	packet[8] = 0;
 	if (write(source, packet, 9) != 9) {
-		close(source);
-		phb->func(phb->data, -1, B_EV_IO_READ);
-		g_free(phb->host);
-		g_free(phb);
-		return FALSE;
+		return phb_close(phb);
 	}
 
@@ -383,16 +348,8 @@
 
 	if (read(source, buf, 10) < 10) {
-		close(source);
-		phb->func(phb->data, -1, B_EV_IO_READ);
-		g_free(phb->host);
-		g_free(phb);
-		return FALSE;
+		return phb_close(phb);
 	}
 	if ((buf[0] != 0x05) || (buf[1] != 0x00)) {
-		close(source);
-		phb->func(phb->data, -1, B_EV_IO_READ);
-		g_free(phb->host);
-		g_free(phb);
-		return FALSE;
+		return phb_close(phb);
 	}
 
@@ -420,8 +377,5 @@
 
 	if (write(source, buf, (5 + strlen(phb->host) + 2)) < (5 + strlen(phb->host) + 2)) {
-		close(source);
-		phb->func(phb->data, -1, B_EV_IO_READ);
-		g_free(phb->host);
-		g_free(phb);
+		phb_close(phb);
 		return;
 	}
@@ -438,17 +392,9 @@
 
 	if (read(source, buf, 2) < 2) {
-		close(source);
-		phb->func(phb->data, -1, B_EV_IO_READ);
-		g_free(phb->host);
-		g_free(phb);
-		return FALSE;
+		return phb_close(phb);
 	}
 
 	if ((buf[0] != 0x01) || (buf[1] != 0x00)) {
-		close(source);
-		phb->func(phb->data, -1, B_EV_IO_READ);
-		g_free(phb->host);
-		g_free(phb);
-		return FALSE;
+		return phb_close(phb);
 	}
 
@@ -466,17 +412,9 @@
 
 	if (read(source, buf, 2) < 2) {
-		close(source);
-		phb->func(phb->data, -1, B_EV_IO_READ);
-		g_free(phb->host);
-		g_free(phb);
-		return FALSE;
+		return phb_close(phb);
 	}
 
 	if ((buf[0] != 0x05) || (buf[1] == 0xff)) {
-		close(source);
-		phb->func(phb->data, -1, B_EV_IO_READ);
-		g_free(phb->host);
-		g_free(phb);
-		return FALSE;
+		return phb_close(phb);
 	}
 
@@ -489,9 +427,5 @@
 		memcpy(buf + 2 + i + 1, proxypass, j);
 		if (write(source, buf, 3 + i + j) < 3 + i + j) {
-			close(source);
-			phb->func(phb->data, -1, B_EV_IO_READ);
-			g_free(phb->host);
-			g_free(phb);
-			return FALSE;
+			return phb_close(phb);
 		}
 
@@ -517,9 +451,5 @@
 	len = sizeof(error);
 	if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
-		close(source);
-		phb->func(phb->data, -1, B_EV_IO_READ);
-		g_free(phb->host);
-		g_free(phb);
-		return FALSE;
+		return phb_close(phb);
 	}
 	sock_make_blocking(source);
@@ -539,9 +469,5 @@
 
 	if (write(source, buf, i) < i) {
-		close(source);
-		phb->func(phb->data, -1, B_EV_IO_READ);
-		g_free(phb->host);
-		g_free(phb);
-		return FALSE;
+		return phb_close(phb);
 	}
 
Index: lib/ssl_gnutls.c
===================================================================
--- lib/ssl_gnutls.c	(revision 71f87bae7a18551af0e8692e1b588dea32c22483)
+++ lib/ssl_gnutls.c	(revision 1522faf1c44fa65a3bd3e544561974f8b2b18b97)
@@ -124,4 +124,5 @@
 
 	if (conn->fd < 0) {
+		g_free(conn->hostname);
 		g_free(conn);
 		return NULL;
@@ -314,4 +315,5 @@
 	if (source == -1) {
 		conn->func(conn->data, 0, NULL, cond);
+		g_free(conn->hostname);
 		g_free(conn);
 		return FALSE;
@@ -355,8 +357,5 @@
 			conn->func(conn->data, 0, NULL, cond);
 
-			gnutls_deinit(conn->session);
-			closesocket(conn->fd);
-
-			g_free(conn);
+			ssl_disconnect(conn);
 		}
 	} else {
@@ -364,8 +363,5 @@
 			conn->func(conn->data, stver, NULL, cond);
 
-			gnutls_deinit(conn->session);
-			closesocket(conn->fd);
-
-			g_free(conn);
+			ssl_disconnect(conn);
 		} else {
 			/* For now we can't handle non-blocking perfectly everywhere... */
Index: otr.c
===================================================================
--- otr.c	(revision 71f87bae7a18551af0e8692e1b588dea32c22483)
+++ otr.c	(revision 1522faf1c44fa65a3bd3e544561974f8b2b18b97)
@@ -287,4 +287,5 @@
 void otr_irc_free(irc_t *irc)
 {
+	set_t *s;
 	otr_t *otr = irc->otr;
 
@@ -292,4 +293,8 @@
 	b_event_remove(otr->timer);
 	otrl_userstate_free(otr->us);
+
+	s = set_find(&irc->b->set, "otr_policy");
+	g_slist_free(s->eval_data);
+
 	if (otr->keygen) {
 		kill(otr->keygen, SIGTERM);
@@ -434,4 +439,8 @@
 	                                    ic->acc->user, ic->acc->prpl->name, iu->bu->handle, msg, &newmsg,
 	                                    &tlvs, NULL, NULL, NULL);
+
+	if (tlvs) {
+		otrl_tlv_free(tlvs);
+	}
 
 	if (ignore_msg) {
@@ -472,5 +481,5 @@
 		/* libotr wants us to replace our message */
 		/* NB: caller will free old msg */
-		msg = g_strdup(otrmsg);
+		msg = st ? NULL : g_strdup(otrmsg);
 		otrl_message_free(otrmsg);
 	}
@@ -1325,4 +1334,6 @@
 
 	log_message(LOGLVL_INFO, "otr: %s", msg);
+
+	g_free(msg);
 }
 
@@ -2075,4 +2086,2 @@
 	}
 }
-
-/* vim: set noet ts=4 sw=4: */
Index: protocols/jabber/jabber_util.c
===================================================================
--- protocols/jabber/jabber_util.c	(revision 71f87bae7a18551af0e8692e1b588dea32c22483)
+++ protocols/jabber/jabber_util.c	(revision 1522faf1c44fa65a3bd3e544561974f8b2b18b97)
@@ -566,4 +566,5 @@
 
 	if ((s = strchr(jid, '=')) == NULL) {
+		g_free(jid);
 		return NULL;
 	}
Index: protocols/msn/msn_util.c
===================================================================
--- protocols/msn/msn_util.c	(revision 71f87bae7a18551af0e8692e1b588dea32c22483)
+++ protocols/msn/msn_util.c	(revision 1522faf1c44fa65a3bd3e544561974f8b2b18b97)
@@ -174,11 +174,7 @@
 };
 
-static void msn_buddy_ask_yes(void *data)
+static void msn_buddy_ask_free(void *data)
 {
 	struct msn_buddy_ask_data *bla = data;
-
-	msn_buddy_list_add(bla->ic, MSN_BUDDY_AL, bla->handle, bla->realname, NULL);
-
-	imcb_ask_add(bla->ic, bla->handle, NULL);
 
 	g_free(bla->handle);
@@ -187,4 +183,15 @@
 }
 
+static void msn_buddy_ask_yes(void *data)
+{
+	struct msn_buddy_ask_data *bla = data;
+
+	msn_buddy_list_add(bla->ic, MSN_BUDDY_AL, bla->handle, bla->realname, NULL);
+
+	imcb_ask_add(bla->ic, bla->handle, NULL);
+
+	msn_buddy_ask_free(bla);
+}
+
 static void msn_buddy_ask_no(void *data)
 {
@@ -193,7 +200,5 @@
 	msn_buddy_list_add(bla->ic, MSN_BUDDY_BL, bla->handle, bla->realname, NULL);
 
-	g_free(bla->handle);
-	g_free(bla->realname);
-	g_free(bla);
+	msn_buddy_ask_free(bla);
 }
 
@@ -216,5 +221,6 @@
 	           "The user %s (%s) wants to add you to his/her buddy list.",
 	           bu->handle, bu->fullname);
-	imcb_ask(bu->ic, buf, bla, msn_buddy_ask_yes, msn_buddy_ask_no);
+
+	imcb_ask_with_free(bu->ic, buf, bla, msn_buddy_ask_yes, msn_buddy_ask_no, msn_buddy_ask_free);
 }
 
Index: protocols/nogaim.c
===================================================================
--- protocols/nogaim.c	(revision 71f87bae7a18551af0e8692e1b588dea32c22483)
+++ protocols/nogaim.c	(revision 1522faf1c44fa65a3bd3e544561974f8b2b18b97)
@@ -498,9 +498,7 @@
 };
 
-static void imcb_ask_auth_cb_no(void *data)
+static void imcb_ask_cb_free(void *data)
 {
 	struct imcb_ask_cb_data *cbd = data;
-
-	cbd->ic->acc->prpl->auth_deny(cbd->ic, cbd->handle);
 
 	g_free(cbd->handle);
@@ -508,4 +506,13 @@
 }
 
+static void imcb_ask_auth_cb_no(void *data)
+{
+	struct imcb_ask_cb_data *cbd = data;
+
+	cbd->ic->acc->prpl->auth_deny(cbd->ic, cbd->handle);
+
+	imcb_ask_cb_free(cbd);
+}
+
 static void imcb_ask_auth_cb_yes(void *data)
 {
@@ -514,6 +521,5 @@
 	cbd->ic->acc->prpl->auth_allow(cbd->ic, cbd->handle);
 
-	g_free(cbd->handle);
-	g_free(cbd);
+	imcb_ask_cb_free(cbd);
 }
 
@@ -535,12 +541,7 @@
 	data->handle = g_strdup(handle);
 	query_add((irc_t *) ic->bee->ui_data, ic, s,
-	          imcb_ask_auth_cb_yes, imcb_ask_auth_cb_no, g_free, data);
-}
-
-
-static void imcb_ask_add_cb_no(void *data)
-{
-	g_free(((struct imcb_ask_cb_data*) data)->handle);
-	g_free(data);
+	          imcb_ask_auth_cb_yes, imcb_ask_auth_cb_no, imcb_ask_cb_free, data);
+
+	g_free(s);
 }
 
@@ -551,10 +552,10 @@
 	cbd->ic->acc->prpl->add_buddy(cbd->ic, cbd->handle, NULL);
 
-	imcb_ask_add_cb_no(data);
+	imcb_ask_cb_free(data);
 }
 
 void imcb_ask_add(struct im_connection *ic, const char *handle, const char *realname)
 {
-	struct imcb_ask_cb_data *data = g_new0(struct imcb_ask_cb_data, 1);
+	struct imcb_ask_cb_data *data;
 	char *s;
 
@@ -564,4 +565,6 @@
 	}
 
+	data = g_new0(struct imcb_ask_cb_data, 1);
+
 	s = g_strdup_printf("The user %s is not in your buddy list yet. Do you want to add him/her now?", handle);
 
@@ -569,5 +572,7 @@
 	data->handle = g_strdup(handle);
 	query_add((irc_t *) ic->bee->ui_data, ic, s,
-	          imcb_ask_add_cb_yes, imcb_ask_add_cb_no, g_free, data);
+	          imcb_ask_add_cb_yes, imcb_ask_cb_free, imcb_ask_cb_free, data);
+
+	g_free(s);
 }
 
Index: storage_xml.c
===================================================================
--- storage_xml.c	(revision 71f87bae7a18551af0e8692e1b588dea32c22483)
+++ storage_xml.c	(revision 1522faf1c44fa65a3bd3e544561974f8b2b18b97)
@@ -128,4 +128,6 @@
 		}
 	} else {
+		g_free(pass_cr);
+		g_free(password);
 		return XT_ABORT;
 	}
