1 /*
2  *  Off-the-Record Messaging library
3  *  Copyright (C) 2004-2014  Ian Goldberg, David Goulet, Rob Smits,
4  *                           Chris Alexander, Willy Lew, Lisa Du,
5  *                           Nikita Borisov
6  *                           <otr@cypherpunks.ca>
7  *
8  *  This library is free software; you can redistribute it and/or
9  *  modify it under the terms of version 2.1 of the GNU Lesser General
10  *  Public License as published by the Free Software Foundation.
11  *
12  *  This library is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  *  Lesser General Public License for more details.
16  *
17  *  You should have received a copy of the GNU Lesser General Public
18  *  License along with this library; if not, write to the Free Software
19  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #ifndef __CONTEXT_H__
23 #define __CONTEXT_H__
24 
25 #include "context_priv.h"
26 
27 #include <gcrypt.h>
28 
29 #include "dh.h"
30 #include "auth.h"
31 #include "sm.h"
32 
33 typedef struct context ConnContext;    /* Forward declare */
34 
35 #include "instag.h"
36 
37 typedef enum {
38     OTRL_MSGSTATE_PLAINTEXT,           /* Not yet started an encrypted
39 					  conversation */
40     OTRL_MSGSTATE_ENCRYPTED,           /* Currently in an encrypted
41 					  conversation */
42     OTRL_MSGSTATE_FINISHED             /* The remote side has sent us a
43 					  notification that he has ended
44 					  his end of the encrypted
45 					  conversation; prevent any
46 					  further messages from being
47 					  sent to him. */
48 } OtrlMessageState;
49 
50 typedef struct s_fingerprint {
51     struct s_fingerprint *next;        /* The next fingerprint in the list */
52     struct s_fingerprint **tous;       /* A pointer to the pointer to us */
53     unsigned char *fingerprint;        /* The fingerprint, or NULL */
54     struct context *context;           /* The context to which we belong */
55     char *trust;                       /* The trust level of the fingerprint */
56 } Fingerprint;
57 
58 struct context {
59     struct context * next;             /* Linked list pointer */
60     struct context ** tous;            /* A pointer to the pointer to us */
61 
62     /* Context information that is meant for internal use */
63 
64     ConnContextPriv *context_priv;
65 
66     /* Context information that is meant for application use */
67 
68     char * username;                   /* The user this context is for */
69     char * accountname;                /* The username is relative to
70 					  this account... */
71     char * protocol;                   /* ... and this protocol */
72 
73     struct context *m_context;         /* If this is a child context, this
74 					  field will point to the master
75 					  context. Otherwise it will point to
76 					  itself. */
77     struct context *recent_rcvd_child; /* If this is a master context, this
78 					  points to the child context that
79 					  has received a message most recently.
80 					  By default, it will point to the
81 					  master context. In child contexts
82 					  this field is NULL. */
83     struct context *recent_sent_child; /* Similar to above, but it points to
84 					  the child who has sent most
85 					  recently. */
86     struct context *recent_child;      /* Similar to above, but will point to
87 					  the most recent of recent_rcvd_child
88 					  and recent_sent_child */
89 
90     otrl_instag_t our_instance;        /* Our instance tag for this computer*/
91     otrl_instag_t their_instance;      /* The user's instance tag */
92 
93     OtrlMessageState msgstate;         /* The state of message disposition
94 					  with this user */
95     OtrlAuthInfo auth;                 /* The state of ongoing
96 					  authentication with this user */
97 
98     Fingerprint fingerprint_root;      /* The root of a linked list of
99 					  Fingerprints entries. This list will
100 					  only be populated in master contexts.
101 					  For child contexts,
102 					  fingerprint_root.next will always
103 					  point to NULL. */
104     Fingerprint *active_fingerprint;   /* Which fingerprint is in use now?
105 					  A pointer into the above list */
106 
107     unsigned char sessionid[20];       /* The sessionid and bold half */
108     size_t sessionid_len;              /* determined when this private */
109     OtrlSessionIdHalf sessionid_half;  /* connection was established. */
110 
111     unsigned int protocol_version;     /* The version of OTR in use */
112 
113     enum {
114 	OFFER_NOT,
115 	OFFER_SENT,
116 	OFFER_REJECTED,
117 	OFFER_ACCEPTED
118     } otr_offer;          /* Has this correspondent repsponded to our
119 			     OTR offers? */
120 
121     /* Application data to be associated with this context */
122     void *app_data;
123     /* A function to free the above data when we forget this context */
124     void (*app_data_free)(void *);
125 
126     OtrlSMState *smstate;              /* The state of the current
127 					  socialist millionaires exchange */
128 };
129 
130 #include "userstate.h"
131 
132 /* Look up a connection context by name/account/protocol/instance from the
133  * given OtrlUserState.  If add_if_missing is true, allocate and return a
134  * new context if one does not currently exist.  In that event, call
135  * add_app_data(data, context) so that app_data and app_data_free can be
136  * filled in by the application, and set *addedp to 1.
137  * In the 'their_instance' field note that you can also specify a 'meta-
138  * instance' value such as OTRL_INSTAG_MASTER, OTRL_INSTAL_RECENT,
139  * OTRL_INSTAG_RECENT_RECEIVED and OTRL_INSTAG_RECENT_SENT. */
140 ConnContext * otrl_context_find(OtrlUserState us, const char *user,
141 	const char *accountname, const char *protocol,
142 	otrl_instag_t their_instance, int add_if_missing, int *addedp,
143 	void (*add_app_data)(void *data, ConnContext *context), void *data);
144 
145 /* Return true iff the given fingerprint is marked as trusted. */
146 int otrl_context_is_fingerprint_trusted(Fingerprint *fprint);
147 
148 /* This method gets called after sending or receiving a message, to
149  * update the master context's "recent context" pointers. */
150 void otrl_context_update_recent_child(ConnContext *context,
151 	unsigned int sent_msg);
152 
153 /* Find a fingerprint in a given context, perhaps adding it if not
154  * present. */
155 Fingerprint *otrl_context_find_fingerprint(ConnContext *context,
156 	unsigned char fingerprint[20], int add_if_missing, int *addedp);
157 
158 /* Set the trust level for a given fingerprint */
159 void otrl_context_set_trust(Fingerprint *fprint, const char *trust);
160 
161 /* Force a context into the OTRL_MSGSTATE_FINISHED state. */
162 void otrl_context_force_finished(ConnContext *context);
163 
164 /* Force a context into the OTRL_MSGSTATE_PLAINTEXT state. */
165 void otrl_context_force_plaintext(ConnContext *context);
166 
167 /* Forget a fingerprint (so long as it's not the active one.  If it's a
168  * fingerprint_root, forget the whole context (as long as
169  * and_maybe_context is set, and it's PLAINTEXT).  Also, if it's not
170  * the fingerprint_root, but it's the only fingerprint, and we're
171  * PLAINTEXT, forget the whole context if and_maybe_context is set. */
172 void otrl_context_forget_fingerprint(Fingerprint *fprint,
173 	int and_maybe_context);
174 
175 /* Forget a whole context, so long as it's PLAINTEXT. If a context has child
176  * instances, don't remove this instance unless children are also all in
177  * PLAINTEXT state. In this case, the children will also be removed.
178  * Returns 0 on success, 1 on failure. */
179 int otrl_context_forget(ConnContext *context);
180 
181 /* Forget all the contexts in a given OtrlUserState. */
182 void otrl_context_forget_all(OtrlUserState us);
183 
184 /* Find requested recent instance */
185 ConnContext * otrl_context_find_recent_instance(ConnContext * context,
186 		otrl_instag_t recent_instag);
187 
188 /* Find the instance of this context that has the best security level, and for
189  * which we have most recently received a message from. Note that most recent
190  * in this case is limited to a one-second resolution. */
191 ConnContext * otrl_context_find_recent_secure_instance(ConnContext * context);
192 
193 #endif
194