27
27
/* libotr headers */
28
28
#include "context.h"
30
/* Strings describing the connection states */
31
const char *otrl_context_statestr[] =
32
{ "Not private", "Setting up", "Private" };
34
30
/* Create a new connection context. */
35
31
static ConnContext * new_context(const char * user, const char * accountname,
36
32
const char * protocol)
41
37
context->username = strdup(user);
42
38
context->accountname = strdup(accountname);
43
39
context->protocol = strdup(protocol);
44
context->state = CONN_UNCONNECTED;
40
context->fragment = NULL;
41
context->fragment_len = 0;
42
context->fragment_n = 0;
43
context->fragment_k = 0;
44
context->msgstate = OTRL_MSGSTATE_PLAINTEXT;
45
otrl_auth_new(&(context->auth));
45
46
context->fingerprint_root.fingerprint = NULL;
46
47
context->fingerprint_root.context = context;
47
48
context->fingerprint_root.next = NULL;
61
62
otrl_dh_session_blank(&(context->sesskeys[0][1]));
62
63
otrl_dh_session_blank(&(context->sesskeys[1][0]));
63
64
otrl_dh_session_blank(&(context->sesskeys[1][1]));
65
memset(context->sessionid, 0, 20);
66
context->sessionid_len = 0;
67
context->protocol_version = 0;
64
68
context->numsavedkeys = 0;
69
context->preshared_secret = NULL;
70
context->preshared_secret_len = 0;
65
71
context->saved_mac_keys = NULL;
66
72
context->generation = 0;
67
73
context->lastsent = 0;
154
/* Force a context into the CONN_SETUP state (so that it only has local
156
void otrl_context_force_setup(ConnContext *context)
158
context->state = CONN_SETUP;
161
/* Set the trust level for a given fingerprint */
162
void otrl_context_set_trust(Fingerprint *fprint, const char *trust)
164
if (fprint == NULL) return;
167
fprint->trust = trust ? strdup(trust) : NULL;
170
/* Set the preshared secret for a given fingerprint. Note that this
171
* currently only stores the secret in the ConnContext structure, but
172
* doesn't yet do anything with it. */
173
void otrl_context_set_preshared_secret(ConnContext *context,
174
const unsigned char *secret, size_t secret_len)
176
free(context->preshared_secret);
177
context->preshared_secret = NULL;
178
context->preshared_secret_len = 0;
181
context->preshared_secret = malloc(secret_len);
182
if (context->preshared_secret) {
183
memmove(context->preshared_secret, secret, secret_len);
184
context->preshared_secret_len = secret_len;
189
/* Force a context into the OTRL_MSGSTATE_FINISHED state. */
190
void otrl_context_force_finished(ConnContext *context)
192
context->msgstate = OTRL_MSGSTATE_FINISHED;
193
otrl_auth_clear(&(context->auth));
194
free(context->fragment);
195
context->fragment = NULL;
196
context->fragment_len = 0;
197
context->fragment_n = 0;
198
context->fragment_k = 0;
159
199
context->active_fingerprint = NULL;
160
200
context->their_keyid = 0;
161
201
gcry_mpi_release(context->their_y);
162
202
context->their_y = NULL;
163
203
gcry_mpi_release(context->their_old_y);
164
204
context->their_old_y = NULL;
205
context->our_keyid = 0;
206
otrl_dh_keypair_free(&(context->our_dh_key));
207
otrl_dh_keypair_free(&(context->our_old_dh_key));
165
208
otrl_dh_session_free(&(context->sesskeys[0][0]));
166
209
otrl_dh_session_free(&(context->sesskeys[0][1]));
167
210
otrl_dh_session_free(&(context->sesskeys[1][0]));
168
211
otrl_dh_session_free(&(context->sesskeys[1][1]));
212
memset(context->sessionid, 0, 20);
213
context->sessionid_len = 0;
214
free(context->preshared_secret);
215
context->preshared_secret = NULL;
216
context->preshared_secret_len = 0;
217
context->protocol_version = 0;
169
218
context->numsavedkeys = 0;
170
219
free(context->saved_mac_keys);
171
220
context->saved_mac_keys = NULL;
174
223
context->may_retransmit = 0;
177
/* Force a context into the CONN_UNCONNECTED state. */
178
void otrl_context_force_disconnect(ConnContext *context)
226
/* Force a context into the OTRL_MSGSTATE_PLAINTEXT state. */
227
void otrl_context_force_plaintext(ConnContext *context)
180
/* First clean up everything we'd need to do for the SETUP state */
181
otrl_context_force_setup(context);
229
/* First clean up everything we'd need to do for the FINISHED state */
230
otrl_context_force_finished(context);
183
/* Now clean up our pubkeys, too */
184
context->state = CONN_UNCONNECTED;
185
context->our_keyid = 0;
186
otrl_dh_keypair_free(&(context->our_dh_key));
187
otrl_dh_keypair_free(&(context->our_old_dh_key));
232
/* And just set the state properly */
233
context->msgstate = OTRL_MSGSTATE_PLAINTEXT;
190
236
/* Forget a fingerprint (so long as it's not the active one. If it's a
191
237
* fingerprint_root, forget the whole context (as long as
192
* and_maybe_context is set, and it's UNCONNECTED). Also, if it's not
238
* and_maybe_context is set, and it's PLAINTEXT). Also, if it's not
193
239
* the fingerprint_root, but it's the only fingerprint, and we're
194
* UNCONNECTED, forget the whole context if and_maybe_context is set. */
240
* PLAINTEXT, forget the whole context if and_maybe_context is set. */
195
241
void otrl_context_forget_fingerprint(Fingerprint *fprint,
196
242
int and_maybe_context)
198
244
ConnContext *context = fprint->context;
199
245
if (fprint == &(context->fingerprint_root)) {
200
if (context->state == CONN_UNCONNECTED && and_maybe_context) {
246
if (context->msgstate == OTRL_MSGSTATE_PLAINTEXT &&
201
248
otrl_context_forget(context);
204
if (context->state != CONN_CONNECTED ||
251
if (context->msgstate != OTRL_MSGSTATE_PLAINTEXT ||
205
252
context->active_fingerprint != fprint) {
206
253
free(fprint->fingerprint);
207
255
*(fprint->tous) = fprint->next;
208
256
if (fprint->next) {
209
257
fprint->next->tous = fprint->tous;
212
if (context->state == CONN_UNCONNECTED &&
260
if (context->msgstate == OTRL_MSGSTATE_PLAINTEXT &&
213
261
context->fingerprint_root.next == NULL &&
214
262
and_maybe_context) {
215
263
/* We just deleted the only fingerprint. Forget the
223
/* Forget a whole context, so long as it's UNCONNECTED. */
271
/* Forget a whole context, so long as it's PLAINTEXT. */
224
272
void otrl_context_forget(ConnContext *context)
226
if (context->state != CONN_UNCONNECTED) return;
274
if (context->msgstate != OTRL_MSGSTATE_PLAINTEXT) return;
228
/* Just to be safe, force a disconnect. This also frees any
276
/* Just to be safe, force to plaintext. This also frees any
229
277
* extraneous data lying around. */
230
otrl_context_force_disconnect(context);
278
otrl_context_force_plaintext(context);
232
280
/* First free all the Fingerprints */
233
281
while(context->fingerprint_root.next) {
259
/* Forget all the contexts in a given OtrlUserState, forcing them to
307
/* Forget all the contexts in a given OtrlUserState. */
261
308
void otrl_context_forget_all(OtrlUserState us)
263
310
while (us->context_root) {
264
otrl_context_force_disconnect(us->context_root);
311
otrl_context_force_plaintext(us->context_root);
265
312
otrl_context_forget(us->context_root);