File: write_device_with_junk.c

package info (click to toggle)
zulucrypt 5.4.0-3
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 7,596 kB
  • sloc: cpp: 25,623; ansic: 23,788; makefile: 24; xml: 10; sh: 2
file content (355 lines) | stat: -rw-r--r-- 10,850 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355

/*
 *
 *  Copyright (c) 2012-2015
 *  name : Francis Banyikwa
 *  email: mhogomchungu@gmail.com
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "includes.h"
#include "../lib/includes.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <blkid/blkid.h>
#include <libintl.h>
#include <locale.h>
#include <stdio.h>
#include <sys/stat.h>

#include <libcryptsetup.h>

#define SIZE 1024
#define KEY_SIZE 128

#include <signal.h>

#define _ignore_result( x ) if( x ){;}

static int __exit_as_requested ;
static int __sig_caught ;

void sigTERMhandler( int sig )
{
	__exit_as_requested = 1 ;
	__sig_caught = sig ;
	printf( "\nINFO: caught signal %d,cleaning up\n",__sig_caught ) ;
}

/*
 * define in partition.c
 *
 * the function is used to check is a presented path is a system partition or not *
 */

static int zuluExit( stringList_t stl, int status )
{
	ssize_t index ;
	switch( status ){
		case 0 : printf( gettext( "SUCCESS: Mapper created successfully\n" ) ) ;
			 index = StringListHasStartSequence( stl,crypt_get_dir() ) ;
			 if( index >= 0 ){
				 printf( gettext( "Opened mapper path: " ) ) ;
				 StringListPrintLineAt( stl,index ) ;
			 }
			 break ;
		case 1 : printf( gettext( "ERROR: Could not create mapper\n" ) )					;break ;
		case 2 : printf( gettext( "ERROR: Could not resolve device path\n" ) )					;break ;
		case 3 : printf( gettext( "\nSUCCESS: Random data successfully written\n" ) )				;break ;
		case 5 : printf( gettext( "INFO: User chose not to proceed\n" ) ) 					;break ;
		case 8 : printf( gettext( "ERROR: Insufficitied privilege to oped device \n" ) ) 			;break ;
		case 9 : printf( gettext( "ERROR: Device path is invalid\n" ) )						;break ;
		case 10: printf( gettext( "ERROR: Passphrase file does not exist\n" ) ) 				;break ;
		case 11: printf( gettext( "ERROR: Could not get enough memory to hold the key file\n" ) ) 	 	;break ;
		case 12: printf( gettext( "ERROR: Insufficient privilege to open key file for reading\n" ) )	       	;break ;
		case 13: printf( gettext( "ERROR: Can not open a mapper on a device with an opened mapper\n" ) )	;break ;
		case 14: printf( gettext( "ERROR: Can not open a mapper on a mounted device\n" ) ) 			;break ;
		case 15: printf( gettext( "INFO: Signal caught,exiting prematurely\n" ) )				;break ;
		case 16: printf( gettext( "ERROR: Can not get passphrase in silent mode\n" ) )				;break ;
		case 17: printf( gettext( "ERROR: Insufficient memory to hold passphrase\n" ) ) 			;break ;
		case 18: printf( gettext( "ERROR: Insufficient memory to hold 3 characters?really?\n" ) ) 		;break ;
		case 19: printf( gettext( "ERROR: Insufficient privilege to open the file with your privileges?\n" ) )  ;break ;
	}

	StringListClearDelete( &stl ) ;
	return status ;
}

