1 /*
2   Copyright (C) 2006-2013 Werner Dittmann
3 
4   This program is free software: you can redistribute it and/or modify
5   it under the terms of the GNU Lesser General Public License as published by
6   the Free Software Foundation, either version 3 of the License, or
7   (at your option) any later version.
8 
9   This program is distributed in the hope that it will be useful,
10   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   GNU General Public License for more details.
13 
14   You should have received a copy of the GNU General Public License
15   along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 */
17 
18 #include <string>
19 
20 #include "ZIDRecord.h"
21 
22 #ifndef _ZIDCACHE_H_
23 #define _ZIDCACHE_H_
24 
25 /**
26  * @file ZIDCache.h
27  * @brief ZID cache management
28  *
29  * A ZID file stores (caches) some data that helps ZRTP to achives its
30  * key continuity feature. See @c ZIDRecord for further info which data
31  * the ZID file contains.
32  *
33  * @ingroup GNU_ZRTP
34  * @{
35  */
36 
37 /**
38  * Interface for classes that implements a ZID (ZRTP Identifiers) file.
39  *
40  * The ZID file holds information about peers.
41  *
42  * @author: Werner Dittmann <Werner.Dittmann@t-online.de>
43  */
44 
45 class ZIDCache;
46 
47 __EXPORT ZIDCache* getZidCacheInstance();
48 
49 
50 class __EXPORT ZIDCache {
51 
52 public:
53 
54     /**
55      * @brief Destructor.
56      * Define a virtual destructor to enable cleanup in derived classes.
57      */
58     virtual ~ZIDCache() {};
59 
60     /**
61      * @brief Open the named ZID file and return a ZID file class.
62      *
63      * This static function either opens an existing ZID file or
64      * creates a new ZID file with the given name. The ZIDCache is a
65      * singleton, thus only <em>one</em> ZID file can be open at one
66      * time.
67      *
68      * To open another ZID file you must close the active ZID file
69      * first.
70      *
71      * @param name
72      *    The name of the ZID file to open or create
73      * @return
74      *    1 if file could be opened/created, 0 if the ZID instance
75      *    already has an open file, -1 if open/creation of file failed.
76      */
77     virtual int open(char *name) =0;
78 
79     /**
80      * @brief Check if ZIDCache has an active (open) file.
81      *
82      * @return
83      *    True if ZIDCache has an active file, false otherwise
84      */
85     virtual bool isOpen() =0;
86 
87      /**
88       * @brief Close the ZID file.
89       *
90       * Closes the ZID file, and prepares to open a new ZID file.
91       */
92     virtual void close() =0;
93 
94     /**
95      * @brief Get a ZID record from ZID cache or create a new record.
96      *
97      * The method tries to read a ZRTP cache record for the ZID.
98      * If no matching record exists in the cache the method creates
99      * it and fills it with default values.
100      *
101      * @param zid is the ZRTP id of the peer
102      * @return pointer to the ZID record. The call must @c delete the
103      *         record if it is not longer used.
104      */
105     virtual ZIDRecord *getRecord(unsigned char *zid) =0;
106 
107     /**
108      * @brief Save a ZID record into the active ZID file.
109      *
110      * This method saves the content of a ZID record into the ZID file. Before
111      * you can save the ZID record you must have performed a getRecord()
112      * first.
113      *
114      * @param zidRecord
115      *    The ZID record to save.
116      * @return
117      *    1 on success
118      */
119     virtual unsigned int saveRecord(ZIDRecord *zidRecord) =0;
120 
121     /**
122      * @brief Get the ZID associated with this ZID file.
123      *
124      * @return
125      *    Pointer to the ZID
126      */
127     virtual const unsigned char* getZid() =0;
128 
129     /**
130      * @brief Get peer name from database.
131      *
132      * This is an optional function.
133      *
134      * A client may use this function to retrieve a name that was assigned
135      * to the peer's ZID.
136      *
137      * @param peerZid the peer's ZID
138      *
139      * @param name string that will get the peer's name. The returned name will
140      *             be truncated to 200 bytes
141      *
142      * @return length og the name read or 0 if no name was previously stored.
143      */
144     virtual int32_t getPeerName(const uint8_t *peerZid, std::string *name) =0;
145 
146     /**
147      * @brief Write peer name to database.
148      *
149      * This is an optional function.
150      *
151      * A client may use this function to write a name in the ZRTP cache database and
152      * asign it to the peer's ZID.
153      *
154      * @param peerZid the peer's ZID
155      *
156      * @param name the name string
157      *
158      */
159     virtual void putPeerName(const uint8_t *peerZid, const std::string name) =0;
160 
161     /**
162      * @brief Clean the cache - only for ZID cache with Sqlite3 backend.
163      *
164      * The function drops and re-creates all tables in the database. This removes all stored
165      * data. The application must not call this while a ZRTP call is active. Also the application
166      * <b>must</b> get the local ZID again.
167      *
168      */
169     virtual void cleanup() =0;
170 
171     /**
172      * @brief Prepare a SQL cursor to read all records from the remote (peer) ZID table.
173      *
174      * The function creates a SQL cursor (prepares a statement in sqlite3 parlance) to
175      * read all records from the table that contains the remote (peers') ZID data.
176      *
177      * This functions returns a pointer to the SQL cursor or @c NULL if it fails to
178      * create a cursor.
179      *
180      * @return a void pointer to the sqlite3 statment (SQL cursor) or @c NULL
181      */
182     virtual void *prepareReadAll() =0;
183 
184     /**
185      * @brief Read next ZID record from and SQL cursor.
186      *
187      * The function reads the next ZID record from a SQL cursor. If it cannot read a
188      * record or encounters an error the function closes the cursor and returns @c NULL.
189      * In this case the function must not use the SQL cursor pointer again.
190      *
191      * For the second parameter the caller @b must use a ZIDRecordDb pointer, not
192      * a ZIDRecordFile pointer.
193      *
194      * The function returns a string in its output parameter. The '|' symbol separates
195      * the different fields. Here the description of the fields:
196      * <ol>
197      * <li> The own ZID, should always be the same (in theroy we coud use different local ZIDs), hex value of random data </li>
198      * <li> the partner's (remote) ZID, hex value of random data</li>
199      * <li> the flag byte (bit field, explanation see below and in ZIDRecordDb.h:
200      * <ul>
201      *     <li>Valid            = 0x1;</li>
202      *     <li>SASVerified      = 0x2;</li>
203      *     <li>RS1Valid         = 0x4;</li>
204      *     <li>RS2Valid         = 0x8;</li>
205      *     <li> MITMKeyAvailable= 0x10;</li>
206      *     <li>inUse            = 0x20;</li>
207      * </ul>
208      * </li>
209      * <li> RS1 value, hex field, 32 binary bytes</li>
210      * <li> RS1 last used timestamp (Unix epoch), decimal, currently not used, always 0</li>
211      * <li> RS1 Time-To-Live timestamp (Unix epoch), decimal, if -1: valid for ever, otherwise the time it's not longer valid</li>
212      * <li> RS2 value, hex field, 32 binary bytes</li>
213      * <li> RS2 last used timestamp (Unix epoch), decimal, currently not used, always 0</li>
214      * <li> RS2 Time-To-Live timestamp (Unix epoch), decimal, if -1: valid for ever, otherwise the time it's not longer valid</li>
215      * <li> trusted PBX shared key value, hex field, 32 binary bytes, valid only if MITMKeyAvailable bit is set</li>
216      * <li> trusted PBX shared key last used timestamp (Unix epoch), decimal, currently not used, always 0</li>
217      * <li> Secure since timestamp (Unix epoch), decimal, shows time ZRTP created this ZID record</li>
218      * <li> Name, may be empty</li>
219      * </ol>
220      *
221      * @param stmt a void pointer to a sqlite3 statement (SQL cursor)
222      *
223      * @param output that will get the peer's name. The returned name will
224      *             be truncated to 200 bytes
225      *
226      * @return void pointer to statment if successful, this is the same pointer as
227      *         the @c stmt input parameter. The function returns @c NULL if either
228      *         no more record is available or it got another error.
229      */
230     virtual void *readNextRecord(void *stmt, std::string *output) =0;
231 
232     virtual void closeOpenStatment(void *stmt) =0;
233 
234 };
235 
236 /**
237  * @}
238  */
239 #endif
240