Exemple #1
0
int64_t copy_stream_to_fd(FILE *input, int fd)
{
	int64_t total = 0;

	while(1) {
		char buffer[COPY_BUFFER_SIZE];

		int64_t actual_read = full_fread(input, buffer, COPY_BUFFER_SIZE);
		if(actual_read <= 0) {
			if (total == 0)
				return -1;
			else
				break;
		}

		int64_t actual_write = full_write(fd, buffer, actual_read);
		if(actual_write == -1) {
			if (total == 0)
				return -1;
			else
				break;
		}

		total += actual_write;
	}

	return total;
}
Exemple #2
0
INT64_T link_stream_from_file(struct link * link, FILE * file, INT64_T length, time_t stoptime)
{
	char buffer[65536];
	INT64_T total = 0;
	INT64_T ractual, wactual;

	while(1) {
		INT64_T chunk = MIN(sizeof(buffer), length);

		ractual = full_fread(file, buffer, chunk);
		if(ractual <= 0)
			break;

		wactual = link_write(link, buffer, ractual, stoptime);
		if(wactual != ractual) {
			total = -1;
			break;
		}

		total += ractual;
		length -= ractual;
	}

	return total;
}
Exemple #3
0
int64_t copy_stream_to_buffer(FILE *input, char **buffer, size_t *len)
{
	size_t _len;
	if (len == NULL)
		len = &_len;

	int64_t total = 0;
	buffer_t B;
	buffer_init(&B);

	while(1) {
		char buffer[COPY_BUFFER_SIZE];

		int64_t actual_read = full_fread(input, buffer, COPY_BUFFER_SIZE);
		if(actual_read <= 0) {
			if (total == 0)
				return -1;
			else
				break;
		}

		if (buffer_putlstring(&B, buffer, actual_read) == -1) {
			buffer_free(&B);
			return -1;
		}

		total += actual_read;
	}

	buffer_dupl(&B, buffer, len);
	buffer_free(&B);

	return total;
}
Exemple #4
0
INT64_T chirp_client_ticket_create(struct chirp_client * c, char name[CHIRP_PATH_MAX], unsigned bits, time_t stoptime)
{
	static const char command[] =
		"T=`mktemp`\n"
		"P=`mktemp`\n"
		"MD5=`mktemp`\n"
		"echo \"# Chirp Ticket\" > \"$T\"\n"
		"echo \"# `date`: Ticket Created.\" >> \"$T\"\n"
		"openssl genrsa \"$CHIRP_BITS\" >> \"$T\" 2> /dev/null\n"
		"sed '/^\\s*#/d' < \"$T\" | openssl rsa -pubout > \"$P\" 2> /dev/null\n"
		/* WARNING: openssl is *very* bad at giving sensible output. Use the last
		 * 32 non-space characters as the MD5 sum.
		 */
		"openssl md5 < \"$P\" 2> /dev/null | tr -d '[:space:]' | tail -c 32 > \"$MD5\"\n"
		"if [ -z \"$CHIRP_TICKET\" ]; then\n"
		"  CHIRP_TICKET=\"ticket.`cat $MD5`\"\n"
		"fi\n"
		"cat > \"$CHIRP_TICKET\" < \"$T\"\n"
		"rm -f \"$T\" \"$P\" \"$MD5\"\n"
		"echo \"Generated ticket $CHIRP_TICKET.\" 1>&2\n"
		"echo -n \"$CHIRP_TICKET\"\n";

	int result = 0;

	if(strlen(name) == 0)
		unsetenv("CHIRP_TICKET");
	else
		result = setenv("CHIRP_TICKET", name, 1);
	if(result == -1)
		return -1;

	char bits_s[32];
	sprintf(bits_s, "%u", bits);
	result = setenv("CHIRP_BITS", bits_s, 1);
	if(result == -1)
		return -1;

	memset(name, 0, CHIRP_PATH_MAX);
	FILE *shell = popen(command, "r");
	if(shell == NULL)
		return -1;
	ssize_t read;
	char *buffer = name;
	while((read = full_fread(shell, buffer, sizeof(name) - 1 - (name - buffer))) > 0)
		buffer += read;
	pclose(shell);
	if((buffer - name) <= 0) {
		errno = EINVAL;
		return -1;
	}

	return 0;
}
char * load_one_file( const char *filename, int *length )
{
	FILE *file = fopen(filename,"r");
	if(!file) {
		fprintf(stderr,"%s: couldn't open %s: %s\n",progname,filename,strerror(errno));
		exit(1);
	}

	fseek(file,0,SEEK_END);
	*length = ftell(file);
	fseek(file,0,SEEK_SET);

	char *data = malloc(*length);
	if(!data) {
		fprintf(stderr,"%s: out of memory!\n",progname);
		exit(1);
	}

	full_fread(file,data,*length);
	fclose(file);

	return data;
}
struct cseq * cseq_read( FILE *file )
{
	char line[SEQUENCE_FILE_LINE_MAX];
	char metadata[SEQUENCE_FILE_LINE_MAX];
	char name[SEQUENCE_FILE_LINE_MAX];
	int  nbases, nbytes;

