about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorMichael Vetter <jubalh@iodoru.org>2019-07-04 18:01:59 +0200
committerGitHub <noreply@github.com>2019-07-04 18:01:59 +0200
commit63552720916dbe82cdb001eee74b7c08723b823a (patch)
treeaf5eb96fd3ff885aec591e61fff2b88ae3f91370 /src
parent593aac8a8469f8cc5b7b95d5ad68a38023691622 (diff)
parent9aad2aa4878fffec098e8b2ecf382be565bd44a7 (diff)
downloadprofani-tty-63552720916dbe82cdb001eee74b7c08723b823a.tar.gz
Merge pull request #1146 from profanity-im/fix/omemoleaks-autocompl
Fix several OMEMO related leaks
Diffstat (limited to 'src')
-rw-r--r--src/omemo/omemo.c12
-rw-r--r--src/omemo/omemo.h1
-rw-r--r--src/profanity.c3
-rw-r--r--src/xmpp/iq.c16
-rw-r--r--src/xmpp/omemo.c67
5 files changed, 72 insertions, 27 deletions
diff --git a/src/omemo/omemo.c b/src/omemo/omemo.c
index 96d2d65a..02107432 100644
--- a/src/omemo/omemo.c
+++ b/src/omemo/omemo.c
@@ -128,6 +128,15 @@ omemo_init(void)
 }
 
 void
+omemo_close(void)
+{
+    if (omemo_ctx.fingerprint_ac) {
+        autocomplete_free(omemo_ctx.fingerprint_ac);
+        omemo_ctx.fingerprint_ac = NULL;
+    }
+}
+
+void
 omemo_on_connect(ProfAccount *account)
 {
     GError *error = NULL;
@@ -217,8 +226,6 @@ omemo_on_connect(ProfAccount *account)
     omemo_ctx.device_list_handler = g_hash_table_new_full(g_str_hash, g_str_equal, free, NULL);
     omemo_ctx.known_devices = g_hash_table_new_full(g_str_hash, g_str_equal, free, (GDestroyNotify)_g_hash_table_free);
 
-    omemo_ctx.fingerprint_ac = autocomplete_new();
-
     char *omemodir = files_get_data_path(DIR_OMEMO);
     GString *basedir = g_string_new(omemodir);
     free(omemodir);
@@ -298,6 +305,7 @@ omemo_on_disconnect(void)
 
     _g_hash_table_free(omemo_ctx.signed_pre_key_store);
     _g_hash_table_free(omemo_ctx.pre_key_store);
+    _g_hash_table_free(omemo_ctx.device_list_handler);
 
     g_string_free(omemo_ctx.identity_filename, TRUE);
     g_key_file_free(omemo_ctx.identity_keyfile);
diff --git a/src/omemo/omemo.h b/src/omemo/omemo.h
index ae25b5ba..abe21be5 100644
--- a/src/omemo/omemo.h
+++ b/src/omemo/omemo.h
@@ -56,6 +56,7 @@ typedef struct omemo_key {
 } omemo_key_t;
 
 void omemo_init(void);
+void omemo_close(void);
 void omemo_on_connect(ProfAccount *account);
 void omemo_on_disconnect(void);
 void omemo_generate_crypto_materials(ProfAccount *account);
diff --git a/src/profanity.c b/src/profanity.c
index a9824729..324aa36d 100644
--- a/src/profanity.c
+++ b/src/profanity.c
@@ -242,6 +242,9 @@ _shutdown(void)
 #ifdef HAVE_LIBGPGME
     p_gpg_close();
 #endif
+#ifdef HAVE_OMEMO
+    omemo_close();
+#endif
     chat_log_close();
     theme_close();
     accounts_close();
diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c
index 91acc212..e31f3269 100644
--- a/src/xmpp/iq.c
+++ b/src/xmpp/iq.c
@@ -134,6 +134,7 @@ static int _command_exec_response_handler(xmpp_stanza_t *const stanza, void *con
 
 static void _iq_free_room_data(ProfRoomInfoData *roominfo);
 static void _iq_free_affiliation_set(ProfPrivilegeSet *affiliation_set);
+static void _iq_id_handler_free(ProfIqHandler *handler);
 
 // scheduled
 static int _autoping_timed_send(xmpp_conn_t *const conn, void *const userdata);
@@ -247,7 +248,7 @@ iq_handlers_init(void)
         g_list_free(keys);
         g_hash_table_destroy(id_handlers);
     }
-    id_handlers = g_hash_table_new_full(g_str_hash, g_str_equal, free, NULL);
+    id_handlers = g_hash_table_new_full(g_str_hash, g_str_equal, free, (GDestroyNotify)_iq_id_handler_free);
     rooms_cache = g_hash_table_new_full(g_str_hash, g_str_equal, free, (GDestroyNotify)xmpp_stanza_release);
 }
 