static int open_plain_as_me_1(const struct_opts * opts,const char * mapping_name,uid_t uid,int op )
{
	/*
	 * Below is a form of memory management.All strings are collected in a stringlist object to easily delete them
	 * when the function returns.This allows for the function to have multiple exit points without risks of leaking
	 * memory from manually examining each exit point to make sure all strings are deleted or go with multiple goto
	 * code deleting blocks to take into account different exit points.
	 */
	stringList_t stl ;
	string_t * stringArray  = StringListArray( &stl,5 ) ;
	string_t * mapper     = &stringArray[ 0 ] ;
	string_t * passphrase = &stringArray[ 1 ] ;
	string_t * p          = &stringArray[ 2 ] ;
	string_t * dev_st     = &stringArray[ 3 ] ;
	string_t * dev_1      = &stringArray[ 4 ] ;

	size_t len = 0 ;

	const char * source      = opts->key_source ;
	const char * pass        = opts->key ;

	int k = opts->ask_confirmation ;

	const char * cpass = NULL ;

	char * d ;

	const char * device = opts->device ;
	const char * dev = opts->device ;

	int j ;
	int n ;

	const char * cmapper ;

	if( StringPrefixEqual( device,"/dev/loop" ) ){
		/*
		 * zuluCryptLoopDeviceAddress() is defined in ../lib/create_loop_device.c
		 */
		d = zuluCryptLoopDeviceAddress( device ) ;
		*dev_st = StringInherit( &d ) ;
		dev = StringContent( *dev_st ) ;
		*dev_1 = StringCopy( *dev_st ) ;
		device = StringReplaceString( * dev_1,"\\040"," " ) ;
	}

	/*
	 * zuluCryptPartitionIsSystemPartition() is defined in ./partition.c
	 */
	if( zuluCryptPartitionIsSystemPartition( device,uid ) ){

		if( zuluCryptExeOriginalUserIsNotRoot() ){

			if( uid != 0 ){

				return zuluExit( stl,8 ) ;
			}
		}
	}
	/*
	 * ZULUCRYPTlongMapperPath and ZULUCRYPTshortMapperPath are in ../constants.h
	 * zuluCryptCreateMapperName() is defined at ../lib/create_mapper_name.c
	 */
	*mapper = zuluCryptCreateMapperName( device,mapping_name,uid,ZULUCRYPTshortMapperPath ) ;

	*p = zuluCryptCreateMapperName( device,mapping_name,uid,ZULUCRYPTlongMapperPath ) ;

	j = zuluCryptCheckOpenedMapper( StringContent( *p ) ) ;

	/*
	 * zuluCryptPartitionIsMounted() is defined in ../lib/process_mountinfo.c
	 */
	n = zuluCryptPartitionIsMounted( dev ) ;

	if( j == 1 ){
		return zuluExit( stl,13 ) ;
	}
	if( n == 1 ){
		return zuluExit( stl,14 ) ;
	}
	if( k == 0 ){
		*passphrase = StringRandomString( 64 ) ;
		cpass = StringContent( *passphrase ) ;
		len = StringLength( *passphrase ) ;
	}else if( source == NULL ){
		printf( gettext( "Enter passphrase: " ) ) ;
		/*
		 * ZULUCRYPT_KEY_MAX_SIZE is set in ../constants.h
		 */
		switch( StringSilentlyGetFromTerminal_1( passphrase,ZULUCRYPT_KEY_MAX_SIZE ) ){
			case 1 : return zuluExit( stl,16 ) ;
			case 2 : return zuluExit( stl,17 ) ;
		}
		printf( "\n" ) ;
		cpass = StringContent( *passphrase ) ;
		len = StringLength( *passphrase ) ;
	}else{
		if( strcmp( source,"-p" ) == 0 ){
			*passphrase = String( pass ) ;
			cpass = StringContent( *passphrase ) ;
			len = StringLength( *passphrase ) ;
		}else if( strcmp( source,"-f" ) == 0 ){
			/*
			 * zuluCryptGetPassFromFile() is defined at "path_access.c"
			 */
			switch( zuluCryptGetPassFromFile( NULL,pass,uid,passphrase ) ){
				case 1 : return zuluExit( stl,10 ) ;
				case 2 : return zuluExit( stl,11 ) ;
				case 4 : return zuluExit( stl,12 ) ;
			}
			cpass = StringContent( *passphrase ) ;
			len = StringLength( *passphrase ) ;
		}
	}

	if( zuluCryptSecurityGainElevatedPrivileges() ){
		/*
		 * zuluCryptOpenPlain() is defined in ../lib/open_plain.c
		 */
		if( zuluCryptOpenPlain( device,StringContent( *mapper ),"rw",cpass,len ) != 0 ){
			zuluCryptSecurityDropElevatedPrivileges() ;
			return zuluExit( stl,1 ) ;
		}
	}

	zuluCryptSecurityDropElevatedPrivileges() ;

	/*
	 * Create a mapper path(usually at /dev/mapper) associated with opened plain mapper above.
	 */
	cmapper = StringMultiplePrepend( *mapper,"/",crypt_get_dir(),NULL ) ;

	/*
	 *  mapper path is usually a soft link to /dev/dm-X
	 *  resolve the mapper path to its respective /dev/dm-X and set permission on it.
	 *
	 * We set permission of /dev/dm-X pointing to the device to "u+rw" because we want notmal user to be able
	 * to write to the device through the mapper.
	 *
	 * Useful when a normal user want to delete content of the device by writing random data to it.
	 */
	d = zuluCryptRealPath( cmapper ) ;
	if( zuluCryptSecurityGainElevatedPrivileges() ){
		if( d != NULL ){
			_ignore_result( chown( d,uid,0 ) ) ;
			_ignore_result( chmod( d,S_IRWXU ) ) ;
			StringFree( d ) ;
		}
		zuluCryptSecurityDropElevatedPrivileges() ;
	}else{
		return zuluExit( stl,1 ) ;
	}

	if( op == 1 ){
		return zuluExit( stl,0 ) ;
	}else{
		StringListClearDelete( &stl ) ;
		return 0 ;
	}
}

