aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/libotr/libotr-3.2.0/src/context.c
diff options
context:
space:
mode:
authorJay Threeth2011-04-04 11:48:26 -0700
committerJay Threeth2011-04-04 11:48:26 -0700
commit3c9cc506f741b980565ff5b3b001cd8b6ee36b12 (patch)
treecb862c57b3d5f74177cde3bd962a53fc377166f6 /linden/indra/libotr/libotr-3.2.0/src/context.c
parentbuild fixes, might build on linux now (diff)
downloadmeta-impy-3c9cc506f741b980565ff5b3b001cd8b6ee36b12.zip
meta-impy-3c9cc506f741b980565ff5b3b001cd8b6ee36b12.tar.gz
meta-impy-3c9cc506f741b980565ff5b3b001cd8b6ee36b12.tar.bz2
meta-impy-3c9cc506f741b980565ff5b3b001cd8b6ee36b12.tar.xz
add source to libraries, and cruft for building under windows
Diffstat (limited to 'linden/indra/libotr/libotr-3.2.0/src/context.c')
-rwxr-xr-xlinden/indra/libotr/libotr-3.2.0/src/context.c321
1 files changed, 321 insertions, 0 deletions
diff --git a/linden/indra/libotr/libotr-3.2.0/src/context.c b/linden/indra/libotr/libotr-3.2.0/src/context.c
new file mode 100755
index 0000000..4b2369a
--- /dev/null
+++ b/linden/indra/libotr/libotr-3.2.0/src/context.c
@@ -0,0 +1,321 @@
1/*
2 * Off-the-Record Messaging library
3 * Copyright (C) 2004-2008 Ian Goldberg, Chris Alexander, Nikita Borisov
4 * <otr@cypherpunks.ca>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of version 2.1 of the GNU Lesser General
8 * Public License as published by the Free Software Foundation.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20/* system headers */
21#include <stdlib.h>
22#include <assert.h>
23
24/* libgcrypt headers */
25#include <gcrypt.h>
26
27/* libotr headers */
28#include "context.h"
29#include "proto.h"
30
31/* Create a new connection context. */
32static ConnContext * new_context(const char * user, const char * accountname,
33 const char * protocol)
34{
35 ConnContext * context;
36 OtrlSMState *smstate;
37 context = malloc(sizeof(*context));
38 assert(context != NULL);
39 context->username = strdup(user);
40 context->accountname = strdup(accountname);
41 context->protocol = strdup(protocol);
42 context->fragments = NULL;
43 context->fragment_len = 0;
44 context->fragment_n = 0;
45 context->fragment_k = 0;
46 context->msgstate = OTRL_MSGSTATE_PLAINTEXT;
47 otrl_auth_new(&(context->auth));
48
49 smstate = malloc(sizeof(OtrlSMState));
50 assert(smstate != NULL);
51 otrl_sm_state_new(smstate);
52 context->smstate = smstate;
53
54 context->fingerprint_root.fingerprint = NULL;
55 context->fingerprint_root.context = context;
56 context->fingerprint_root.next = NULL;
57 context->fingerprint_root.tous = NULL;
58 context->active_fingerprint = NULL;
59 context->their_keyid = 0;
60 context->their_y = NULL;
61 context->their_old_y = NULL;
62 context->our_keyid = 0;
63 context->our_dh_key.groupid = 0;
64 context->our_dh_key.priv = NULL;
65 context->our_dh_key.pub = NULL;
66 context->our_old_dh_key.groupid = 0;
67 context->our_old_dh_key.priv = NULL;
68 context->our_old_dh_key.pub = NULL;
69 otrl_dh_session_blank(&(context->sesskeys[0][0]));
70 otrl_dh_session_blank(&(context->sesskeys[0][1]));
71 otrl_dh_session_blank(&(context->sesskeys[1][0]));
72 otrl_dh_session_blank(&(context->sesskeys[1][1]));
73 memset(context->sessionid, 0, 20);
74 context->sessionid_len = 0;
75 context->protocol_version = 0;
76 context->numsavedkeys = 0;
77 context->preshared_secret = NULL;
78 context->preshared_secret_len = 0;
79 context->saved_mac_keys = NULL;
80 context->generation = 0;
81 context->lastsent = 0;
82 context->lastmessage = NULL;
83 context->may_retransmit = 0;
84 context->otr_offer = OFFER_NOT;
85 context->app_data = NULL;
86 context->app_data_free = NULL;
87 context->next = NULL;
88 return context;
89}
90
91/* Look up a connection context by name/account/protocol from the given
92 * OtrlUserState. If add_if_missing is true, allocate and return a new
93 * context if one does not currently exist. In that event, call
94 * add_app_data(data, context) so that app_data and app_data_free can be
95 * filled in by the application, and set *addedp to 1. */
96ConnContext * otrl_context_find(OtrlUserState us, const char *user,
97 const char *accountname, const char *protocol, int add_if_missing,
98 int *addedp,
99 void (*add_app_data)(void *data, ConnContext *context), void *data)
100{
101 ConnContext ** curp;
102 int usercmp = 1, acctcmp = 1, protocmp = 1;
103 if (addedp) *addedp = 0;
104 if (!user || !accountname || !protocol) return NULL;
105 for (curp = &(us->context_root); *curp; curp = &((*curp)->next)) {
106 if ((usercmp = strcmp((*curp)->username, user)) > 0 ||
107 (usercmp == 0 &&
108 (acctcmp = strcmp((*curp)->accountname, accountname)) > 0) ||
109 (usercmp == 0 && acctcmp == 0 &&
110 (protocmp = strcmp((*curp)->protocol, protocol)) >= 0))
111 /* We're at the right place in the list. We've either found
112 * it, or gone too far. */
113 break;
114 }
115 if (usercmp == 0 && acctcmp == 0 && protocmp == 0) {
116 /* Found it! */
117 return *curp;
118 }
119 if (add_if_missing) {
120 ConnContext *newctx;
121 if (addedp) *addedp = 1;
122 newctx = new_context(user, accountname, protocol);
123 newctx->next = *curp;
124 if (*curp) {
125 (*curp)->tous = &(newctx->next);
126 }
127 *curp = newctx;
128 newctx->tous = curp;
129 if (add_app_data) {
130 add_app_data(data, *curp);
131 }
132 return *curp;
133 }
134 return NULL;
135}
136
137/* Find a fingerprint in a given context, perhaps adding it if not
138 * present. */
139Fingerprint *otrl_context_find_fingerprint(ConnContext *context,
140 unsigned char fingerprint[20], int add_if_missing, int *addedp)
141{
142 Fingerprint *f = context->fingerprint_root.next;
143 if (addedp) *addedp = 0;
144 while(f) {
145 if (!memcmp(f->fingerprint, fingerprint, 20)) return f;
146 f = f->next;
147 }
148 /* Didn't find it. */
149 if (add_if_missing) {
150 if (addedp) *addedp = 1;
151 f = malloc(sizeof(*f));
152 assert(f != NULL);
153 f->fingerprint = malloc(20);
154 assert(f->fingerprint != NULL);
155 memmove(f->fingerprint, fingerprint, 20);
156 f->context = context;
157 f->trust = NULL;
158 f->next = context->fingerprint_root.next;
159 if (f->next) {
160 f->next->tous = &(f->next);
161 }
162 context->fingerprint_root.next = f;
163 f->tous = &(context->fingerprint_root.next);
164 return f;
165 }
166 return NULL;
167}
168
169/* Set the trust level for a given fingerprint */
170void otrl_context_set_trust(Fingerprint *fprint, const char *trust)
171{
172 if (fprint == NULL) return;
173
174 free(fprint->trust);
175 fprint->trust = trust ? strdup(trust) : NULL;
176}
177
178/* Set the preshared secret for a given fingerprint. Note that this
179 * currently only stores the secret in the ConnContext structure, but
180 * doesn't yet do anything with it. */
181void otrl_context_set_preshared_secret(ConnContext *context,
182 const unsigned char *secret, size_t secret_len)
183{
184 free(context->preshared_secret);
185 context->preshared_secret = NULL;
186 context->preshared_secret_len = 0;
187
188 if (secret_len) {
189 context->preshared_secret = malloc(secret_len);
190 if (context->preshared_secret) {
191 memmove(context->preshared_secret, secret, secret_len);
192 context->preshared_secret_len = secret_len;
193 }
194 }
195}
196
197/* Force a context into the OTRL_MSGSTATE_FINISHED state. */
198void otrl_context_force_finished(ConnContext *context)
199{
200 context->msgstate = OTRL_MSGSTATE_FINISHED;
201 otrl_auth_clear(&(context->auth));
202 otrl_free_fragments(context);
203 context->active_fingerprint = NULL;
204 context->their_keyid = 0;
205 gcry_mpi_release(context->their_y);
206 context->their_y = NULL;
207 gcry_mpi_release(context->their_old_y);
208 context->their_old_y = NULL;
209 context->our_keyid = 0;
210 otrl_dh_keypair_free(&(context->our_dh_key));
211 otrl_dh_keypair_free(&(context->our_old_dh_key));
212 otrl_dh_session_free(&(context->sesskeys[0][0]));
213 otrl_dh_session_free(&(context->sesskeys[0][1]));
214 otrl_dh_session_free(&(context->sesskeys[1][0]));
215 otrl_dh_session_free(&(context->sesskeys[1][1]));
216 memset(context->sessionid, 0, 20);
217 context->sessionid_len = 0;
218 free(context->preshared_secret);
219 context->preshared_secret = NULL;
220 context->preshared_secret_len = 0;
221 context->protocol_version = 0;
222 context->numsavedkeys = 0;
223 free(context->saved_mac_keys);
224 context->saved_mac_keys = NULL;
225 gcry_free(context->lastmessage);
226 context->lastmessage = NULL;
227 context->may_retransmit = 0;
228 otrl_sm_state_free(context->smstate);
229}
230
231/* Force a context into the OTRL_MSGSTATE_PLAINTEXT state. */
232void otrl_context_force_plaintext(ConnContext *context)
233{
234 /* First clean up everything we'd need to do for the FINISHED state */
235 otrl_context_force_finished(context);
236
237 /* And just set the state properly */
238 context->msgstate = OTRL_MSGSTATE_PLAINTEXT;
239}
240
241/* Forget a fingerprint (so long as it's not the active one. If it's a
242 * fingerprint_root, forget the whole context (as long as
243 * and_maybe_context is set, and it's PLAINTEXT). Also, if it's not
244 * the fingerprint_root, but it's the only fingerprint, and we're
245 * PLAINTEXT, forget the whole context if and_maybe_context is set. */
246void otrl_context_forget_fingerprint(Fingerprint *fprint,
247 int and_maybe_context)
248{
249 ConnContext *context = fprint->context;
250 if (fprint == &(context->fingerprint_root)) {
251 if (context->msgstate == OTRL_MSGSTATE_PLAINTEXT &&
252 and_maybe_context) {
253 otrl_context_forget(context);
254 }
255 } else {
256 if (context->msgstate != OTRL_MSGSTATE_PLAINTEXT ||
257 context->active_fingerprint != fprint) {
258 free(fprint->fingerprint);
259 free(fprint->trust);
260 *(fprint->tous) = fprint->next;
261 if (fprint->next) {
262 fprint->next->tous = fprint->tous;
263 }
264 free(fprint);
265 if (context->msgstate == OTRL_MSGSTATE_PLAINTEXT &&
266 context->fingerprint_root.next == NULL &&
267 and_maybe_context) {
268 /* We just deleted the only fingerprint. Forget the
269 * whole thing. */
270 otrl_context_forget(context);
271 }
272 }
273 }
274}
275
276/* Forget a whole context, so long as it's PLAINTEXT. */
277void otrl_context_forget(ConnContext *context)
278{
279 if (context->msgstate != OTRL_MSGSTATE_PLAINTEXT) return;
280
281 /* Just to be safe, force to plaintext. This also frees any
282 * extraneous data lying around. */
283 otrl_context_force_plaintext(context);
284
285 /* First free all the Fingerprints */
286 while(context->fingerprint_root.next) {
287 otrl_context_forget_fingerprint(context->fingerprint_root.next, 0);
288 }
289 /* Now free all the dynamic info here */
290 free(context->username);
291 free(context->accountname);
292 free(context->protocol);
293 free(context->smstate);
294 context->username = NULL;
295 context->accountname = NULL;
296 context->protocol = NULL;
297 context->smstate = NULL;
298
299 /* Free the application data, if it exists */
300 if (context->app_data && context->app_data_free) {
301 (context->app_data_free)(context->app_data);
302 context->app_data = NULL;
303 }
304
305 /* Fix the list linkages */
306 *(context->tous) = context->next;
307 if (context->next) {
308 context->next->tous = context->tous;
309 }
310
311 free(context);
312}
313
314/* Forget all the contexts in a given OtrlUserState. */
315void otrl_context_forget_all(OtrlUserState us)
316{
317 while (us->context_root) {
318 otrl_context_force_plaintext(us->context_root);
319 otrl_context_forget(us->context_root);
320 }
321}