zuluCrypt  5.7.1
About: zuluCrypt is a simple but feature rich solution for hard drives encryption. It can manage PLAIN dm-crypt, LUKS, TrueCrypt and VeraCrypt encrypted volumes.
  Fossies Dox: zuluCrypt-5.7.1.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

add_key.c
Go to the documentation of this file.
1 /*
2  *
3  * Copyright (c) 2011-2015
4  * name : Francis Banyikwa
5  * email: mhogomchungu@gmail.com
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program 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
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include "includes.h"
21 #include "../lib/includes.h"
22 #include <locale.h>
23 #include <stdio.h>
24 #include <libintl.h>
25 #include <sys/stat.h>
26 
27 typedef struct{
28 
29  const char * device ;
30  const char * existing_key ;
33  const char * new_key ;
34  size_t new_key_size ;
36  const char * type ;
37 
38 }tcrypt_opts ;
39 
40 /*
41  * Its not possible to add more keys to a volume with no empty slots or to a non luks volume
42  *
43  * This function checks if a volume is luks and if it has atleast one empty slot.
44  */
45 static int _zuluCryptCheckEmptySlots( const char * device )
46 {
47  int r = 0 ;
48  char * c ;
49  char * d ;
50 
52 
53  /*
54  * zuluCryptVolumeIsLuks() is defined in ../lib/is_luks.c
55  */
56  if( zuluCryptVolumeIsLuks( device ) ){
57 
58  /*
59  * zuluCryptEmptySlots() is defined in ../lib/empty_slots.c
60  */
61  c = zuluCryptEmptySlots( device ) ;
62 
63  if( c == NULL ){
64  /*
65  * we shouldnt get here
66  */
67  r = 1 ;
68  }else{
69  d = c - 1 ;
70 
71  while( *++d ){
72 
73  if( *d == '0' ){
74 
75  r = 2 ;
76 
77  break ;
78  }
79  }
80 
81  StringFree( c ) ;
82  }
83  }else{
84  /*
85  * volume is not a LUKS volume,assuming its a TrueCrypt volume
86  */
87  r = 2 ;
88  }
89 
91 
92  return r ;
93 }
94 
95 static int _replace_truecrypt_key( const tcrypt_opts * opts )
96 {
97  info_t info ;
98 
99  string_t st = StringVoid ;
100  string_t xt = StringVoid ;
101 
102  int r ;
103 
104  stringList_t stl ;
105 
106  memset( &info,'\0',sizeof( info_t ) ) ;
107 
108  stl = veraCryptVolumePIMValue( &info,opts->type ) ;
109 
110  info.device = opts->device ;
111 
112  /*
113  * zuluCryptCreateKeyFile() is defined in ../lib/open_tcrypt.c
114  */
115  if( opts->existing_key_is_keyfile ){
116 
117  info.header_key_source = "keyfiles" ;
118  st = zuluCryptCreateKeyFile( opts->existing_key,opts->existing_key_size,"add-tcrypt-1" ) ;
119  info.header_key = StringContent( st ) ;
120  }else{
121  info.header_key_source = "passphrase" ;
122  info.header_key = opts->existing_key ;
123  }
124 
125  if( opts->new_key_is_keyfile ){
126 
127  info.header_new_key_source = "new_keyfiles" ;
128  st = zuluCryptCreateKeyFile( opts->new_key,opts->new_key_size,"add-tcrypt-2" ) ;
129  info.header_new_key = StringContent( st ) ;
130  }else{
131 
132  info.header_new_key_source = "new_passphrase" ;
133  info.header_new_key = opts->new_key ;
134  }
135 
136  info.rng = "/dev/urandom" ;
137 
138  /*
139  * zuluCryptModifyTcryptHeader() is defined in ../lib/create_tcrypt.c
140  */
141  r = zuluCryptModifyTcryptHeader( &info ) ;
142 
143  /*
144  * zuluCryptDeleteFile_1() is defined in ../lib/file_path_security.c
145  */
146  if( st != StringVoid ){
147 
148  zuluCryptDeleteFile_1( st ) ;
149  StringDelete( &st ) ;
150  }
151  if( xt != StringVoid ){
152 
153  zuluCryptDeleteFile_1( xt ) ;
154  StringDelete( &xt ) ;
155  }
156 
157  StringListDelete( &stl ) ;
158 
159  if( r == 0 ){
160 
161  return 0 ;
162  }else{
163  return 1 ;
164  }
165 }
166 
167 static int zuluExit( int st,stringList_t stl )
168 {
170  /*
171  * this function is defined in ../string/StringList.c
172  */
173  StringListClearDelete( &stl ) ;
174 
175  switch( st ){
176  case 0 : printf( gettext( "SUCCESS: key added successfully\n" ) ) ; break ;
177  case 1 : printf( gettext( "ERROR: Presented key does not match any key in the volume\n" ) ) ; break ;
178  case 2 : printf( gettext( "ERROR: Could not open luks volume\n" ) ) ; break ;
179  case 3 : printf( gettext( "ERROR: Volume is not a luks volume\n" ) ); break ;
180  case 4 : printf( gettext( "ERROR: Insufficient privilege to open a system device,\n\
181 only root user or members of group \"zulucrypt\" can do that\n" ) ) ; break ;
182  case 5 : printf( gettext( "ERROR: Could not open volume in write mode\n" ) ) ; break ;
183  case 6 : printf( gettext( "ERROR: All key slots are occupied, can not add any more keys\n" ) ) ; break ;
184  case 7 : printf( gettext( "ERROR: Can not get passphrase in silent mode\n" ) ) ; break ;
185  case 8 : printf( gettext( "ERROR: Insufficient memory to hold passphrase\n" ) ) ; break ;
186  case 9 : printf( gettext( "ERROR: New passphrases do not match\n" ) ) ; break ;
187  case 10 : printf( gettext( "ERROR: One or more required argument(s) for this operation is missing\n" ));break ;
188  case 11 : printf( gettext( "ERROR: One or both keyfile(s) does not exist\n" ) ) ; break ;
189  case 12 : printf( gettext( "ERROR: Insufficient privilege to open key file for reading\n" ) ) ; break ;
190  case 13 : printf( gettext( "ERROR: Couldnt get enought memory to hold the key file\n" ) ) ; break ;
191  case 14 : printf( gettext( "ERROR: Could not get a key from a socket\n" ) ) ; break ;
192  case 15 : printf( gettext( "ERROR: Could not get elevated privilege,check binary permissions\n" ) ) ; break ;
193  default : printf( gettext( "ERROR: Unrecognized error with status number %d encountered\n" ),st ) ;
194  }
195 
196  return st ;
197 }
198 
199 static int zuluGetKeys( string_t * key1,string_t * key2,string_t * key3 )
200 {
201  int st ;
202  /*
203  * ZULUCRYPT_KEY_MAX_SIZE is set in ../constants.h
204  */
205  printf( gettext( "Enter an existing passphrase: " ) ) ;
206 
208 
209  if( st != 0 ){
210 
211  return st ;
212  }
213 
214  printf( gettext( "\nEnter the new passphrase: " ) ) ;
215 
217 
218  if( st != 0 ){
219 
220  StringClearDelete( key1 ) ;
221 
222  return st ;
223  }
224 
225  printf( gettext( "\nRe enter the new passphrase: " ) ) ;
226 
228 
229  if( st != 0 ){
230 
231  StringClearDelete( key1 ) ;
232  StringClearDelete( key2 ) ;
233 
234  return st ;
235  }
236 
237  printf( "\n" ) ;
238  return 0 ;
239 }
240 
241 /*
242  * get_pass_from_file function is defined at get_pass_from_file.c *
243  */
244 int zuluCryptEXEAddKey( const struct_opts * opts,uid_t uid )
245 {
246  const char * device = opts->device ;
247  const char * keyType1 = opts->existing_key_source ;
248  const char * existingKey = opts->existing_key ;
249  const char * keyType2 = opts->new_key_source ;
250  const char * newKey = opts->new_key ;
251 
252  /*
253  * Below is a form of memory management.All strings are collected in a stringlist object to easily delete them
254  * when the function returns.This allows for the function to have multiple exit points without risks of leaking
255  * memory from manually examining each exit point to make sure all strings are deleted or go with multiple goto
256  * code deleting blocks to take into account different exit points.
257  */
258  stringList_t stl ;
259  string_t * stringArray = StringListArray( &stl,5 ) ;
260  string_t * presentKey = &stringArray[ 0 ] ;
261  string_t * newKey_1 = &stringArray[ 1 ] ;
262  string_t * newKey_2 = &stringArray[ 2 ] ;
263  string_t * ek = &stringArray[ 3 ] ;
264  string_t * nk = &stringArray[ 4 ] ;
265 
266  const char * key1 = NULL ;
267  const char * key2 = NULL ;
268 
269  size_t len1 = 0 ;
270  size_t len2 = 0 ;
271 
272  int status = 0 ;
273 
274  int socket_path ;
275 
277 
278  memset( &tcrypt,'\0',sizeof( tcrypt_opts ) ) ;
279 
280  /*
281  * zuluCryptPartitionIsSystemPartition() is defined in ./partitions.c
282  */
283  if( zuluCryptPartitionIsSystemPartition( device,uid ) ){
284 
286 
287  if( !zuluCryptUserIsAMemberOfAGroup( uid,"zulucrypt" ) ){
288 
289  return zuluExit( 4,stl ) ;
290  }
291  }
292  }
293  /*
294  * zuluCryptSecurityDeviceIsWritable() is defined in path_access.c
295  */
296  status = zuluCryptCanOpenPathForWriting( device,uid ) ;
297  /*
298  * 1-permissions denied
299  * 2-invalid path
300  * 3-shenanigans
301  * 4-common error
302  */
303  switch( status ){
304 
305  case 0 : break ;
306  case 1 : return zuluExit( 5,stl ) ;
307  case 2 : return zuluExit( 5,stl ) ;
308  case 3 : return zuluExit( 5,stl ) ;
309  case 4 : return zuluExit( 5,stl ) ;
310  default: return zuluExit( 5,stl ) ;
311  }
312 
313  switch( _zuluCryptCheckEmptySlots( device ) ){
314 
315  case 0 : return zuluExit( 6,stl ) ;
316  case 1 : return zuluExit( 2,stl ) ;
317  case 2 : /* no complains,continue */ ;
318  }
319 
320  if( keyType1 == NULL && keyType2 == NULL ){
321 
322  switch( zuluGetKeys( presentKey,newKey_1,newKey_2 ) ){
323 
324  case 1 : return zuluExit( 7,stl ) ;
325  case 2 : return zuluExit( 8,stl ) ;
326  }
327 
328  if( StringsAreEqual_1( *newKey_1,*newKey_2 ) ){
329 
330  key1 = StringContent( *presentKey ) ;
331  len1 = StringLength ( *presentKey ) ;
332  key2 = StringContent( *newKey_1 ) ;
333  len2 = StringLength ( *newKey_1 ) ;
334  }else{
335  return zuluExit( 9,stl ) ;
336  }
337  }else{
338  if( newKey == NULL || existingKey == NULL ){
339 
340  return zuluExit( 10,stl ) ;
341  }
342  if( StringsAreEqual( keyType1,"-f" ) ){
343 
344  /*
345  * this function is defined at "path_access.c"
346  */
347 
348  switch( zuluCryptGetPassFromFile( &socket_path,existingKey,uid,ek ) ){
349 
350  case 1 : return zuluExit( 11,stl ) ;
351  case 4 : return zuluExit( 12,stl ) ;
352  case 2 : return zuluExit( 13,stl ) ;
353  case 5 : return zuluExit( 14,stl ) ;
354  }
355 
356  key1 = StringContent( *ek ) ;
357  len1 = StringLength( *ek ) ;
358 
359  if( !socket_path ){
360 
361  tcrypt.existing_key_is_keyfile = 1 ;
362  }
363  }
364  if( StringsAreEqual( keyType2,"-f" ) ){
365 
366  /*
367  * this function is defined at "path_access.c"
368  */
369 
370  switch( zuluCryptGetPassFromFile( &socket_path,newKey,uid,nk ) ){
371 
372  case 1 : return zuluExit( 11,stl ) ;
373  case 4 : return zuluExit( 12,stl ) ;
374  case 2 : return zuluExit( 13,stl ) ;
375  case 5 : return zuluExit( 14,stl ) ;
376  }
377 
378  key2 = StringContent( *nk ) ;
379  len2 = StringLength( *nk ) ;
380 
381  if( !socket_path ){
382 
383  tcrypt.new_key_is_keyfile = 1 ;
384  }
385  }
386  if( StringsAreEqual( keyType1,"-f" ) && StringsAreEqual( keyType2,"-f" ) ){
387 
388  ;
389 
390  }else if( StringsAreEqual( keyType1,"-p" ) && StringsAreEqual( keyType2,"-p" ) ){
391 
392  key1 = existingKey ;
393  len1 = StringSize( existingKey ) ;
394  key2 = newKey ;
395  len2 = StringSize( newKey ) ;
396 
397  }else if( StringsAreEqual( keyType1,"-p" ) && StringsAreEqual( keyType2,"-f" ) ){
398 
399  key1 = existingKey ;
400  len1 = StringSize( existingKey ) ;
401 
402  }else if( StringsAreEqual( keyType1,"-f" ) && StringsAreEqual( keyType2,"-p" ) ){
403 
404  key2 = newKey ;
405  len2 = StringSize( newKey ) ;
406  }else{
407  return zuluExit( 10,stl ) ;
408  }
409  }
410 
412 
414 
415  /*
416  * zuluCryptVolumeIsLuks() is defined in ../lib/is_luks.c
417  */
418  if( zuluCryptVolumeIsLuks( device ) ){
419 
420  /*
421  * zuluCryptAddKey() is defined in ../lib/add_key.c
422  */
423  status = zuluCryptAddKey( device,key1,len1,key2,len2 ) ;
424  }else{
425  tcrypt.device = device ;
426 
427  tcrypt.existing_key = key1 ;
428  tcrypt.existing_key_size = len1 ;
429 
430  tcrypt.new_key = key2 ;
431  tcrypt.new_key_size = len2 ;
432 
433  tcrypt.type = opts->type ;
434 
436  }
437 
439 
440  return zuluExit( status,stl ) ;
441 }
tcrypt_opts::device
const char * device
Definition: add_key.c:29
StringSilentlyGetFromTerminal_1
int StringSilentlyGetFromTerminal_1(string_t *q, size_t s)
Definition: String.c:1752
_zuluCryptCheckEmptySlots
static int _zuluCryptCheckEmptySlots(const char *device)
Definition: add_key.c:45
struct_opts_1::type
const char * type
Definition: libzuluCrypt-exe.h:44
info_t::header_new_key_source
const char * header_new_key_source
Definition: includes.h:61
info_t::header_new_key
const char * header_new_key
Definition: includes.h:60
info_t::device
const char * device
Definition: includes.h:52
struct_opts_1::device
const char * device
Definition: libzuluCrypt-exe.h:37
StringLength
size_t StringLength(string_t st)
Definition: String.c:678
_replace_truecrypt_key
static int _replace_truecrypt_key(const tcrypt_opts *opts)
Definition: add_key.c:95
tcrypt_opts::type
const char * type
Definition: add_key.c:36
tcrypt_opts::existing_key_size
size_t existing_key_size
Definition: add_key.c:31
struct_opts_1::new_key
const char * new_key
Definition: libzuluCrypt-exe.h:48
tcrypt_opts::existing_key_is_keyfile
size_t existing_key_is_keyfile
Definition: add_key.c:32
zuluCryptCanOpenPathForWriting
int zuluCryptCanOpenPathForWriting(const char *path, uid_t uid)
Definition: path_access.c:103
struct_opts_1
Definition: libzuluCrypt-exe.h:35
zuluCryptUserIsAMemberOfAGroup
int zuluCryptUserIsAMemberOfAGroup(uid_t uid, const char *groupname)
Definition: mount_fs_options.c:172
zuluExit
static int zuluExit(int st, stringList_t stl)
Definition: add_key.c:167
StringListDelete
void StringListDelete(stringList_t *stl)
Definition: StringList.c:1184
zuluCryptAddKey
int zuluCryptAddKey(const char *device, const char *existingkey, size_t existingkey_size, const char *newkey, size_t newkey_size)
Definition: add_key.c:67
info_t::header_key_source
const char * header_key_source
Definition: includes.h:59
struct_opts_1::new_key_source
const char * new_key_source
Definition: libzuluCrypt-exe.h:49
StringsAreEqual
#define StringsAreEqual(x, y)
Definition: zuluSafe.c:46
struct_opts_1::existing_key
const char * existing_key
Definition: libzuluCrypt-exe.h:47
tcrypt_opts::existing_key
const char * existing_key
Definition: add_key.c:30
zuluGetKeys
static int zuluGetKeys(string_t *key1, string_t *key2, string_t *key3)
Definition: add_key.c:199
tcrypt_opts::new_key_is_keyfile
size_t new_key_is_keyfile
Definition: add_key.c:35
StringSize
static __inline__ size_t StringSize(const char *str)
Definition: String.h:846
StringContent
static const __inline__ char * StringContent(string_t st)
Definition: String.h:1011
zuluCryptCreateKeyFile
string_t zuluCryptCreateKeyFile(const char *key, size_t key_len, const char *fileName)
Definition: open_tcrypt.c:125
StringType
Definition: String.c:49
StringsAreEqual_1
int StringsAreEqual_1(string_t x, string_t y)
Definition: String.c:1460
zuluCryptSecurityDropElevatedPrivileges
int zuluCryptSecurityDropElevatedPrivileges(void)
Definition: security.c:109
zuluCryptModifyTcryptHeader
int zuluCryptModifyTcryptHeader(const info_t *info)
Definition: create_tcrypt.c:229
tcrypt
Definition: tcrypt.h:39
zuluCryptVolumeIsLuks
int zuluCryptVolumeIsLuks(const char *device)
Definition: is_luks.c:45
zuluCryptSecurityUnlockMemory
void zuluCryptSecurityUnlockMemory(stringList_t stl)
Definition: security.c:229
struct_opts_1::existing_key_source
const char * existing_key_source
Definition: libzuluCrypt-exe.h:46
tcrypt_opts::new_key
const char * new_key
Definition: add_key.c:33
siritask::status
status
Definition: siritask.h:114
zuluCryptSecurityGainElevatedPrivileges
int zuluCryptSecurityGainElevatedPrivileges(void)
Definition: security.c:64
tcrypt_opts
Definition: add_key.c:27
StringListArray
string_t * StringListArray(stringList_t *stz, size_t arraySize)
Definition: StringList.c:244
zuluCryptEXEAddKey
int zuluCryptEXEAddKey(const struct_opts *opts, uid_t uid)
Definition: add_key.c:244
ZULUCRYPT_KEY_MAX_SIZE
#define ZULUCRYPT_KEY_MAX_SIZE
Definition: constants.h:49
StringListType
Definition: StringList.c:33
info_t::rng
const char * rng
Definition: includes.h:57
veraCryptVolumePIMValue
stringList_t veraCryptVolumePIMValue(info_t *s, const char *type)
Definition: save_and_restore_volume_header.c:411
tcrypt_opts::new_key_size
size_t new_key_size
Definition: add_key.c:34
info_t::header_key
const char * header_key
Definition: includes.h:58
zuluCryptSecurityLockMemory
void zuluCryptSecurityLockMemory(stringList_t stl)
Definition: security.c:210
zuluCryptDeleteFile_1
void zuluCryptDeleteFile_1(string_t st)
Definition: file_path_security.c:83
zuluCryptGetPassFromFile
int zuluCryptGetPassFromFile(int *socket_path, const char *path, uid_t uid, string_t *st)
Definition: path_access.c:121
zuluCryptPartitionIsSystemPartition
int zuluCryptPartitionIsSystemPartition(const char *dev, uid_t uid)
Definition: volumes.c:1143
StringDelete
void StringDelete(string_t *st)
Definition: String.c:162
info_t
Definition: includes.h:51
StringListClearDelete
void StringListClearDelete(stringList_t *stl)
Definition: StringList.c:1216
zuluCryptEmptySlots
char * zuluCryptEmptySlots(const char *device)
Definition: empty_slots.c:86
includes.h
zuluCryptExeOriginalUserIsNotRoot
int zuluCryptExeOriginalUserIsNotRoot()
Definition: security.c:59
StringClearDelete
void StringClearDelete(string_t *st)
Definition: String.c:177
StringFree
static __inline__ void StringFree(const void *str)
Definition: String.h:823
StringVoid
#define StringVoid
Definition: String.h:47