	if(!fgets(line,sizeof(line),file)) return 0;

	// special case: two arrows indicates the end of a list,
	// but not the end of a file.

	if(line[0] == '>' && line[1] == '>') return 0;

	metadata[0] = 0;

	int n = sscanf(line, ">%s %d %d %[^\n]",name,&nbases,&nbytes,metadata);
	if(n<3) fatal("syntax error near %s\n",line);

	// allocate memory, rounding up to the next word size
	int malloc_bytes = get_malloc_bytes(nbases);
	short *data = malloc(malloc_bytes);

	// set the last full word to zero, to avoid uninitialized data.
	data[(malloc_bytes/sizeof(short))-1] = 0;

	n = full_fread(file,data,nbytes);
	if(n!=nbytes) fatal("sequence file is corrupted.");

	fgetc(file);

	struct cseq *c = cseq_create(name,nbases,data,metadata);

	free(data);

	return c;
}
Exemple #7
0
int64_t link_stream_from_file(struct link * link, FILE * file, int64_t length, time_t stoptime)
{
	int64_t total = 0;

	while(1) {
		char buffer[1<<16];
		size_t chunk = MIN(sizeof(buffer), (size_t)length);

		ssize_t ractual = full_fread(file, buffer, chunk);
		if(ractual <= 0)
			break;

		ssize_t wactual = link_write(link, buffer, ractual, stoptime);
		if(wactual != ractual) {
			total = -1;
			break;
		}

		total += ractual;
		length -= ractual;
	}

	return total;
}
Exemple #8
0
int main(int argc, char *argv[])
{
	int did_explicit_auth = 0;
	int follow_mode = 0;
	int whole_file_mode = 1;
	const char *hostname, *source_file, *target_file;
	time_t stoptime;
	FILE *file;
	int c;
	char *tickets = NULL;

	debug_config(argv[0]);

	static struct option long_options[] = {
		{"auth", required_argument, 0, 'a'},
		{"block-size", required_argument, 0, 'b'},
		{"debug", required_argument, 0, 'd'},
		{"follow", no_argument, 0, 'f'},
		{"tickets", required_argument, 0, 'i'},
		{"timeout", required_argument, 0, 't'},
		{"version", no_argument, 0, 'v'},
		{"help", no_argument, 0, 'h'},
		{0, 0, 0, 0}
	};

	while((c = getopt_long(argc, argv, "a:b:d:fi:t:vh", long_options, NULL)) > -1) {
		switch (c) {
		case 'a':
			auth_register_byname(optarg);
			did_explicit_auth = 1;
			break;
		case 'b':
			buffer_size = (size_t)strtoul(optarg, NULL, 0);
			break;
		case 'd':
			debug_flags_set(optarg);
			break;
		case 'f':
			follow_mode = 1;
			break;
		case 'i':
			tickets = strdup(optarg);
			break;
		case 't':
			timeout = string_time_parse(optarg);
			break;
		case 'v':
			cctools_version_print(stdout, argv[0]);
			exit(0);
			break;
		case 'h':
			show_help(argv[0]);
			exit(0);
			break;

		}
	}

	cctools_version_debug(D_DEBUG, argv[0]);

	if(!did_explicit_auth)
		auth_register_all();
	if(tickets) {
		auth_ticket_load(tickets);
		free(tickets);
	} else if(getenv(CHIRP_CLIENT_TICKETS)) {
		auth_ticket_load(getenv(CHIRP_CLIENT_TICKETS));
	} else {
		auth_ticket_load(NULL);
	}

	if((argc - optind) < 3) {
		show_help(argv[0]);
		exit(0);
	}

	source_file = argv[optind];
	hostname = argv[optind + 1];
	target_file = argv[optind + 2];
	stoptime = time(0) + timeout;

	if(!strcmp(source_file, "-")) {
		file = stdin;
		source_file = "/dev/stdin";
	} else {
		file = fopen(source_file, "r");
		if(!file) {
			fprintf(stderr, "chirp_put: couldn't open %s: %s\n", source_file, strerror(errno));
			return 1;
		}
	}

	if(follow_mode)
		whole_file_mode = 0;

	if(whole_file_mode) {
		INT64_T result = chirp_recursive_put(hostname, source_file, target_file, stoptime);
		if(result < 0) {
			fprintf(stderr, "chirp_put: couldn't put %s to host %s: %s\n", source_file, hostname, strerror(errno));
			return 1;
		} else {
			return 0;
		}
	} else {
		struct chirp_stream *stream;
		char *buffer = xxmalloc(buffer_size);
		INT64_T ractual, wactual;

		stream = chirp_stream_open(hostname, target_file, CHIRP_STREAM_WRITE, stoptime);
		if(!stream) {
			fprintf(stderr, "chirp_put: couldn't open %s for writing: %s\n", target_file, strerror(errno));
			return 1;
		}

		while(1) {
			ractual = full_fread(file, buffer, buffer_size);
			if(ractual == 0) {
				if(follow_mode) {
					debug(D_DEBUG, "waiting for more data...");
					sleep(1);
					continue;
				} else {
					break;
				}
			}
			wactual = chirp_stream_write(stream, buffer, (int)ractual, stoptime);
			if(wactual != ractual) {
				fprintf(stderr, "chirp_put: couldn't write to %s: %s\n", target_file, strerror(errno));
				return 1;
			}
		}
		chirp_stream_close(stream, stoptime);
		return 0;
	}
}
static int auth_ticket_assert(struct link *link, time_t stoptime)
{
	/* FIXME need to save errno ? */
	char line[AUTH_LINE_MAX];
	char **tickets = client_tickets;

	if(tickets) {
		char *ticket;
		char digest[DIGEST_LENGTH];

		for (ticket = *tickets; ticket; ticket = *(++tickets)) {
			if (access(ticket, R_OK) == -1) {
				debug(D_AUTH, "could not access ticket %s: %s", ticket, strerror(errno));
				continue;
			}

			/* load the digest */
			/* WARNING: openssl is *very* bad at giving sensible output. Use the last
			 * 32 non-space characters as the MD5 sum.
			 */
			char command[PATH_MAX * 2 + 4096];
			sprintf(command, "openssl rsa -in '%s' -pubout 2> /dev/null | openssl md5 2> /dev/null | tr -d '[:space:]' | tail -c 32", ticket);
			FILE *digestf = popen(command, "r");
			if(full_fread(digestf, digest, DIGEST_LENGTH) < DIGEST_LENGTH) {
				pclose(digestf);
				return 0;
			}
			pclose(digestf);
			debug(D_AUTH, "trying ticket %.*s", DIGEST_LENGTH, digest);
			if(link_putlstring(link, digest, DIGEST_LENGTH, stoptime) <= 0)
				return 0;
			if(link_putliteral(link, "\n", stoptime) <= 0)
				return 0;

			if(link_readline(link, line, sizeof(line), stoptime) <= 0)
				return 0;
			if(strcmp(line, "declined") == 0)
				continue;

			unsigned long length = strtoul(line, NULL, 10);
			if(errno == ERANGE || errno == EINVAL)
				return 0;	/* not a number? */
			debug(D_AUTH, "receiving challenge of %d bytes", length);

			FILE *in, *out;
			static const char command_template[] = "T1=`mktemp`\n"	/* signed challenge */
				"T2=`mktemp`\n"	/* private key without comments */
				"sed '/^\\s*#/d' < '%s' > \"$T2\"\n" "openssl rsautl -inkey \"$T2\" -sign > \"$T1\" 2> /dev/null\n" "R=\"$?\"\n" "if [ \"$R\" -ne 0 ]; then\n" "  rm -f \"$T1\" \"$T2\"\n" "  exit \"$R\"\n" "fi\n"
				"ls -l \"$T1\" | awk '{ print $5 }'\n" "cat \"$T1\"\n" "rm -f \"$T1\" \"$T2\"\n";
			sprintf(command, command_template, ticket);
			pid_t pid = dpopen(command, &in, &out);
			if(pid == 0)
				return 0;
			if(link_stream_to_file(link, in, length, stoptime) <= 0) {
				dpclose(in, out, pid);
				debug(D_AUTH, "openssl failed, your keysize may be too small");
				debug(D_AUTH, "please debug using \"dd if=/dev/urandom count=64 bs=1 | openssl rsautl -inkey <ticket file> -sign\"");
				return 0;
			}
			fclose(in);
			in = NULL;
			if(link_stream_from_file(link, out, 1 << 20, stoptime) <= 0) {
				dpclose(in, out, pid);
				debug(D_AUTH, "openssl failed, your keysize may be too small");
				debug(D_AUTH, "please debug using \"dd if=/dev/urandom count=64 bs=1 | openssl rsautl -inkey <ticket file> -sign\"");
				return 0;
			}
			dpclose(in, out, pid);

			if(link_readline(link, line, sizeof(line), stoptime) <= 0)
				return 0;
			if(strcmp(line, "success") == 0) {
				debug(D_AUTH, "succeeded challenge for %.*s\n", DIGEST_LENGTH, digest);
				return 1;
			} else if(strcmp(line, "failure") == 0) {
				debug(D_AUTH, "failed challenge for %.*s\n", DIGEST_LENGTH, digest);
				errno = EINVAL;
				return 0;
			} else {
				debug(D_AUTH, "received bad response: '%s'", line);
				errno = EINVAL;
				return 0;
			}
		}
	}
	link_putliteral(link, "==\n", stoptime);

	return 0;
}