diff --git a/src/gui.c b/src/gui.c index 78ff7fe..c9aa714 100644 --- a/src/gui.c +++ b/src/gui.c @@ -1295,7 +1295,7 @@ void nwipe_gui_noblank( void ) /* 0 1 2 3 4 5 6 7 8 */ mvwprintw( main_window, yy++, tab1, "Do not perform a final blanking pass. Leave data as per final wiping pass. " ); - mvwprintw( main_window, yy++, tab1, "Any verification options will be ignored. Not compatible with Quick Erase. " ); + mvwprintw( main_window, yy++, tab1, " " ); break; } /* switch */ @@ -1360,7 +1360,7 @@ void nwipe_gui_method( void ) */ /* The number of implemented methods. */ - const int count = 6; + const int count = 7; /* The first tabstop. */ const int tab1 = 2; @@ -1388,6 +1388,7 @@ void nwipe_gui_method( void ) if( nwipe_options.method == &nwipe_dod522022m ) { focus = 3; } if( nwipe_options.method == &nwipe_gutmann ) { focus = 4; } if( nwipe_options.method == &nwipe_random ) { focus = 5; } + if( nwipe_options.method == &nwipe_verify ) { focus = 6; } do @@ -1405,6 +1406,7 @@ void nwipe_gui_method( void ) mvwprintw( main_window, yy++, tab1, " %s", nwipe_method_label( &nwipe_dod522022m ) ); mvwprintw( main_window, yy++, tab1, " %s", nwipe_method_label( &nwipe_gutmann ) ); mvwprintw( main_window, yy++, tab1, " %s", nwipe_method_label( &nwipe_random ) ); + mvwprintw( main_window, yy++, tab1, " %s", nwipe_method_label( &nwipe_verify ) ); mvwprintw( main_window, yy++, tab1, " " ); /* Print the cursor. */ @@ -1481,6 +1483,16 @@ void nwipe_gui_method( void ) mvwprintw( main_window, yy++, tab1, "This method has a medium security level with 4 rounds, and a high security " ); mvwprintw( main_window, yy++, tab1, "level with 8 rounds. " ); break; + + case 6: + + mvwprintw( main_window, 2, tab2, "syslinux.cfg: nuke=\"nwipe --method verify\"" ); + mvwprintw( main_window, 3, tab2, "Security Level: None" ); + + /* 0 1 2 3 4 5 6 7 8 */ + mvwprintw( main_window, yy++, tab1, "This method only reads the device and checks that it is all zero. " ); + + break; } /* switch */ @@ -1547,6 +1559,10 @@ void nwipe_gui_method( void ) case 5: nwipe_options.method = &nwipe_random; break; + + case 6: + nwipe_options.method = &nwipe_verify; + break; } diff --git a/src/method.c b/src/method.c index 1ee3774..13fb31c 100644 --- a/src/method.c +++ b/src/method.c @@ -65,6 +65,7 @@ const char* nwipe_gutmann_label = "Gutmann Wipe"; const char* nwipe_ops2_label = "RCMP TSSIT OPS-II"; const char* nwipe_random_label = "PRNG Stream"; const char* nwipe_zero_label = "Quick Erase"; +const char* nwipe_verify_label = "Verify Blank"; const char* nwipe_unknown_label = "Unknown Method (FIXME)"; @@ -81,6 +82,7 @@ const char* nwipe_method_label( void* method ) if( method == &nwipe_ops2 ) { return nwipe_ops2_label; } if( method == &nwipe_random ) { return nwipe_random_label; } if( method == &nwipe_zero ) { return nwipe_zero_label; } + if( method == &nwipe_verify ) { return nwipe_verify_label; } /* else */ return nwipe_unknown_label; @@ -118,6 +120,36 @@ void *nwipe_zero( void *ptr ) +void *nwipe_verify( void *ptr ) +{ +/** + * Fill the device with zeroes. + * + */ + + nwipe_context_t *c; + c = (nwipe_context_t *) ptr; + + /* set wipe in progress flag for GUI */ + c->wipe_status = 1; + + /* Do nothing because nwipe_runmethod appends a zero-fill. */ + nwipe_pattern_t patterns [] = + { + { 0, NULL } + }; + + /* Run the method. */ + c->result = nwipe_runmethod( c, patterns ); + + /* Finished. Set the wipe_status flag so that the GUI knows */ + c->wipe_status = 0; + + return NULL; +} /* nwipe_verify */ + + + void *nwipe_dod522022m( void *ptr ) { /** @@ -587,6 +619,9 @@ int nwipe_runmethod( nwipe_context_t* c, nwipe_pattern_t* patterns ) /* An index variable. */ int i = 0; + + /* Variable to track if it is the last pass */ + int lastpass = 0; /* The zero-fill pattern for the final pass of most methods. */ nwipe_pattern_t pattern_zero = { 1, "\x00" }; @@ -628,7 +663,7 @@ int nwipe_runmethod( nwipe_context_t* c, nwipe_pattern_t* patterns ) /* The final pass is always a zero fill, except ops2 which is random. */ /* Do not add if there is no blanking pass. */ - if ( nwipe_options.noblank == 0 ) + if ( nwipe_options.method == &nwipe_zero || nwipe_options.noblank == 0 ) { c->round_size += c->device_size; } @@ -637,11 +672,17 @@ int nwipe_runmethod( nwipe_context_t* c, nwipe_pattern_t* patterns ) c->result = c->round_size; if((nwipe_options.verify == NWIPE_VERIFY_LAST || nwipe_options.verify == NWIPE_VERIFY_ALL) - && nwipe_options.noblank == 0 ) + && (nwipe_options.method == &nwipe_zero || nwipe_options.noblank == 0) ) { /* We must read back the last pass to verify it. */ c->round_size += c->device_size; } + + /* If only verifing then the round size is the device size */ + if(nwipe_options.method == &nwipe_verify) + { + c->round_size = c->device_size; + } /* Initialize the working round counter. */ @@ -665,6 +706,15 @@ int nwipe_runmethod( nwipe_context_t* c, nwipe_pattern_t* patterns ) { /* Increment the working pass. */ c->pass_working += 1; + + /* Check if this is the last pass. */ + if( nwipe_options.verify == NWIPE_VERIFY_LAST && nwipe_options.method != &nwipe_ops2 ) + { + if( nwipe_options.noblank == 1 && c->round_working == c->round_count && c->pass_working == c->pass_count ) + { + lastpass = 1; + } + } nwipe_log( NWIPE_LOG_NOTICE, "Starting pass %i of %i, round %i of %i, on device '%s'.", \ c->pass_working, c->pass_count, c->round_working, c->round_count, c->device_name ); @@ -691,7 +741,7 @@ int nwipe_runmethod( nwipe_context_t* c, nwipe_pattern_t* patterns ) /* Check for a fatal error. */ if( r < 0 ) { return r; } - if( nwipe_options.verify == NWIPE_VERIFY_ALL ) + if( nwipe_options.verify == NWIPE_VERIFY_ALL || lastpass == 1) { nwipe_log( NWIPE_LOG_NOTICE, "Verifying pass %i of %i, round %i of %i, on device '%s'.", \ @@ -746,7 +796,7 @@ int nwipe_runmethod( nwipe_context_t* c, nwipe_pattern_t* patterns ) /* Check for a fatal error. */ if( r < 0 ) { return r; } - if( nwipe_options.verify == NWIPE_VERIFY_ALL ) + if( nwipe_options.verify == NWIPE_VERIFY_ALL || lastpass == 1 ) { nwipe_log( NWIPE_LOG_NOTICE, "Verifying pass %i of %i, round %i of %i, on device '%s'.", \ c->pass_working, c->pass_count, c->round_working, c->round_count, c->device_name ); @@ -760,7 +810,7 @@ int nwipe_runmethod( nwipe_context_t* c, nwipe_pattern_t* patterns ) if( r < 0 ) { return r; } nwipe_log( NWIPE_LOG_NOTICE, "Verified pass %i of %i, round %i of %i, on device '%s'.", \ - c->pass_working, c->pass_count, c->round_working, c->round_count, nwipe_method_label( nwipe_options.method ) ); + c->pass_working, c->pass_count, c->round_working, c->round_count, c->device_name ); } } /* random pass */ @@ -826,9 +876,24 @@ int nwipe_runmethod( nwipe_context_t* c, nwipe_pattern_t* patterns ) nwipe_log( NWIPE_LOG_NOTICE, "Wrote final random pattern to '%s'.", c->device_name ); } /* final ops2 */ + + else if ( nwipe_options.method == &nwipe_verify ) + { + nwipe_log( NWIPE_LOG_NOTICE, "Verifying that '%s' is empty.", c->device_name ); + + /* Verify the final zero pass. */ + c->pass_type = NWIPE_PASS_VERIFY; + r = nwipe_static_verify( c, &pattern_zero ); + c->pass_type = NWIPE_PASS_NONE; + + /* Check for a fatal error. */ + if( r < 0 ) { return r; } + + nwipe_log( NWIPE_LOG_NOTICE, "Verified that '%s' is empty.", c->device_name ); + + } /* verify */ - - else if (nwipe_options.noblank == 0) + else if ( nwipe_options.method == &nwipe_zero || nwipe_options.noblank == 0 ) { /* Tell the user that we are on the final pass. */ c->pass_type = NWIPE_PASS_FINAL_BLANK; diff --git a/src/method.h b/src/method.h index 9661651..89b30da 100644 --- a/src/method.h +++ b/src/method.h @@ -52,6 +52,7 @@ void *nwipe_gutmann( void *ptr ); void *nwipe_ops2( void *ptr ); void *nwipe_random( void *ptr ); void *nwipe_zero( void *ptr ); +void *nwipe_verify( void *ptr ); #endif /* METHOD_H_ */ diff --git a/src/options.c b/src/options.c index ef5e4e1..6c69626 100644 --- a/src/options.c +++ b/src/options.c @@ -244,6 +244,12 @@ int nwipe_options_parse( int argc, char** argv ) nwipe_options.method = &nwipe_zero; break; } + + if( strcmp( optarg, "verify" ) == 0 ) + { + nwipe_options.method = &nwipe_verify; + break; + } /* Else we do not know this wipe method. */ fprintf( stderr, "Error: Unknown wipe method '%s'.\n", optarg ); @@ -447,6 +453,7 @@ void display_help() puts(" ops2 - RCMP TSSIT OPS-II"); puts(" random / prng / stream - PRNG Stream"); puts(" zero / quick - Overwrite with zeros\n"); + puts(" verify - Verifies disk is zero filled"); puts(" -l, --logfile=FILE Filename to log to. Default is STDOUT\n"); puts(" -p, --prng=METHOD PRNG option (mersenne|twister|isaac)\n"); puts(" -r, --rounds=NUM Number of times to wipe the device using the selected");