From: <ow...@us...> - 2008-12-29 12:05:21
|
Revision: 2239 http://ipcop.svn.sourceforge.net/ipcop/?rev=2239&view=rev Author: owes Date: 2008-12-29 12:05:10 +0000 (Mon, 29 Dec 2008) Log Message: ----------- Restore (during installation) is now possible from floppy and USB. Modified Paths: -------------- ipcop/trunk/src/installer/restore.c ipcop/trunk/src/misc-progs/ipcoprscfg.c Modified: ipcop/trunk/src/installer/restore.c =================================================================== --- ipcop/trunk/src/installer/restore.c 2008-12-28 23:01:41 UTC (rev 2238) +++ ipcop/trunk/src/installer/restore.c 2008-12-29 12:05:10 UTC (rev 2239) @@ -37,9 +37,14 @@ // tweak for errorbox #define gettext ipcop_gettext -#define TMP_RESTORE_PATH "/tmp/restore" +#define TMP_RESTORE_PATH_FULL "/harddisk/tmp/restore" +#define TMP_RESTORE_PATH_CHROOT "/tmp/restore" +#define MOUNT_BACKUP_FULL "/harddisk/mnt/usb" +#define MOUNT_BACKUP_CHROOT "/mnt/usb" +#define DATFILE "/home/httpd/html/backup/ipcop-xxxx-xx-xx_xx-xx-xx.dat" +static char command[STRING_SIZE]; /* these are module global, to make callback function work */ static newtComponent restoreform; static newtComponent radiofloppy, radiousb, radionetwork; @@ -49,7 +54,7 @@ /* */ static int copy_change_files(void) { - if (access("/harddisk" TMP_RESTORE_PATH "/var/ipcop/main/settings", 0)) { + if (access(TMP_RESTORE_PATH_FULL "/var/ipcop/main/settings", 0)) { errorbox(ipcop_gettext("TR_NO_MAIN_SETTINGS_IN_BACKUP")); return FAILURE; } @@ -57,7 +62,7 @@ /* Let us simply accept everything for now. Will need to add basic version check here. */ - mysystem("/bin/chroot /harddisk /bin/cp -af " TMP_RESTORE_PATH "/. /"); + mysystem("/bin/chroot /harddisk /bin/cp -af " TMP_RESTORE_PATH_CHROOT "/. /"); /* Here we will need to upgrade from 1.4.xx configuration files */ @@ -65,6 +70,56 @@ } +/* Return SUCCESS when dev contains a backup key and backup dat file. + * Leave dev mounted */ +static int test_backup_key(char *dev, char *hostname) +{ + mysystem("/bin/umount " MOUNT_BACKUP_FULL " 2>/dev/null"); + snprintf(command, STRING_SIZE, "/bin/mount -t vfat -o ro %s " MOUNT_BACKUP_FULL, dev); + if (mysystem(command)) { + return FAILURE; /* no mountable dev */ + } + + /* Test backup .key */ + snprintf(command, STRING_SIZE, MOUNT_BACKUP_FULL "/backup.%s.key", hostname); + if (access(command, 0)) { + return FAILURE; /* no backup key on this dev */ + } + /* Test backup .dat */ + snprintf(command, STRING_SIZE, MOUNT_BACKUP_FULL "/%s.dat", hostname); + if (access(command, 0)) { + return FAILURE; /* no backup dat on this dev */ + } + /* */ + snprintf(command, STRING_SIZE, "cp -f " MOUNT_BACKUP_FULL "/%s.dat /harddisk/" DATFILE, hostname); + mysystem(command); + + return SUCCESS; +} + + +/* Try to mount usb device until backup.<hostname>.key is found */ +static int mountusb(char *hostname) +{ + char sourcedev[30]; + int i, j; + + /* TODO: instead of scanning sda, sda1 ... sdz3, sdz4 it is probably better to look at /proc/partitions */ + for (i = 'a'; i <= 'z'; i++) { + for (j = 0; j < 5; j++) { + if (j) { + sprintf(sourcedev, "/dev/sd%c%d", i, j); + } + else { + sprintf(sourcedev, "/dev/sd%c", i); + } + if (test_backup_key(sourcedev, hostname) == SUCCESS) return SUCCESS; + } + } + return FAILURE; +} + + /* Try and grab from /dev/fd0 (1st floppy) USB floppy is /dev/sd[a-z], need some magic to walk through sd devices */ static int restorefromfloppy(void) @@ -88,10 +143,11 @@ lstat(device, &st); if (S_ISBLK(st.st_mode)) { if (mysystem - ("/sbin/chroot /harddisk /bin/tar -X /var/ipcop/backup/exclude.system -C " TMP_RESTORE_PATH + ("/sbin/chroot /harddisk /bin/tar -X /var/ipcop/backup/exclude.system -C " TMP_RESTORE_PATH_CHROOT " -xvzf /dev/fd0") == 0) { newtPopWindow(); // Pop status window - return SUCCESS; + + return copy_change_files(); } } @@ -106,16 +162,46 @@ /* */ -static int restorefromusb(void) +static int restorefromusb(char *hostname, char *password) { + if (mountusb(hostname) == FAILURE) { + newtPopWindow(); + errorbox(ipcop_gettext("TR_NO_BACKUP_ON_USB_FOUND")); + return FAILURE; + } + + /* device is mounted and contains .key and .dat + extract .key first */ + snprintf(command, STRING_SIZE, "/bin/chroot /harddisk /usr/bin/openssl enc" + " -a -d -aes256 -salt" + " -pass pass:%s" + " -in " MOUNT_BACKUP_CHROOT "/backup.%s.key" + " -out /var/ipcop/backup/backup.key", + password, hostname); + if (mysystem(command)) { + newtPopWindow(); + errorbox(ipcop_gettext("TR_WRONG_PASSWORD_OR_KEYFILE")); + return FAILURE; + } + + /* adjust mode */ + mysystem("/bin/chroot /harddisk /bin/chmod 400 /var/ipcop/backup/backup.key"); + + snprintf(command, STRING_SIZE, "/bin/chroot /harddisk /usr/local/bin/ipcoprscfg" + " --restore=%s --hostname=ipcop --hardware", DATFILE); + if (mysystem(command)) { + newtPopWindow(); + errorbox(ipcop_gettext("TR_UNABLE_TO_INSTALL_FILES")); + return FAILURE; + } + newtPopWindow(); // Pop status window - newtWinMessage(ipcop_gettext("TR_RESTORE"), ipcop_gettext("TR_OK"), "Sorry, not implemented yet."); - return FAILURE; + return SUCCESS; } /* */ -static int restorefromnetwork(void) +static int restorefromnetwork(char *hostname) { newtPopWindow(); // Pop status window newtWinMessage(ipcop_gettext("TR_RESTORE"), ipcop_gettext("TR_OK"), "Sorry, not implemented yet."); @@ -147,6 +233,9 @@ newtComponent text; newtComponent ok, skip; newtComponent labelhostname, labelpassword; + char hostnameinitvalue[STRING_SIZE]; + char passwordinitvalue[STRING_SIZE]; + char typevalue[32]; const char *hostnamevalue; const char *passwordvalue; struct newtExitStruct exitstruct; @@ -155,6 +244,8 @@ int error; int userskip; + strcpy(hostnameinitvalue, "ipcop.localdomain"); + strcpy(typevalue, "floppy"); do { snprintf(message, STRING_SIZE, ipcop_gettext("TR_RESTORE_CONFIGURATION"), NAME); @@ -166,14 +257,14 @@ newtFormAddComponent(restoreform, text); /* selections: floppy, usb */ - radiofloppy = newtRadiobutton(12, 2 + numLines, ipcop_gettext("TR_FLOPPY"), 1, NULL); - radiousb = newtRadiobutton(12, 3 + numLines, ipcop_gettext("TR_USB_KEY"), 0, radiofloppy); + radiofloppy = newtRadiobutton(12, 2 + numLines, ipcop_gettext("TR_FLOPPY"), !strcmp(typevalue, "floppy"), NULL); + radiousb = newtRadiobutton(12, 3 + numLines, ipcop_gettext("TR_USB_KEY"), !strcmp(typevalue, "usb"), radiofloppy); newtComponentAddCallback(radiofloppy, restorecallback, NULL); newtComponentAddCallback(radiousb, restorecallback, NULL); if (medium_sources == network) { - radionetwork = newtRadiobutton(12, 4 + numLines, "http/ftp", 0, radiousb); + radionetwork = newtRadiobutton(12, 4 + numLines, "http/ftp", !strcmp(typevalue, "http"), radiousb); newtComponentAddCallback(radionetwork, restorecallback, NULL); newtFormAddComponents(restoreform, radiofloppy, radiousb, radionetwork, NULL); } @@ -187,7 +278,7 @@ labelhostname = newtTextbox(2, 6 + numLines, 35, 1, 0); newtTextboxSetText(labelhostname, ipcop_gettext("TR_HOSTNAME")); newtFormAddComponent(restoreform, labelhostname); - entryhostname = newtEntry(25, 6 + numLines, "ipcop.local", 35, &hostnamevalue, 0); + entryhostname = newtEntry(25, 6 + numLines, hostnameinitvalue, 35, &hostnamevalue, 0); newtFormAddComponent(restoreform, entryhostname); /* password */ labelpassword = newtTextbox(2, 7 + numLines, 35, 1, 0); @@ -196,10 +287,13 @@ entrypassword = newtEntry(25, 7 + numLines, "", 20, &passwordvalue, 0); newtEntrySetFlags(entrypassword, NEWT_FLAG_PASSWORD, NEWT_FLAGS_SET); newtFormAddComponent(restoreform, entrypassword); - /* disabled for default selection */ - newtEntrySetFlags(entryhostname, NEWT_FLAG_DISABLED, NEWT_FLAGS_SET); - newtEntrySetFlags(entrypassword, NEWT_FLAG_DISABLED, NEWT_FLAGS_SET); + if (!strcmp(typevalue, "floppy")) { + /* disabled for default selection */ + newtEntrySetFlags(entryhostname, NEWT_FLAG_DISABLED, NEWT_FLAGS_SET); + newtEntrySetFlags(entrypassword, NEWT_FLAG_DISABLED, NEWT_FLAGS_SET); + } + ok = newtButton(6, 9 + numLines, ipcop_gettext("TR_OK")); skip = newtButton(26, 9 + numLines, gettext("TR_SKIP")); newtFormAddComponents(restoreform, ok, skip, NULL); @@ -207,10 +301,12 @@ newtRefresh(); newtDrawForm(restoreform); - error = 1; + error = FAILURE; userskip = 0; newtFormRun(restoreform, &exitstruct); newtPopWindow(); + strcpy(hostnameinitvalue, (char *)hostnamevalue); + strcpy(passwordinitvalue, (char *)passwordvalue); newtFormDestroy(restoreform); if (exitstruct.u.co == skip) { @@ -222,30 +318,37 @@ statuswindow(72, 5, ipcop_gettext("TR_RESTORE"), ipcop_gettext("TR_READING_BACKUP")); /* cleanout possible leftovers and (re)create temp path */ - mysystem("/bin/rm -rf /harddisk" TMP_RESTORE_PATH); - mkdir("/harddisk" TMP_RESTORE_PATH, S_IRWXU | S_IRWXG | S_IRWXO); + mysystem("/bin/rm -rf " TMP_RESTORE_PATH_FULL); + mkdir(TMP_RESTORE_PATH_FULL, S_IRWXU | S_IRWXG | S_IRWXO); + mysystem("/bin/rm -rf " MOUNT_BACKUP_FULL); + mkdir(MOUNT_BACKUP_FULL, S_IRWXU|S_IRWXG|S_IRWXO); if (selected == radiofloppy) { + strcpy(typevalue, "floppy"); error = restorefromfloppy(); } else if (selected == radiousb) { - error = restorefromusb(); + strcpy(typevalue, "usb"); + if (!strcmp(passwordinitvalue, "")) { + /* password is mandatory to decrypt the key */ + newtPopWindow(); + errorbox(ipcop_gettext("TR_PASSWORD_CANNOT_BE_BLANK")); + error = FAILURE; + } + else { + error = restorefromusb(hostnameinitvalue, passwordinitvalue); + } } else { - error = restorefromnetwork(); + strcpy(typevalue, "http"); + error = restorefromnetwork(hostnameinitvalue); } - - if (error == SUCCESS) { - error = copy_change_files(); - } } } while ((error != SUCCESS) && (userskip == 0)); return (error); - // ipcop_gettext("TR_NO_BACKUP_ON_USB_FOUND") // ipcop_gettext("TR_FILE_NOT_FOUND") - // ipcop_gettext("TR_WRONG_PASSWORD_OR_KEYFILE") // ipcop_gettext("TR_UNABLE_TO_INSTALL_FILES") } Modified: ipcop/trunk/src/misc-progs/ipcoprscfg.c =================================================================== --- ipcop/trunk/src/misc-progs/ipcoprscfg.c 2008-12-28 23:01:41 UTC (rev 2238) +++ ipcop/trunk/src/misc-progs/ipcoprscfg.c 2008-12-29 12:05:10 UTC (rev 2239) @@ -58,6 +58,7 @@ static int flag_hardware = 0; +static int flag_hostname = 0; static int flag_import = 0; static int flag_restore = 0; static char hostname[STRING_SIZE]; @@ -102,16 +103,18 @@ unlink(command); } -static void usage() + +void usage(char *prg, int exit_code) { - fprintf(stderr, "Usage:\n"); - fprintf(stderr, "ipcoprscfg --import\n"); - fprintf(stderr, "\tRename <hostname>.dat to <hostname>.YYYY-MM-DD_HH-MM-SS.dat\n"); - fprintf(stderr, "\tand create corresponding .dat.time file\n"); - fprintf(stderr, "ipcoprscfg --restore file.dat [--hardware]\n"); - fprintf(stderr, "\tRestore a file.dat backup\n"); - fprintf(stderr, "\t--hardware option restore hardware settings\n"); - exit(1); + fprintf(stderr, "Usage: %s [OPTION]\n\n", prg); + fprintf(stderr, "Options:\n"); + fprintf(stderr, " --import rename <hostname>.dat to <hostname>.YYYY-MM-DD_HH-MM-SS.dat\n"); + fprintf(stderr, " --restore=<file.dat> restore from <file.dat> backup\n"); + fprintf(stderr, " --hardware restore hardware settings\n"); + fprintf(stderr, " --hostname force host.domain\n"); + fprintf(stderr, " -v, --verbose be verbose\n"); + fprintf(stderr, " --help display this help and exit\n"); + exit(exit_code); } @@ -127,45 +130,57 @@ static struct option long_options[] = { { "hardware", no_argument, &flag_hardware, 1 }, + { "hostname", required_argument, &flag_hostname, 1 }, { "import", no_argument, &flag_import, 1 }, - { "restore", required_argument, 0, 'r' }, + { "restore", required_argument, &flag_restore, 1}, { "verbose", no_argument, 0, 'v' }, + { "help", no_argument, 0, 'h' }, { 0, 0, 0, 0} }; int c; int option_index = 0; char *opt_filename; - while ((c = getopt_long(argc, argv, "v", long_options, &option_index)) != -1) { + while ((c = getopt_long(argc, argv, "r:v", long_options, &option_index)) != -1) { switch (c) { - case 'r': /* restore */ - opt_filename = strdup(optarg); + case 0: + if (!strcmp("hostname", long_options[option_index].name)) { + strcpy(hostname, optarg); + } + else if (!strcmp("restore", long_options[option_index].name)) { + opt_filename = strdup(optarg); + } break; case 'v': /* verbose */ flag_verbose++; break; + case 'h': + usage(argv[0], 0); default: fprintf(stderr, "unknown option\n"); - usage(argv[0]); - break; + usage(argv[0], 1); } } if (!flag_import && !flag_restore) { /* need at least one of import or restore */ - usage(); + usage(argv[0], 1); } /* Init setuid */ if (!(initsetuid())) exit(ERR_SUID); - gethostname(hostname, STRING_SIZE - 1); + if (!flag_hostname) { + gethostname(hostname, STRING_SIZE - 1); + } if (flag_restore) { /* check filename valid, full file name length */ if (strlen(opt_filename) != (strlen(MOUNTPOINT "/-YYYY-MM-DD_HH-MM-SS.dat")+ strlen(hostname))) { fprintf(stderr, "ipcoprscfg : bad file name\n"); + fprintf(stderr, "%s\n", hostname); + fprintf(stderr, "%s\n", opt_filename); exit(ERR_FILENAME); } /* file in the path */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |