diff options
author | Jay Threeth | 2011-04-04 11:48:26 -0700 |
---|---|---|
committer | Jay Threeth | 2011-04-04 11:48:26 -0700 |
commit | 3c9cc506f741b980565ff5b3b001cd8b6ee36b12 (patch) | |
tree | cb862c57b3d5f74177cde3bd962a53fc377166f6 /linden/indra/libotr/libotr-3.2.0/src/context.c | |
parent | build fixes, might build on linux now (diff) | |
download | meta-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-x | linden/indra/libotr/libotr-3.2.0/src/context.c | 321 |
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. */ | ||
32 | static 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. */ | ||
96 | ConnContext * 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. */ | ||
139 | Fingerprint *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 */ | ||
170 | void 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. */ | ||
181 | void 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. */ | ||
198 | void 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. */ | ||
232 | void 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. */ | ||
246 | void 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. */ | ||
277 | void 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. */ | ||
315 | void 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 | } | ||