Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 201295
Collapse All | Expand All

(-)cryptsetup-1.0.5/lib/setup.c (-84 / +98 lines)
Lines 167-269 Link Here
167
	int newline_stop;
167
	int newline_stop;
168
	int read_horizon;
168
	int read_horizon;
169
	
169
	
170
	if(options->key_file && !strcmp(options->key_file, "-")) {
170
	if(options->passphrase) {
171
		/* Allow binary reading from stdin */
171
		if(strlen(options->passphrase) > 512)
172
		fd = options->passphrase_fd;
172
		{
173
		newline_stop = 0;
173
			set_error("Passphrase size exceeds memory limits");
174
		read_horizon = 0;
175
	} else if (options->key_file) {
176
		fd = open(options->key_file, O_RDONLY);
177
		if (fd < 0) {
178
			char buf[128];
179
			set_error("Error opening key file: %s",
180
				  strerror_r(errno, buf, 128));
181
			goto out_err;
174
			goto out_err;
182
		}
175
		}
183
		newline_stop = 0;
184
185
		/* This can either be 0 (LUKS) or the actually number
186
		 * of key bytes (default or passed by -s) */
187
		read_horizon = options->key_size;
188
	} else {
189
		fd = options->passphrase_fd;
190
		newline_stop = 1;
191
		read_horizon = 0;   /* Infinite, if read from terminal or fd */
192
	}	
193
194
	/* Interactive case */
195
	if(isatty(fd)) {
196
		int i;
197
198
		pass = safe_alloc(512);
176
		pass = safe_alloc(512);
199
		if (!pass || (i = interactive_pass(prompt, pass, 512, options->timeout))) {
177
		strcpy(pass, options->passphrase);
200
			set_error("Error reading passphrase");
178
		*key = pass;
201
			goto out_err;
179
		*passLen = strlen(pass);
202
		}
180
	}
203
		if (verify || verify_if_possible) {
181
	else {
204
			char pass_verify[512];
182
		if(options->key_file && !strcmp(options->key_file, "-")) {
205
			i = interactive_pass("Verify passphrase: ", pass_verify, sizeof(pass_verify), options->timeout);
183
			/* Allow binary reading from stdin */
206
			if (i || strcmp(pass, pass_verify) != 0) {
184
			fd = options->passphrase_fd;
207
				set_error("Passphrases do not match");
185
			newline_stop = 0;
186
			read_horizon = 0;
187
		} else if (options->key_file) {
188
			fd = open(options->key_file, O_RDONLY);
189
			if (fd < 0) {
190
				char buf[128];
191
				set_error("Error opening key file: %s",
192
					  strerror_r(errno, buf, 128));
208
				goto out_err;
193
				goto out_err;
209
			}
194
			}
210
			memset(pass_verify, 0, sizeof(pass_verify));
195
			newline_stop = 0;
211
		}
196
	
212
		*passLen = strlen(pass);
197
			/* This can either be 0 (LUKS) or the actually number
213
		*key = pass;
198
			 * of key bytes (default or passed by -s) */
214
	} else {
199
			read_horizon = options->key_size;
215
		/* 
200
		} else {
216
		 * This is either a fd-input or a file, in neither case we can verify the input,
201
			fd = options->passphrase_fd;
217
		 * however we don't stop on new lines if it's a binary file.
202
			newline_stop = 1;
218
		 */
203
			read_horizon = 0;   /* Infinite, if read from terminal or fd */
219
		int buflen, i;
204
		}	
220
205
	
221
		if(verify) {
206
		/* Interactive case */
222
			set_error("Can't do passphrase verification on non-tty inputs");
207
		if(isatty(fd)) {
223
			goto out_err;
208
			int i;
224
		}
209
	
225
		/* The following for control loop does an exhausting
210
			pass = safe_alloc(512);
226
		 * read on the key material file, if requested with
211
			if (!pass || (i = interactive_pass(prompt, pass, 512, options->timeout))) {
227
		 * key_size == 0, as it's done by LUKS. However, we
212
				set_error("Error reading passphrase");
228
		 * should warn the user, if it's a non-regular file,
229
		 * such as /dev/random, because in this case, the loop
230
		 * will read forever.
231
		 */ 
232
		if(options->key_file && strcmp(options->key_file, "-") && read_horizon == 0) {
233
			struct stat st;
234
			if(stat(options->key_file, &st) < 0) {
235
		 		set_error("Can't stat key file");
236
				goto out_err;
213
				goto out_err;
237
			}
214
			}
238
			if(!S_ISREG(st.st_mode)) {
215
			if (verify || verify_if_possible) {
239
				//		 		set_error("Can't do exhausting read on non regular files");
216
				char pass_verify[512];
240
				// goto out_err;
217
				i = interactive_pass("Verify passphrase: ", pass_verify, sizeof(pass_verify), options->timeout);
241
				fprintf(stderr,"Warning: exhausting read requested, but key file is not a regular file, function might never return.\n");
218
				if (i || strcmp(pass, pass_verify) != 0) {
219
					set_error("Passphrases do not match");
220
					goto out_err;
221
				}
222
				memset(pass_verify, 0, sizeof(pass_verify));
242
			}
223
			}
243
		}
224
			*passLen = strlen(pass);
244
		buflen = 0;
225
			*key = pass;
245
		for(i = 0; read_horizon == 0 || i < read_horizon; i++) {
226
		} else {
246
			if(i >= buflen - 1) {
227
			/* 
247
				buflen += 128;
228
			 * This is either a fd-input or a file, in neither case we can verify the input,
248
				pass = safe_realloc(pass, buflen);
229
			 * however we don't stop on new lines if it's a binary file.
249
				if (!pass) {
230
			 */
250
					set_error("Not enough memory while "
231
			int buflen, i;
251
					          "reading passphrase");
232
	
233
			if(verify) {
234
				set_error("Can't do passphrase verification on non-tty inputs");
235
				goto out_err;
236
			}
237
			/* The following for control loop does an exhausting
238
			 * read on the key material file, if requested with
239
			 * key_size == 0, as it's done by LUKS. However, we
240
			 * should warn the user, if it's a non-regular file,
241
			 * such as /dev/random, because in this case, the loop
242
			 * will read forever.
243
			 */ 
244
			if(options->key_file && strcmp(options->key_file, "-") && read_horizon == 0) {
245
				struct stat st;
246
				if(stat(options->key_file, &st) < 0) {
247
			 		set_error("Can't stat key file");
252
					goto out_err;
248
					goto out_err;
253
				}
249
				}
250
				if(!S_ISREG(st.st_mode)) {
251
					// set_error("Can't do exhausting read on non regular files");
252
					// goto out_err;
253
					fprintf(stderr,"Warning: exhausting read requested, but key file is not a regular file, function might never return.\n");
254
				}
254
			}
255
			}
255
			if(read(fd, pass + i, 1) != 1 || (newline_stop && pass[i] == '\n'))
256
			buflen = 0;
256
				break;
257
			for(i = 0; read_horizon == 0 || i < read_horizon; i++) {
258
				if(i >= buflen - 1) {
259
					buflen += 128;
260
					pass = safe_realloc(pass, buflen);
261
					if (!pass) {
262
						set_error("Not enough memory while "
263
						          "reading passphrase");
264
						goto out_err;
265
					}
266
				}
267
				if(read(fd, pass + i, 1) != 1 || (newline_stop && pass[i] == '\n'))
268
					break;
269
			}
270
			if(options->key_file)
271
				close(fd);
272
			pass[i] = 0;
273
			*key = pass;
274
			*passLen = i;
257
		}
275
		}
258
		if(options->key_file)
276
	
259
			close(fd);
277
		return isatty(fd); /* Return true, when password reading can be tried on interactive fds */
260
		pass[i] = 0;
261
		*key = pass;
262
		*passLen = i;
263
	}
278
	}
264
279
	return 0;
265
	return isatty(fd); /* Return true, when password reading can be tried on interactive fds */
280
	
266
267
out_err:
281
out_err:
268
	if(pass)
282
	if(pass)
269
		safe_free(pass);
283
		safe_free(pass);

Return to bug 201295