Exemple #1
0
/**
 * 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
Exemple #2
0
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;
}