int zuluCryptEXEOpenPlainAsMe(const struct_opts * opts,const char * mapping_name,uid_t uid )
{
	return open_plain_as_me_1( opts,mapping_name,uid,1 ) ;
}

/*
 * Purpose of this function is to open a device and write random data to it as a way of hiding information on the disk.
 *
 * The above is accomplished by opening a plain mapper against the device and then write to the device through the mapper
 *
 */
int zuluCryptEXEWriteDeviceWithJunk( const struct_opts * opts,const char * mapping_name,uid_t uid )
{
	stringList_t stl   = StringListInit() ;
	string_t * mapper  = StringListAssign( stl ) ;
	string_t * confirm = StringListAssign( stl );

	double size ;
	double size_written ;

	const char * device =  opts->device ;

	char buffer[ SIZE ] ;

	int ratio ;
	int prev_ratio ;
	int k ;

	struct sigaction sigac;

	memset( &sigac,'\0',sizeof( struct sigaction ) ) ;

	sigac.sa_handler = &sigTERMhandler ;

	sigaction( SIGINT,&sigac,NULL ) ;
	sigaction( SIGTERM,&sigac,NULL ) ;
	sigaction( SIGHUP,&sigac,NULL ) ;

	__exit_as_requested = 0 ;

	if( ( k = open_plain_as_me_1( opts,mapping_name,uid,0 ) ) != 0 ){
		return k ;
	}
	*mapper = zuluCryptCreateMapperName( device,mapping_name,uid,ZULUCRYPTshortMapperPath ) ;

	StringMultiplePrepend( *mapper,"/",crypt_get_dir(),NULL ) ;

	if( opts->ask_confirmation ){
		printf( gettext( "\nWARNING, device \"%s\" will be overwritten with random data destroying all present data.\n" ),device ) ;
		printf( gettext( "Are you sure you want to proceed? Type \"YES\" and press enter if you are sure: " ) ) ;

		*confirm = StringGetFromTerminal_1( 3 ) ;
		if( *confirm == StringVoid ){
			return zuluExit( stl,17 ) ;
		}else{
			k = StringsAreEqual_2( *confirm,gettext( "YES" ) ) ;

			if( k == 0 ){
				if( zuluCryptSecurityGainElevatedPrivileges() ){
					zuluCryptCloseMapper( StringContent( *mapper ) ) ;
					zuluCryptSecurityDropElevatedPrivileges() ;
				}
				return zuluExit( stl,5 ) ;
			}
		}
	}

	k = open( StringContent( *mapper ),O_WRONLY ) ;

	size = ( double ) blkid_get_dev_size( k ) ;

	memset( buffer,0,SIZE ) ;

	size_written = 0 ;
	prev_ratio = -1 ;

	while( write( k,buffer,SIZE ) > 0 ){

		if( __exit_as_requested == 1 ){
			break ;
		}
		size_written += SIZE ;

		ratio = ( int ) ( ( size_written / size ) * 100 ) ;

		if( ratio > prev_ratio ){
			printf( "\r%s %d%%",gettext( "percentage complete: " ),ratio ) ;
			fflush( stdout );
			prev_ratio = ratio ;
		}
	}

	close( k ) ;
	if( zuluCryptSecurityGainElevatedPrivileges() ){
		zuluCryptCloseMapper( StringContent( *mapper ) ) ;
		zuluCryptSecurityDropElevatedPrivileges() ;
	}

	if( __exit_as_requested == 1 ){
		return zuluExit( stl,15 ) ;
	}else{
		return zuluExit( stl,3 ) ;
	}
}