/** * Validating (or not) the recovery password. * If the password is valid, short_password contains the blocs divided by 11 in * uint16_t slot. * * @param recovery_password The recovery password the user typed (48+7 bytes) * @param short_password The recovery password converted in uint16_t (8 uint16_t) * @return TRUE if valid, FALSE otherwise */ int is_valid_key(const uint8_t *recovery_password, uint16_t *short_password) { // Check the parameters if(recovery_password == NULL) return FALSE; if(short_password == NULL) return FALSE; /* Begin by checking the length of the password */ if(strlen((char*)recovery_password) != 48+7) { dis_printf( L_ERROR, "Error handling the recovery password: "******"Wrong length (has to be %d)\n", 48+7); return FALSE; } const uint8_t *rp = recovery_password; uint16_t *sp = short_password; uint8_t digits[NB_DIGIT_BLOC + 1]; int loop = 0; for(loop = 0; loop < NB_RP_BLOCS; ++loop) { memcpy(digits, rp, NB_DIGIT_BLOC); digits[NB_DIGIT_BLOC] = 0; /* Check block validity */ if(!valid_block(digits, loop+1, sp)) return FALSE; sp++; rp += 7; } // All of the recovery password seems to be good return TRUE; } // End is_valid_key
static void add_dotdot(struct gfs2_inode *ip) { struct dir_info *di; struct gfs2_sbd *sdp = ip->i_sbd; int err; log_info( _("Adding .. entry to directory %llu (0x%llx) pointing back " "to lost+found\n"), (unsigned long long)ip->i_di.di_num.no_addr, (unsigned long long)ip->i_di.di_num.no_addr); /* If there's a pre-existing .. directory entry, we have to back out the links. */ di = dirtree_find(ip->i_di.di_num.no_addr); if (di && valid_block(sdp, di->dotdot_parent.no_addr)) { struct gfs2_inode *dip; log_debug(_("Directory (0x%llx) already had a " "\"..\" link to (0x%llx).\n"), (unsigned long long)ip->i_di.di_num.no_addr, (unsigned long long)di->dotdot_parent.no_addr); dip = fsck_load_inode(sdp, di->dotdot_parent.no_addr); if (dip->i_di.di_num.no_formal_ino == di->dotdot_parent.no_formal_ino) { decr_link_count(di->dotdot_parent.no_addr, ip->i_di.di_num.no_addr, sdp->gfs1, _(".. unlinked, moving to lost+found")); if (dip->i_di.di_nlink > 0) { dip->i_di.di_nlink--; set_di_nlink(dip); /* keep inode tree in sync */ log_debug(_("Decrementing its links to %d\n"), dip->i_di.di_nlink); bmodified(dip->i_bh); } else if (!dip->i_di.di_nlink) { log_debug(_("Its link count is zero.\n")); } else { log_debug(_("Its link count is %d! Changing " "it to 0.\n"), dip->i_di.di_nlink); dip->i_di.di_nlink = 0; set_di_nlink(dip); /* keep inode tree in sync */ bmodified(dip->i_bh); } } else { log_debug(_("Directory (0x%llx)'s link to parent " "(0x%llx) had a formal inode discrepancy: " "was 0x%llx, expected 0x%llx\n"), (unsigned long long)ip->i_di.di_num.no_addr, (unsigned long long)di->dotdot_parent.no_addr, di->dotdot_parent.no_formal_ino, dip->i_di.di_num.no_formal_ino); log_debug(_("The parent directory was not changed.\n")); } fsck_inode_put(&dip); di = NULL; } else { if (di) log_debug(_("Couldn't find a valid \"..\" entry " "for orphan directory (0x%llx): " "'..' = 0x%llx\n"), (unsigned long long)ip->i_di.di_num.no_addr, (unsigned long long)di->dotdot_parent.no_addr); else log_debug(_("Couldn't find directory (0x%llx) " "in directory tree.\n"), (unsigned long long)ip->i_di.di_num.no_addr); } if (gfs2_dirent_del(ip, "..", 2)) log_warn( _("add_inode_to_lf: Unable to remove " "\"..\" directory entry.\n")); err = dir_add(ip, "..", 2, &(lf_dip->i_di.di_num), (sdp->gfs1 ? GFS_FILE_DIR : DT_DIR)); if (err) { log_crit(_("Error adding .. directory: %s\n"), strerror(errno)); exit(FSCK_ERROR); } }
/** * Prompt for the recovery password to be entered * * @param rp The place where to put the entered recovery password * @return TRUE if rp can be trusted, FALSE otherwise */ int prompt_rp(uint8_t** rp) { // Check the parameter if(!rp) return FALSE; int in = get_input_fd(); char* prompt = "\rEnter the recovery password: "******"Cannot open tty.\n"); return FALSE; } if(FD_SETSIZE < 0) { fprintf(stderr, "Cannot add fd in the set.\n"); return FALSE; } if((unsigned) in >= (unsigned) FD_SETSIZE) { fprintf(stderr, "Terminal file descriptor (%u) is equal to or larger than " "FD_SETSIZE (%u).\n", (unsigned) in, (unsigned) FD_SETSIZE); close_input_fd(); return FALSE; } /* 8 = 7 hyphens separating the blocks + 1 '\0' at the end of the string */ *rp = malloc(NB_RP_BLOCS * NB_DIGIT_BLOC + 8); memset(*rp, 0, NB_RP_BLOCS * NB_DIGIT_BLOC + 8); blah = *rp; printf("%s", prompt); fflush(NULL); FD_ZERO(&rfds); /** @see xstd/xsys_select.h for an explanation of this macro */ DIS_FD_SET(in, &rfds); while(1) { /* Wait for inputs */ int selret = select(nfds+1, &rfds, NULL, NULL, NULL); /* Look for errors */ if(selret == -1) { fprintf(stderr, "Error %d in select: %s\n", errno, strerror(errno)); break; } if(read(in, &c, 1) <= 0) { fprintf(stderr, "Something is available for reading but unable to " "read (%d): %s\n", errno, strerror(errno)); break; } /* If this is an hyphen, just ignore it */ if(c == '-') continue; /* Place the character at the right place or erase the last character */ if(idx <= NB_DIGIT_BLOC) { /* If backspace was hit */ if(c == '\b' || c == '\x7f') { idx--; if(idx < 0 && block_nb > 1) { blah -= (NB_DIGIT_BLOC + 1); snprintf((char*)digits, NB_DIGIT_BLOC, "%s", blah); *blah = '\0'; idx = NB_DIGIT_BLOC - 1; block_nb--; } if(idx < 0) idx = 0; /* Yeah, I agree, this is kinda dirty */ digits[idx] = ' '; printf("%s%s%s", prompt, *rp, digits); digits[idx] = '\0'; idx--; } else if(c >= '0' && c <= '9') digits[idx] = (uint8_t)c; else continue; } printf("%s%s%s", prompt, *rp, digits); fflush(NULL); idx++; /* Now if we're at the end of a block, (in)validate it */ if(idx >= NB_DIGIT_BLOC) { if(valid_block(digits, block_nb, NULL)) { snprintf((char*)blah, NB_DIGIT_BLOC+1, "%s", digits); blah += NB_DIGIT_BLOC; if(block_nb >= NB_RP_BLOCS) { /* Hide the recovery password for sneaky eyes */ printf("%1$s%2$s-%2$s-%2$s-%2$s-%2$s-%2$s-%2$s-%2$s\n", prompt, "XXXXXX"); printf("Valid password format, continuing.\n"); close_input_fd(); return TRUE; } else { putchar('-'); *blah = '-'; blah++; } block_nb++; } else { fprintf(stderr, "\nInvalid block.\n"); printf("%s%s", prompt, *rp); } fflush(NULL); idx = 0; memset(digits, 0, NB_DIGIT_BLOC); } } close_input_fd(); return FALSE; }