1/*
2 * Off-the-Record Messaging library
3 * Copyright (C) 2004-2012 Ian Goldberg, Rob Smits, Chris Alexander,
4 * Willy Lew, Lisa Du, Nikita Borisov
5 * <otr@cypherpunks.ca>
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of version 2.1 of the GNU Lesser General
9 * Public License as published by the Free Software Foundation.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21#ifndef __MESSAGE_H__
22#define __MESSAGE_H__
23
24#define OTR_ERROR_PREFIX "?OTR Error: "
25
26typedef enum {
27 OTRL_ERRCODE_NONE,
28 OTRL_ERRCODE_ENCRYPTION_ERROR,
29 OTRL_ERRCODE_MSG_NOT_IN_PRIVATE,
30 OTRL_ERRCODE_MSG_UNREADABLE,
31 OTRL_ERRCODE_MSG_MALFORMED,
32} OtrlErrorCode;
33
34/* These define the events used to indicate status of SMP to the UI */
35typedef enum {
36 OTRL_SMPEVENT_NONE,
37 OTRL_SMPEVENT_ERROR,
38 OTRL_SMPEVENT_ABORT,
39 OTRL_SMPEVENT_CHEATED,
40 OTRL_SMPEVENT_ASK_FOR_ANSWER,
41 OTRL_SMPEVENT_ASK_FOR_SECRET,
42 OTRL_SMPEVENT_IN_PROGRESS,
43 OTRL_SMPEVENT_SUCCESS,
44 OTRL_SMPEVENT_FAILURE
45} OtrlSMPEvent;
46
47/* These define the events used to indicate the messages that need
48 * to be sent */
49typedef enum {
50 OTRL_MSGEVENT_NONE,
51 OTRL_MSGEVENT_ENCRYPTION_REQUIRED,
52 OTRL_MSGEVENT_ENCRYPTION_ERROR,
53 OTRL_MSGEVENT_CONNECTION_ENDED,
54 OTRL_MSGEVENT_SETUP_ERROR,
55 OTRL_MSGEVENT_MSG_REFLECTED,
56 OTRL_MSGEVENT_MSG_RESENT,
57 OTRL_MSGEVENT_RCVDMSG_NOT_IN_PRIVATE,
58 OTRL_MSGEVENT_RCVDMSG_UNREADABLE,
59 OTRL_MSGEVENT_RCVDMSG_MALFORMED,
60 OTRL_MSGEVENT_LOG_HEARTBEAT_RCVD,
61 OTRL_MSGEVENT_LOG_HEARTBEAT_SENT,
62 OTRL_MSGEVENT_RCVDMSG_GENERAL_ERR,
63 OTRL_MSGEVENT_RCVDMSG_UNENCRYPTED,
64 OTRL_MSGEVENT_RCVDMSG_UNRECOGNIZED,
65 OTRL_MSGEVENT_RCVDMSG_FOR_OTHER_INSTANCE
66} OtrlMessageEvent;
67
68typedef enum {
69 OTRL_NOTIFY_ERROR,
70 OTRL_NOTIFY_WARNING,
71 OTRL_NOTIFY_INFO
72} OtrlNotifyLevel;
73
74typedef enum {
75 OTRL_CONVERT_SENDING,
76 OTRL_CONVERT_RECEIVING
77} OtrlConvertType;
78
79typedef struct s_OtrlMessageAppOps {
80 /* Return the OTR policy for the given context. */
81 OtrlPolicy (*policy)(void *opdata, ConnContext *context);
82
83 /* Create a private key for the given accountname/protocol if
84 * desired. */
85 void (*create_privkey)(void *opdata, const char *accountname,
86 const char *protocol);
87
88 /* Report whether you think the given user is online. Return 1 if
89 * you think he is, 0 if you think he isn't, -1 if you're not sure.
90 *
91 * If you return 1, messages such as heartbeats or other
92 * notifications may be sent to the user, which could result in "not
93 * logged in" errors if you're wrong. */
94 int (*is_logged_in)(void *opdata, const char *accountname,
95 const char *protocol, const char *recipient);
96
97 /* Send the given IM to the given recipient from the given
98 * accountname/protocol. */
99 void (*inject_message)(void *opdata, const char *accountname,
100 const char *protocol, const char *recipient, const char *message);
101
102 /* When the list of ConnContexts changes (including a change in
103 * state), this is called so the UI can be updated. */
104 void (*update_context_list)(void *opdata);
105
106 /* A new fingerprint for the given user has been received. */
107 void (*new_fingerprint)(void *opdata, OtrlUserState us,
108 const char *accountname, const char *protocol,
109 const char *username, unsigned char fingerprint[20]);
110
111 /* The list of known fingerprints has changed. Write them to disk. */
112 void (*write_fingerprints)(void *opdata);
113
114 /* A ConnContext has entered a secure state. */
115 void (*gone_secure)(void *opdata, ConnContext *context);
116
117 /* A ConnContext has left a secure state. */
118 void (*gone_insecure)(void *opdata, ConnContext *context);
119
120 /* We have completed an authentication, using the D-H keys we
121 * already knew. is_reply indicates whether we initiated the AKE. */
122 void (*still_secure)(void *opdata, ConnContext *context, int is_reply);
123
124 /* Find the maximum message size supported by this protocol. */
125 int (*max_message_size)(void *opdata, ConnContext *context);
126
127 /* Return a newly allocated string containing a human-friendly
128 * representation for the given account */
129 const char *(*account_name)(void *opdata, const char *account,
130 const char *protocol);
131
132 /* Deallocate a string returned by account_name */
133 void (*account_name_free)(void *opdata, const char *account_name);
134
135 /* We received a request from the buddy to use the current "extra"
136 * symmetric key. The key will be passed in symkey, of length
137 * OTRL_EXTRAKEY_BYTES. The requested use, as well as use-specific
138 * data will be passed so that the applications can communicate other
139 * information (some id for the data transfer, for example). */
140 void (*received_symkey)(void *opdata, ConnContext *context,
141 unsigned int use, const unsigned char *usedata,
142 size_t usedatalen, const unsigned char *symkey);
143
144 /* Return a string according to the error event. This string will then
145 * be concatenated to an OTR header to produce an OTR protocol error
146 * message. The following are the possible error events:
147 * - OTRL_ERRCODE_ENCRYPTION_ERROR
148 * occured while encrypting a message
149 * - OTRL_ERRCODE_MSG_NOT_IN_PRIVATE
150 * sent encrypted message to somebody who is not in
151 * a mutual OTR session
152 * - OTRL_ERRCODE_MSG_UNREADABLE
153 * sent an unreadable encrypted message
154 * - OTRL_ERRCODE_MSG_MALFORMED
155 * message sent is malformed */
156 const char *(*otr_error_message)(void *opdata, ConnContext *context,
157 OtrlErrorCode err_code);
158
159 /* Deallocate a string returned by otr_error_message */
160 void (*otr_error_message_free)(void *opdata, const char *err_msg);
161
162 /* Return a string that will be prefixed to any resent message. If this
163 * function is not provided by the application then the default prefix,
164 * "[resent]", will be used.
165 * */
166 const char *(*resent_msg_prefix)(void *opdata, ConnContext *context);
167
168 /* Deallocate a string returned by resent_msg_prefix */
169 void (*resent_msg_prefix_free)(void *opdata, const char *prefix);
170
171 /* Update the authentication UI with respect to SMP events
172 * These are the possible events:
173 * - OTRL_SMPEVENT_ASK_FOR_SECRET
174 * prompt the user to enter a shared secret. The sender application
175 * should call otrl_message_initiate_smp, passing NULL as the question.
176 * When the receiver application resumes the SM protocol by calling
177 * otrl_message_respond_smp with the secret answer.
178 * - OTRL_SMPEVENT_ASK_FOR_ANSWER
179 * (same as OTRL_SMPEVENT_ASK_FOR_SECRET but sender calls
180 * otrl_message_initiate_smp_q instead)
181 * - OTRL_SMPEVENT_CHEATED
182 * abort the current auth and update the auth progress dialog
183 * with progress_percent. otrl_message_abort_smp should be called to
184 * stop the SM protocol.
185 * - OTRL_SMPEVENT_INPROGRESS and
186 * OTRL_SMPEVENT_SUCCESS and
187 * OTRL_SMPEVENT_FAILURE and
188 * OTRL_SMPEVENT_ABORT
189 * update the auth progress dialog with progress_percent
190 * - OTRL_SMPEVENT_ERROR
191 * (same as OTRL_SMPEVENT_CHEATED)
192 * */
193 void (*handle_smp_event)(void *opdata, OtrlSMPEvent smp_event,
194 ConnContext *context, unsigned short progress_percent,
195 char *question);
196
197 /* Handle and send the appropriate message(s) to the sender/recipient
198 * depending on the message events. All the events only require an opdata,
199 * the event, and the context. The message and err will be NULL except for
200 * some events (see below). The possible events are:
201 * - OTRL_MSGEVENT_ENCRYPTION_REQUIRED
202 * Our policy requires encryption but we are trying to send
203 * an unencrypted message out.
204 * - OTRL_MSGEVENT_ENCRYPTION_ERROR
205 * An error occured while encrypting a message and the message
206 * was not sent.
207 * - OTRL_MSGEVENT_CONNECTION_ENDED
208 * Message has not been sent because our buddy has ended the
209 * private conversation. We should either close the connection,
210 * or refresh it.
211 * - OTRL_MSGEVENT_SETUP_ERROR
212 * A private conversation could not be set up. A gcry_error_t
213 * will be passed.
214 * - OTRL_MSGEVENT_MSG_REFLECTED
215 * Received our own OTR messages.
216 * - OTRL_MSGEVENT_MSG_RESENT
217 * The previous message was resent.
218 * - OTRL_MSGEVENT_RCVDMSG_NOT_IN_PRIVATE
219 * Received an encrypted message but cannot read
220 * it because no private connection is established yet.
221 * - OTRL_MSGEVENT_RCVDMSG_UNREADABLE
222 * Cannot read the received message.
223 * - OTRL_MSGEVENT_RCVDMSG_MALFORMED
224 * The message received contains malformed data.
225 * - OTRL_MSGEVENT_LOG_HEARTBEAT_RCVD
226 * Received a heartbeat.
227 * - OTRL_MSGEVENT_LOG_HEARTBEAT_SENT
228 * Sent a heartbeat.
229 * - OTRL_MSGEVENT_RCVDMSG_GENERAL_ERR
230 * Received a general OTR error. The argument 'message' will
231 * also be passed and it will contain the OTR error message.
232 * - OTRL_MSGEVENT_RCVDMSG_UNENCRYPTED
233 * Received an unencrypted message. The argument 'smessage' will
234 * also be passed and it will contain the plaintext message.
235 * - OTRL_MSGEVENT_RCVDMSG_UNRECOGNIZED
236 * Cannot recognize the type of OTR message received.
237 * - OTRL_MSGEVENT_RCVDMSG_FOR_OTHER_INSTANCE
238 * Received and discarded a message intended for another instance. */
239 void (*handle_msg_event)(void *opdata, OtrlMessageEvent msg_event,
240 ConnContext *context, const char *message,
241 gcry_error_t err);
242
243 /* Create a instance tag for the given accountname/protocol if
244 * desired. */
245 void (*create_instag)(void *opdata, const char *accountname,
246 const char *protocol);
247
248 /* Called immediately before a data message is encrypted, and after a data
249 * message is decrypted. The OtrlConvertType parameter has the value
250 * OTRL_CONVERT_SENDING or OTRL_CONVERT_RECEIVING to differentiate these
251 * cases. */
252 void (*convert_msg)(void *opdata, ConnContext *context,
253 OtrlConvertType convert_type, char ** dest, const char *src);
254
255 /* Deallocate a string returned by convert_msg. */
256 void (*convert_free)(void *opdata, ConnContext *context, char *dest);
257
258 /* When timer_control is called, turn off any existing periodic
259 * timer.
260 *
261 * Additionally, if interval > 0, set a new periodic timer
262 * to go off every interval seconds. When that timer fires, you
263 * must call otrl_message_poll(userstate, uiops, uiopdata); from the
264 * main libotr thread.
265 *
266 * The timing does not have to be exact; this timer is used to
267 * provide forward secrecy by cleaning up stale private state that
268 * may otherwise stick around in memory. Note that the
269 * timer_control callback may be invoked from otrl_message_poll
270 * itself, possibly to indicate that interval == 0 (that is, that
271 * there's no more periodic work to be done at this time).
272 *
273 * If you set this callback to NULL, then you must ensure that your
274 * application calls otrl_message_poll(userstate, uiops, uiopdata);
275 * from the main libotr thread every definterval seconds (where
276 * definterval can be obtained by calling
277 * definterval = otrl_message_poll_get_default_interval(userstate);
278 * right after creating the userstate). The advantage of
279 * implementing the timer_control callback is that the timer can be
280 * turned on by libotr only when it's needed.
281 *
282 * It is not a problem (except for a minor performance hit) to call
283 * otrl_message_poll more often than requested, whether
284 * timer_control is implemented or not.
285 *
286 * If you fail to implement the timer_control callback, and also
287 * fail to periodically call otrl_message_poll, then you open your
288 * users to a possible forward secrecy violation: an attacker that
289 * compromises the user's computer may be able to decrypt a handful
290 * of long-past messages (the first messages of an OTR
291 * conversation).
292 */
293 void (*timer_control)(void *opdata, unsigned int interval);
294
295} OtrlMessageAppOps;
296
297/* Deallocate a message allocated by other otrl_message_* routines. */
298void otrl_message_free(char *message);
299
300/* Handle a message about to be sent to the network. It is safe to pass
301 * all messages about to be sent to this routine. add_appdata is a
302 * function that will be called in the event that a new ConnContext is
303 * created. It will be passed the data that you supplied, as well as a
304 * pointer to the new ConnContext. You can use this to add
305 * application-specific information to the ConnContext using the
306 * "context->app" field, for example. If you don't need to do this, you
307 * can pass NULL for the last two arguments of otrl_message_sending.
308 *
309 * tlvs is a chain of OtrlTLVs to append to the private message. It is
310 * usually correct to just pass NULL here.
311 *
312 * If non-NULL, ops->convert_msg will be called just before encrypting a
313 * message.
314 *
315 * "instag" specifies the instance tag of the buddy (protocol version 3 only).
316 * Meta-instances may also be specified (e.g., OTRL_INSTAG_MOST_SECURE).
317 * If "contextp" is not NULL, it will be set to the ConnContext used for
318 * sending the message.
319 *
320 * If no fragmentation or msg injection is wanted, use OTRL_FRAGMENT_SEND_SKIP
321 * as the OtrlFragmentPolicy. In this case, this function will assign *messagep
322 * with the encrypted msg. If the routine returns non-zero, then the library
323 * tried to encrypt the message, but for some reason failed. DO NOT send the
324 * message in the clear in that case. If *messagep gets set by the call to
325 * something non-NULL, then you should replace your message with the contents
326 * of *messagep, and send that instead.
327 *
328 * Other fragmentation policies are OTRL_FRAGMENT_SEND_ALL,
329 * OTRL_FRAGMENT_SEND_ALL_BUT_LAST, or OTRL_FRAGMENT_SEND_ALL_BUT_FIRST. In
330 * these cases, the appropriate fragments will be automatically sent. For the
331 * last two policies, the remaining fragment will be passed in *original_msg.
332 *
333 * Call otrl_message_free(*messagep) if you don't need *messagep or when you're
334 * done with it. */
335gcry_error_t otrl_message_sending(OtrlUserState us,
336 const OtrlMessageAppOps *ops,
337 void *opdata, const char *accountname, const char *protocol,
338 const char *recipient, otrl_instag_t instag, const char *original_msg,
339 OtrlTLV *tlvs, char **messagep, OtrlFragmentPolicy fragPolicy,
340 ConnContext **contextp,
341 void (*add_appdata)(void *data, ConnContext *context),
342 void *data);
343
344/* Handle a message just received from the network. It is safe to pass
345 * all received messages to this routine. add_appdata is a function
346 * that will be called in the event that a new ConnContext is created.
347 * It will be passed the data that you supplied, as well as
348 * a pointer to the new ConnContext. You can use this to add
349 * application-specific information to the ConnContext using the
350 * "context->app" field, for example. If you don't need to do this, you
351 * can pass NULL for the last two arguments of otrl_message_receiving.
352 *
353 * If non-NULL, ops->convert_msg will be called after a data message is
354 * decrypted.
355 *
356 * If "contextp" is not NULL, it will be set to the ConnContext used for
357 * receiving the message.
358 *
359 * If otrl_message_receiving returns 1, then the message you received
360 * was an internal protocol message, and no message should be delivered
361 * to the user.
362 *
363 * If it returns 0, then check if *messagep was set to non-NULL. If
364 * so, replace the received message with the contents of *messagep, and
365 * deliver that to the user instead. You must call
366 * otrl_message_free(*messagep) when you're done with it. If tlvsp is
367 * non-NULL, *tlvsp will be set to a chain of any TLVs that were
368 * transmitted along with this message. You must call
369 * otrl_tlv_free(*tlvsp) when you're done with those.
370 *
371 * If otrl_message_receiving returns 0 and *messagep is NULL, then this
372 * was an ordinary, non-OTR message, which should just be delivered to
373 * the user without modification. */
374int otrl_message_receiving(OtrlUserState us, const OtrlMessageAppOps *ops,
375 void *opdata, const char *accountname, const char *protocol,
376 const char *sender, const char *message, char **newmessagep,
377 OtrlTLV **tlvsp, ConnContext **contextp,
378 void (*add_appdata)(void *data, ConnContext *context),
379 void *data);
380
381/* Put a connection into the PLAINTEXT state, first sending the
382 * other side a notice that we're doing so if we're currently ENCRYPTED,
383 * and we think he's logged in. Affects only the specified instance. */
384void otrl_message_disconnect(OtrlUserState us, const OtrlMessageAppOps *ops,
385 void *opdata, const char *accountname, const char *protocol,
386 const char *username, otrl_instag_t instance);
387
388/* Put a connection into the PLAINTEXT state, first sending the
389 * other side a notice that we're doing so if we're currently ENCRYPTED,
390 * and we think he's logged in. Affects all matching instances. */
391void otrl_message_disconnect_all_instances(OtrlUserState us,
392 const OtrlMessageAppOps *ops, void *opdata, const char *accountname,
393 const char *protocol, const char *username);
394
395/* Initiate the Socialist Millionaires' Protocol */
396void otrl_message_initiate_smp(OtrlUserState us, const OtrlMessageAppOps *ops,
397 void *opdata, ConnContext *context, const unsigned char *secret,
398 size_t secretlen);
399
400/* Initiate the Socialist Millionaires' Protocol and send a prompt
401 * question to the buddy */
402void otrl_message_initiate_smp_q(OtrlUserState us,
403 const OtrlMessageAppOps *ops, void *opdata, ConnContext *context,
404 const char *question, const unsigned char *secret, size_t secretlen);
405
406/* Respond to a buddy initiating the Socialist Millionaires' Protocol */
407void otrl_message_respond_smp(OtrlUserState us, const OtrlMessageAppOps *ops,
408 void *opdata, ConnContext *context, const unsigned char *secret,
409 size_t secretlen);
410
411/* Abort the SMP. Called when an unexpected SMP message breaks the
412 * normal flow. */
413void otrl_message_abort_smp(OtrlUserState us, const OtrlMessageAppOps *ops,
414 void *opdata, ConnContext *context);
415
416/* Get the current extra symmetric key (of size OTRL_EXTRAKEY_BYTES
417 * bytes) and let the other side know what we're going to use it for.
418 * The key is stored in symkey, which must already be allocated
419 * and OTRL_EXTRAKEY_BYTES bytes long. */
420gcry_error_t otrl_message_symkey(OtrlUserState us,
421 const OtrlMessageAppOps *ops, void *opdata, ConnContext *context,
422 unsigned int use, const unsigned char *usedata, size_t usedatalen,
423 unsigned char *symkey);
424
425/* If you do _not_ define a timer_control callback function, set a timer
426 * to go off every definterval =
427 * otrl_message_poll_get_default_interval(userstate) seconds, and call
428 * otrl_message_poll every time the timer goes off. */
429unsigned int otrl_message_poll_get_default_interval(OtrlUserState us);
430
431/* Call this function every so often, either as directed by the
432 * timer_control callback, or every definterval =
433 * otrl_message_poll_get_default_interval(userstate) seconds if you have
434 * no timer_control callback. This function must be called from the
435 * main libotr thread.*/
436void otrl_message_poll(OtrlUserState us, const OtrlMessageAppOps *ops,
437 void *opdata);
438
439#endif
440