@@ -259,6 +260,19 @@ iq_handlers_clear()
     }
 }
 
+static void
+_iq_id_handler_free(ProfIqHandler *handler)
+{
+    if (handler == NULL) {
+        return;
+    }
+    if (handler->free_func && handler->userdata) {
+        handler->free_func(handler->userdata);
+    }
+    free(handler);
+    handler = NULL;
+}
+
 void
 iq_id_handler_add(const char *const id, ProfIqCallback func, ProfIqFreeCallback free_func, void *userdata)
 {
diff --git a/src/xmpp/omemo.c b/src/xmpp/omemo.c
index cfa3f84c..e44cc00e 100644
--- a/src/xmpp/omemo.c
+++ b/src/xmpp/omemo.c
@@ -111,8 +111,13 @@ omemo_bundle_request(const char * const jid, uint32_t device_id, ProfIqCallback
 int
 omemo_start_device_session_handle_bundle(xmpp_stanza_t *const stanza, void *const userdata)
 {
+    GList *prekeys_list = NULL;
+    unsigned char *signed_prekey_raw = NULL;
+    unsigned char *signed_prekey_signature_raw = NULL;
     char *from = NULL;
+
     const char *from_attr = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
+
     if (!from_attr) {
         Jid *jid = jid_create(connection_get_fulljid());
         from = strdup(jid->barejid);
@@ -122,55 +127,59 @@ omemo_start_device_session_handle_bundle(xmpp_stanza_t *const stanza, void *cons
     }
 
     if (g_strcmp0(from, userdata) != 0) {
-        return 1;
+        goto out;
     }
 
     xmpp_stanza_t *pubsub = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_PUBSUB);
     if (!pubsub) {
-        return 1;
+        goto out;
     }
 
     xmpp_stanza_t *items = xmpp_stanza_get_child_by_name(pubsub, "items");
     if (!items) {
-        return 1;
+        goto out;
     }
     const char *node = xmpp_stanza_get_attribute(items, "node");
     char *device_id_str = strstr(node, ":");
     if (!device_id_str) {
-        return 1;
+        goto out;
     }
 
     uint32_t device_id = strtoul(++device_id_str, NULL, 10);
 
     xmpp_stanza_t *item = xmpp_stanza_get_child_by_name(items, "item");
     if (!item) {
-        return 1;
+        goto out;
     }
 
     xmpp_stanza_t *bundle = xmpp_stanza_get_child_by_ns(item, STANZA_NS_OMEMO);
     if (!bundle) {
-        return 1;
+        goto out;
     }
 
     xmpp_stanza_t *prekeys = xmpp_stanza_get_child_by_name(bundle, "prekeys");
     if (!prekeys) {
-        return 1;
+        goto out;
     }
 
-    GList *prekeys_list = NULL;
     xmpp_stanza_t *prekey;
     for (prekey = xmpp_stanza_get_children(prekeys); prekey != NULL; prekey = xmpp_stanza_get_next(prekey)) {
         omemo_key_t *key = malloc(sizeof(omemo_key_t));
 
         const char *prekey_id_text = xmpp_stanza_get_attribute(prekey, "preKeyId");
         if (!prekey_id_text) {
-            return 1;
+            omemo_key_free(key);
+            goto out;
         }
+
         key->id = strtoul(prekey_id_text, NULL, 10);
         xmpp_stanza_t *prekey_text = xmpp_stanza_get_children(prekey);
+
         if (!prekey_text) {
-            return 1;
+            omemo_key_free(key);
+            goto out;
         }
+
         char *prekey_b64 = xmpp_stanza_get_text(prekey_text);
         key->data = g_base64_decode(prekey_b64, &key->length);
         free(prekey_b64);
@@ -182,42 +191,44 @@ omemo_start_device_session_handle_bundle(xmpp_stanza_t *const stanza, void *cons
 
     xmpp_stanza_t *signed_prekey = xmpp_stanza_get_child_by_name(bundle, "signedPreKeyPublic");
     if (!signed_prekey) {
-        return 1;
+        goto out;
     }
     const char *signed_prekey_id_text = xmpp_stanza_get_attribute(signed_prekey, "signedPreKeyId");
     if (!signed_prekey_id_text) {
-        return 1;
+        goto out;
     }
+
     uint32_t signed_prekey_id = strtoul(signed_prekey_id_text, NULL, 10);
     xmpp_stanza_t *signed_prekey_text = xmpp_stanza_get_children(signed_prekey);
     if (!signed_prekey_text) {
-        return 1;
+        goto out;
     }
+
     size_t signed_prekey_len;
     char *signed_prekey_b64 = xmpp_stanza_get_text(signed_prekey_text);
-    unsigned char *signed_prekey_raw = g_base64_decode(signed_prekey_b64, &signed_prekey_len);
+    signed_prekey_raw = g_base64_decode(signed_prekey_b64, &signed_prekey_len);
     free(signed_prekey_b64);
 
     xmpp_stanza_t *signed_prekey_signature = xmpp_stanza_get_child_by_name(bundle, "signedPreKeySignature");
     if (!signed_prekey_signature) {
-        return 1;
+        goto out;
     }
     xmpp_stanza_t *signed_prekey_signature_text = xmpp_stanza_get_children(signed_prekey_signature);
     if (!signed_prekey_signature_text) {
-        return 1;
+        goto out;
     }
     size_t signed_prekey_signature_len;
     char *signed_prekey_signature_b64 = xmpp_stanza_get_text(signed_prekey_signature_text);
-    unsigned char *signed_prekey_signature_raw = g_base64_decode(signed_prekey_signature_b64, &signed_prekey_signature_len);
+    signed_prekey_signature_raw = g_base64_decode(signed_prekey_signature_b64, &signed_prekey_signature_len);
     free(signed_prekey_signature_b64);
 
     xmpp_stanza_t *identity_key = xmpp_stanza_get_child_by_name(bundle, "identityKey");
     if (!identity_key) {
-        return 1;
+        goto out;
     }
     xmpp_stanza_t *identity_key_text = xmpp_stanza_get_children(identity_key);
     if (!identity_key_text) {
-        return 1;
+        goto out;
     }
     size_t identity_key_len;
     char *identity_key_b64 = xmpp_stanza_get_text(identity_key_text);
@@ -228,11 +239,19 @@ omemo_start_device_session_handle_bundle(xmpp_stanza_t *const stanza, void *cons
         signed_prekey_raw, signed_prekey_len, signed_prekey_signature_raw,
         signed_prekey_signature_len, identity_key_raw, identity_key_len);
 
-    free(from);
-    g_list_free_full(prekeys_list, (GDestroyNotify)omemo_key_free);
-    g_free(signed_prekey_raw);
     g_free(identity_key_raw);
-    g_free(signed_prekey_signature_raw);
+
+out:
+    free(from);
+    if (signed_prekey_raw) {
+        g_free(signed_prekey_raw);
+    }
+    if (signed_prekey_signature_raw) {
+        g_free(signed_prekey_signature_raw);
+    }
+    if (prekeys_list) {
+        g_list_free_full(prekeys_list, (GDestroyNotify)omemo_key_free);
+    }
     return 1;
 }
 
@@ -292,12 +311,12 @@ omemo_receive_message(xmpp_stanza_t *const stanza, gboolean *trusted)
             goto skip;
         }
 
-
         const char *rid_text = xmpp_stanza_get_attribute(key_stanza, "rid");
         key->device_id = strtoul(rid_text, NULL, 10);
         if (!key->device_id) {
             goto skip;
         }
+
         key->data = g_base64_decode(key_text, &key->length);
         free(key_text);
         key->prekey = g_strcmp0(xmpp_stanza_get_attribute(key_stanza, "prekey"), "true") == 0;
0f2b1f7cf9'>672e3e50 ^
65361948 ^
672e3e50 ^














65361948 ^
672e3e50 ^
65361948 ^
672e3e50 ^

65361948 ^
672e3e50 ^

65361948 ^
672e3e50 ^

65361948 ^
672e3e50 ^

65361948 ^
672e3e50 ^














65361948 ^
672e3e50 ^
65361948 ^
672e3e50 ^

65361948 ^

672e3e50 ^

65361948 ^

672e3e50 ^












65361948 ^
672e3e50 ^

65361948 ^
672e3e50 ^

65361948 ^
672e3e50 ^

65361948 ^
672e3e50 ^














1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235