Beispiel #1
0
/*
 * Stores and arbitrary binary string in the buffer.
 */
void
buffer_put_string(Buffer *buffer, const void *buf, u_int len)
{
	buffer_put_int(buffer, len);
	buffer_append(buffer, buf, len);
}
Beispiel #2
0
void VirtualSerial::_recv(uint8_t c) {
	buffer_append(c);
}
static int
mail_transaction_log_file_create2(struct mail_transaction_log_file *file,
				  int new_fd, bool reset,
				  struct dotlock **dotlock)
{
	struct mail_index *index = file->log->index;
	struct stat st;
	const char *path2;
	buffer_t *writebuf;
	int fd, ret;
	bool rename_existing, need_lock;

	need_lock = file->log->head != NULL && file->log->head->locked;

	if (fcntl(new_fd, F_SETFL, O_APPEND) < 0) {
		log_file_set_syscall_error(file, "fcntl(O_APPEND)");
		return -1;
	}

	if (file->log->nfs_flush) {
		/* although we check also mtime and file size below, it's done
		   only to fix broken log files. we don't bother flushing
		   attribute cache just for that. */
		nfs_flush_file_handle_cache(file->filepath);
	}

	/* log creation is locked now - see if someone already created it.
	   note that if we're rotating, we need to keep the log locked until
	   the file has been rewritten. and because fcntl() locks are stupid,
	   if we go and open()+close() the file and we had it already opened,
	   its locks are lost. so we use stat() to check if the file has been
	   recreated, although it almost never is. */
	if (reset)
		rename_existing = FALSE;
	else if (nfs_safe_stat(file->filepath, &st) < 0) {
		if (errno != ENOENT) {
			log_file_set_syscall_error(file, "stat()");
			return -1;
		}
		rename_existing = FALSE;
	} else if (st.st_ino == file->st_ino &&
		   CMP_DEV_T(st.st_dev, file->st_dev) &&
		   /* inode/dev checks are enough when we're rotating the file,
		      but not when we're replacing a broken log file */
		   st.st_mtime == file->last_mtime &&
		   (uoff_t)st.st_size == file->last_size) {
		/* no-one else recreated the file */
		rename_existing = TRUE;
	} else {
		/* recreated. use the file if its header is ok */
		fd = nfs_safe_open(file->filepath, O_RDWR | O_APPEND);
		if (fd == -1) {
			if (errno != ENOENT) {
				log_file_set_syscall_error(file, "open()");
				return -1;
			}
		} else {
			file->fd = fd;
			file->last_size = 0;
			if (mail_transaction_log_file_read_hdr(file,
							       FALSE) > 0 &&
			    mail_transaction_log_file_stat(file, FALSE) == 0) {
				/* yes, it was ok */
				file_dotlock_delete(dotlock);
				mail_transaction_log_file_add_to_list(file);
				return 0;
			}
			file->fd = -1;
			if (close(fd) < 0)
				log_file_set_syscall_error(file, "close()");
		}
		rename_existing = FALSE;
	}

	if (index->fd == -1 && !rename_existing) {
		/* creating the initial index */
		reset = TRUE;
	}

	if (mail_transaction_log_init_hdr(file->log, &file->hdr) < 0)
		return -1;

	if (reset) {
		/* don't reset modseqs. if we're reseting due to rebuilding
		   indexes we'll probably want to keep uidvalidity and in such
		   cases we really don't want to shrink modseqs. */
		file->hdr.prev_file_seq = 0;
		file->hdr.prev_file_offset = 0;
	}

	writebuf = buffer_create_dynamic(pool_datastack_create(), 128);
	buffer_append(writebuf, &file->hdr, sizeof(file->hdr));

	if (index->ext_hdr_init_data != NULL && reset)
		log_write_ext_hdr_init_data(index, writebuf);
	if (write_full(new_fd, writebuf->data, writebuf->used) < 0) {
		log_file_set_syscall_error(file, "write_full()");
		return -1;
	}

	if (file->log->index->fsync_mode == FSYNC_MODE_ALWAYS) {
		/* the header isn't important, so don't bother calling
		   fdatasync() unless it's required */
		if (fdatasync(new_fd) < 0) {
			log_file_set_syscall_error(file, "fdatasync()");
			return -1;
		}
	}

	file->fd = new_fd;
	ret = mail_transaction_log_file_stat(file, FALSE);

	if (need_lock) {
		/* we'll need to preserve the lock */
		if (mail_transaction_log_file_lock(file) < 0)
			ret = -1;
	}

	/* if we return -1 the dotlock deletion code closes the fd */
	file->fd = -1;
	if (ret < 0)
		return -1;

	/* keep two log files */
	if (rename_existing) {
		/* rename() would be nice and easy way to do this, except then
		   there's a race condition between the rename and
		   file_dotlock_replace(). during that time the log file
		   doesn't exist, which could cause problems. */
		path2 = t_strconcat(file->filepath, ".2", NULL);
		if (i_unlink_if_exists(path2) < 0) {
			/* try to link() anyway */
		}
		if (nfs_safe_link(file->filepath, path2, FALSE) < 0 &&
		    errno != ENOENT && errno != EEXIST) {
                        mail_index_set_error(index, "link(%s, %s) failed: %m",
					     file->filepath, path2);
			/* ignore the error. we don't care that much about the
			   second log file and we're going to overwrite this
			   first one. */
		}
		/* NOTE: here's a race condition where both .log and .log.2
		   point to the same file. our reading code should ignore that
		   though by comparing the inodes. */
	}

	if (file_dotlock_replace(dotlock,
				 DOTLOCK_REPLACE_FLAG_DONT_CLOSE_FD) <= 0)
		return -1;

	/* success */
	file->fd = new_fd;
	mail_transaction_log_file_add_to_list(file);

	i_assert(!need_lock || file->locked);
	return 1;
}
Beispiel #4
0
/*
 * Performs the interactive session.  This handles data transmission between
 * the client and the program.  Note that the notion of stdin, stdout, and
 * stderr in this function is sort of reversed: this function writes to
 * stdin (of the child program), and reads from stdout and stderr (of the
 * child program).
 */
void
server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg)
{
	fd_set *readset = NULL, *writeset = NULL;
	int max_fd = 0;
	u_int nalloc = 0;
	int wait_status;	/* Status returned by wait(). */
	pid_t wait_pid;		/* pid returned by wait(). */
	int waiting_termination = 0;	/* Have displayed waiting close message. */
	u_int64_t max_time_milliseconds;
	u_int previous_stdout_buffer_bytes;
	u_int stdout_buffer_bytes;
	int type;

	debug("Entering interactive session.");

	/* Initialize the SIGCHLD kludge. */
	child_terminated = 0;
	signal(SIGCHLD, sigchld_handler);

	if (!use_privsep) {
		signal(SIGTERM, sigterm_handler);
		signal(SIGINT, sigterm_handler);
		signal(SIGQUIT, sigterm_handler);
	}

	/* Initialize our global variables. */
	fdin = fdin_arg;
	fdout = fdout_arg;
	fderr = fderr_arg;

	/* nonblocking IO */
	set_nonblock(fdin);
	set_nonblock(fdout);
	/* we don't have stderr for interactive terminal sessions, see below */
	if (fderr != -1)
		set_nonblock(fderr);

	if (!(datafellows & SSH_BUG_IGNOREMSG) && isatty(fdin))
		fdin_is_tty = 1;

	connection_in = packet_get_connection_in();
	connection_out = packet_get_connection_out();

	notify_setup();

	previous_stdout_buffer_bytes = 0;

	/* Set approximate I/O buffer size. */
	if (packet_is_interactive())
		buffer_high = 4096;
	else
		buffer_high = 64 * 1024;

#if 0
	/* Initialize max_fd to the maximum of the known file descriptors. */
	max_fd = MAX(connection_in, connection_out);
	max_fd = MAX(max_fd, fdin);
	max_fd = MAX(max_fd, fdout);
	if (fderr != -1)
		max_fd = MAX(max_fd, fderr);
#endif

	/* Initialize Initialize buffers. */
	buffer_init(&stdin_buffer);
	buffer_init(&stdout_buffer);
	buffer_init(&stderr_buffer);

	/*
	 * If we have no separate fderr (which is the case when we have a pty
	 * - there we cannot make difference between data sent to stdout and
	 * stderr), indicate that we have seen an EOF from stderr.  This way
	 * we don't need to check the descriptor everywhere.
	 */
	if (fderr == -1)
		fderr_eof = 1;

	server_init_dispatch();

	/* Main loop of the server for the interactive session mode. */
	for (;;) {

		/* Process buffered packets from the client. */
		process_buffered_input_packets();

		/*
		 * If we have received eof, and there is no more pending
		 * input data, cause a real eof by closing fdin.
		 */
		if (stdin_eof && fdin != -1 && buffer_len(&stdin_buffer) == 0) {
			if (fdin != fdout)
				close(fdin);
			else
				shutdown(fdin, SHUT_WR); /* We will no longer send. */
			fdin = -1;
		}
		/* Make packets from buffered stderr data to send to the client. */
		make_packets_from_stderr_data();

		/*
		 * Make packets from buffered stdout data to send to the
		 * client. If there is very little to send, this arranges to
		 * not send them now, but to wait a short while to see if we
		 * are getting more data. This is necessary, as some systems
		 * wake up readers from a pty after each separate character.
		 */
		max_time_milliseconds = 0;
		stdout_buffer_bytes = buffer_len(&stdout_buffer);
		if (stdout_buffer_bytes != 0 && stdout_buffer_bytes < 256 &&
		    stdout_buffer_bytes != previous_stdout_buffer_bytes) {
			/* try again after a while */
			max_time_milliseconds = 10;
		} else {
			/* Send it now. */
			make_packets_from_stdout_data();
		}
		previous_stdout_buffer_bytes = buffer_len(&stdout_buffer);

		/* Send channel data to the client. */
		if (packet_not_very_much_data_to_write())
			channel_output_poll();

		/*
		 * Bail out of the loop if the program has closed its output
		 * descriptors, and we have no more data to send to the
		 * client, and there is no pending buffered data.
		 */
		if (fdout_eof && fderr_eof && !packet_have_data_to_write() &&
		    buffer_len(&stdout_buffer) == 0 && buffer_len(&stderr_buffer) == 0) {
			if (!channel_still_open())
				break;
			if (!waiting_termination) {
				const char *s = "Waiting for forwarded connections to terminate...\r\n";
				char *cp;
				waiting_termination = 1;
				buffer_append(&stderr_buffer, s, strlen(s));

				/* Display list of open channels. */
				cp = channel_open_message();
				buffer_append(&stderr_buffer, cp, strlen(cp));
				free(cp);
			}
		}
		max_fd = MAX(connection_in, connection_out);
		max_fd = MAX(max_fd, fdin);
		max_fd = MAX(max_fd, fdout);
		max_fd = MAX(max_fd, fderr);
		max_fd = MAX(max_fd, notify_pipe[0]);

		/* Sleep in select() until we can do something. */
		wait_until_can_do_something(&readset, &writeset, &max_fd,
		    &nalloc, max_time_milliseconds);

		if (received_sigterm) {
			logit("Exiting on signal %d", (int)received_sigterm);
			/* Clean up sessions, utmp, etc. */
			cleanup_exit(255);
		}

		/* Process any channel events. */
		channel_after_select(readset, writeset);

		/* Process input from the client and from program stdout/stderr. */
		process_input(readset);

		/* Process output to the client and to program stdin. */
		process_output(writeset);
	}
	free(readset);
	free(writeset);

	/* Cleanup and termination code. */

	/* Wait until all output has been sent to the client. */
	drain_output();

	debug("End of interactive session; stdin %ld, stdout (read %ld, sent %ld), stderr %ld bytes.",
	    stdin_bytes, fdout_bytes, stdout_bytes, stderr_bytes);

	/* Free and clear the buffers. */
	buffer_free(&stdin_buffer);
	buffer_free(&stdout_buffer);
	buffer_free(&stderr_buffer);

	/* Close the file descriptors. */
	if (fdout != -1)
		close(fdout);
	fdout = -1;
	fdout_eof = 1;
	if (fderr != -1)
		close(fderr);
	fderr = -1;
	fderr_eof = 1;
	if (fdin != -1)
		close(fdin);
	fdin = -1;

	channel_free_all();

	/* We no longer want our SIGCHLD handler to be called. */
	signal(SIGCHLD, SIG_DFL);

	while ((wait_pid = waitpid(-1, &wait_status, 0)) < 0)
		if (errno != EINTR)
			packet_disconnect("wait: %.100s", strerror(errno));
	if (wait_pid != pid)
		error("Strange, wait returned pid %ld, expected %ld",
		    (long)wait_pid, (long)pid);

	/* Check if it exited normally. */
	if (WIFEXITED(wait_status)) {
		/* Yes, normal exit.  Get exit status and send it to the client. */
		debug("Command exited with status %d.", WEXITSTATUS(wait_status));
		packet_start(SSH_SMSG_EXITSTATUS);
		packet_put_int(WEXITSTATUS(wait_status));
		packet_send();
		packet_write_wait();

		/*
		 * Wait for exit confirmation.  Note that there might be
		 * other packets coming before it; however, the program has
		 * already died so we just ignore them.  The client is
		 * supposed to respond with the confirmation when it receives
		 * the exit status.
		 */
		do {
			type = packet_read();
		}
		while (type != SSH_CMSG_EXIT_CONFIRMATION);

		debug("Received exit confirmation.");
		return;
	}
	/* Check if the program terminated due to a signal. */
	if (WIFSIGNALED(wait_status))
		packet_disconnect("Command terminated on signal %d.",
				  WTERMSIG(wait_status));

	/* Some weird exit cause.  Just exit. */
	packet_disconnect("wait returned status %04x.", wait_status);
	/* NOTREACHED */
}
Beispiel #5
0
static bool message_decode_body(struct message_decoder_context *ctx,
				struct message_block *input,
				struct message_block *output)
{
	const unsigned char *data = NULL;
	size_t pos = 0, size = 0;
	int ret;

	if (ctx->encoding_buf->used != 0) {
		/* @UNSAFE */
		buffer_append(ctx->encoding_buf, input->data, input->size);
	}

	switch (ctx->message_cte) {
	case MESSAGE_CTE_UNKNOWN:
		/* just skip this body */
		return FALSE;

	case MESSAGE_CTE_78BIT:
	case MESSAGE_CTE_BINARY:
		data = input->data;
		size = pos = input->size;
		break;
	case MESSAGE_CTE_QP:
		buffer_set_used_size(ctx->buf, 0);
		if (ctx->encoding_buf->used != 0) {
			(void)quoted_printable_decode(ctx->encoding_buf->data,
						      ctx->encoding_buf->used,
						      &pos, ctx->buf);
		} else {
			(void)quoted_printable_decode(input->data, input->size,
						      &pos, ctx->buf);
		}
		data = ctx->buf->data;
		size = ctx->buf->used;
		break;
	case MESSAGE_CTE_BASE64:
		buffer_set_used_size(ctx->buf, 0);
		if (ctx->encoding_buf->used != 0) {
			ret = base64_decode(ctx->encoding_buf->data,
					    ctx->encoding_buf->used,
					    &pos, ctx->buf);
		} else {
			ret = base64_decode(input->data, input->size,
					    &pos, ctx->buf);
		}
		if (ret < 0) {
			/* corrupted base64 data, don't bother with
			   the rest of it */
			return FALSE;
		}
		if (ret == 0) {
			/* end of base64 input */
			pos = input->size;
			buffer_set_used_size(ctx->encoding_buf, 0);
		}
		data = ctx->buf->data;
		size = ctx->buf->used;
		break;
	}

	if (ctx->encoding_buf->used != 0)
		buffer_delete(ctx->encoding_buf, 0, pos);
	else if (pos != input->size) {
		buffer_append(ctx->encoding_buf,
			      input->data + pos, input->size - pos);
	}

	if (ctx->binary_input) {
		output->data = data;
		output->size = size;
	} else if (ctx->charset_utf8 || ctx->charset_trans == NULL) {
		/* handle unknown charsets the same as UTF-8. it might find
		   usable ASCII text. */
		buffer_set_used_size(ctx->buf2, 0);
		if (ctx->normalizer != NULL) {
			(void)ctx->normalizer(data, size, ctx->buf2);
			output->data = ctx->buf2->data;
			output->size = ctx->buf2->used;
		} else if (uni_utf8_get_valid_data(data, size, ctx->buf2)) {
			output->data = data;
			output->size = size;
		} else {
			output->data = ctx->buf2->data;
			output->size = ctx->buf2->used;
		}
	} else {
		buffer_set_used_size(ctx->buf2, 0);
		if (ctx->translation_size != 0)
			translation_buf_decode(ctx, &data, &size);

		pos = size;
		(void)charset_to_utf8(ctx->charset_trans,
				      data, &pos, ctx->buf2);
		if (pos != size) {
			ctx->translation_size = size - pos;
			i_assert(ctx->translation_size <=
				 sizeof(ctx->translation_buf));
			memcpy(ctx->translation_buf, data + pos,
			       ctx->translation_size);
		}
		output->data = ctx->buf2->data;
		output->size = ctx->buf2->used;
	}

	output->hdr = NULL;
	return TRUE;
}
Beispiel #6
0
static int
userauth_hostbased(Authctxt *authctxt)
{
	Buffer b;
	Key *key = NULL;
	char *pkalg, *cuser, *chost, *service;
	u_char *pkblob, *sig;
	u_int alen, blen, slen;
	int pktype;
	int authenticated = 0;

	if (!authctxt->valid) {
		debug2("userauth_hostbased: disabled because of invalid user");
		return 0;
	}
	pkalg = packet_get_string(&alen);
	pkblob = packet_get_string(&blen);
	chost = packet_get_string(NULL);
	cuser = packet_get_string(NULL);
	sig = packet_get_string(&slen);

	debug("userauth_hostbased: cuser %s chost %s pkalg %s slen %d",
	    cuser, chost, pkalg, slen);
#ifdef DEBUG_PK
	debug("signature:");
	buffer_init(&b);
	buffer_append(&b, sig, slen);
	buffer_dump(&b);
	buffer_free(&b);
#endif
	pktype = key_type_from_name(pkalg);
	if (pktype == KEY_UNSPEC) {
		/* this is perfectly legal */
		logit("userauth_hostbased: unsupported "
		    "public key algorithm: %s", pkalg);
		goto done;
	}
	key = key_from_blob(pkblob, blen);
	if (key == NULL) {
		error("userauth_hostbased: cannot decode key: %s", pkalg);
		goto done;
	}
	if (key->type != pktype) {
		error("userauth_hostbased: type mismatch for decoded key "
		    "(received %d, expected %d)", key->type, pktype);
		goto done;
	}
	service = datafellows & SSH_BUG_HBSERVICE ? "ssh-userauth" :
	    authctxt->service;
	buffer_init(&b);
	buffer_put_string(&b, session_id2, session_id2_len);
	/* reconstruct packet */
	buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
	buffer_put_cstring(&b, authctxt->user);
	buffer_put_cstring(&b, service);
	buffer_put_cstring(&b, "hostbased");
	buffer_put_string(&b, pkalg, alen);
	buffer_put_string(&b, pkblob, blen);
	buffer_put_cstring(&b, chost);
	buffer_put_cstring(&b, cuser);
#ifdef DEBUG_PK
	buffer_dump(&b);
#endif

	pubkey_auth_info(authctxt, key,
	    "client user \"%.100s\", client host \"%.100s\"", cuser, chost);

	/* test for allowed key and correct signature */
	authenticated = 0;
	if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, key)) &&
	    PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b),
			buffer_len(&b))) == 1)
		authenticated = 1;

	buffer_free(&b);
done:
	debug2("userauth_hostbased: authenticated %d", authenticated);
	if (key != NULL)
		key_free(key);
	free(pkalg);
	free(pkblob);
	free(cuser);
	free(chost);
	free(sig);
	return authenticated;
}
Beispiel #7
0
static buffer_array* parse_c_cpp(const char *filepath)
{
	if (NULL == filepath)
	{
		return NULL;
	}
	
//	log_info("Parse file : %s", filepath);
	//获得文件所在的目录的路径。
	//保存在path中。
	char 	path[500];
	size_t 	s_end = strlen(filepath);
	while(filepath[s_end--] != '/');
	s_end += 2;
	strncpy(path, filepath, s_end);
	path[s_end] = '\0';

	int 	buf_len = 500;
	char 	buf[500];
	buffer_array *ba = buffer_array_init();

	FILE 	*fp;
	if ((fp = fopen(filepath, "r")) == NULL)
	{
		log_err("Can not open file : %s", filepath);
		exit(1);
	}

	int 	read_len;
	int 	index;
	int 	begin, end;
	char 	includepath[buf_len];
	int 	includeindex;
	int 	is_std; 		//标记包含的文件是否是标准头文件
	buffer 	*b;
	while (fgets(buf, buf_len, fp) != NULL)
	{
		is_std = 0;
		read_len = strlen(buf);
		/*
		 * 头文件是以#include "" 或者#include <>形式表示的。
		 * 如果此行的长度小于9就不可能存在include声明。
		 */
		if (read_len < 9)
		{
			continue;
		}

		//判断是否以#开头,若不是,继续读下一行。
		index = 0;
		while(buf[index] == ' ') 	//除去开头的空白。
		{
			++index;
		}
		if(buf[index] != '#')
		{
			continue;
		}
		
		while(buf[++index] == ' ');
		begin = index;
		end = begin + 7; //include 只有7个字母,因此只需比较7个字母是不是include即可。
		if (strcmp_n("include", buf, begin, end) == 0)
		{
			continue;
		}
		
		while (buf[begin] != '"' && buf[begin] != '<')
		{
			++begin;
		}
	
		if(buf[begin] == '<') 		//包含的文件是标准头文件
		{
			is_std = 1;
		}

		++begin;
		end = begin;
		while (buf[end] != '"' && buf[end] != '>')
		{
			++end;
		}

		includeindex = 0;
		for (; begin < end; ++begin, ++includeindex)
		{
			includepath[includeindex] = buf[begin];
		}
		includepath[includeindex] = '\0';
		b = buffer_init();	
		if(!is_std)
		{
			buffer_append(b, path, strlen(path));
		}
		buffer_append(b, includepath, strlen(includepath));
		buffer_array_append(ba, b);

	//	printf("\t%s\n", b -> ptr);
	}
 
	fclose(fp);
	return ba;
}
Beispiel #8
0
static void write_item(struct buffer *buffer, char *bytes, size_t len)
{
	uint32_t be32len = htobe32(len);
	buffer_append(buffer, &be32len, sizeof(be32len));
	buffer_append(buffer, bytes, len);
}
Beispiel #9
0
int html_attachment(const char *list, unsigned int y, unsigned int m, unsigned int d, unsigned int n, unsigned int a)
{
	unsigned int aday;
	char *list_file;
	off_t idx_offset;
	int fd, error, got, trunc;
	idx_msgnum_t m1, m1r;
	struct idx_message idx_msg;
	idx_off_t offset;
	idx_size_t size;
	struct buffer src, dst;
	struct mime_ctx mime;
	char *body, *bend;

	if (y < MIN_YEAR || y > MAX_YEAR ||
	    m < 1 || m > 12 ||
	    d < 1 || d > 31 ||
	    n < 1 || n > 999999)
		return html_error("Invalid date or message number");
	aday = YMD2ADAY(y - MIN_YEAR, m, d);

	list_file = concat(MAIL_SPOOL_PATH "/", list, NULL);
	if (!list_file)
		return html_error(NULL);

	fd = idx_open(list);
	if (fd < 0) {
		error = errno;
		free(list_file);
		return html_error(error == ENOENT ?
		    "No such mailing list" : (error == ESRCH ?
		    "Index needs rebuild" : NULL));
	}

	error = !idx_read_aday_ok(fd, aday, &m1, sizeof(m1));
	if (error || m1 < 1 || m1 >= MAX_MAILBOX_MESSAGES) {
		idx_close(fd);
		free(list_file);
		return html_error((error || m1 > 0) ? NULL : "No such message");
	}
	m1r = m1 + n - 2; /* both m1 and n are 1-based; m1r is 0-based */
	idx_offset = IDX2MSG(m1r);
	got = idx_read(fd, idx_offset, &idx_msg, sizeof(idx_msg));
	if (got != sizeof(idx_msg))
		error = 1;

	if (idx_close(fd) || error) {
		free(list_file);
		return html_error(got ? NULL : "No such message");
	}

	if (y - MIN_YEAR != idx_msg.y ||
	    m != idx_msg.m ||
	    d != idx_msg.d) {
		free(list_file);
		return html_error("No such message");
	}

	offset = idx_msg.offset;
	size = idx_msg.size;

	trunc = size > MAX_MESSAGE_SIZE;
	if (trunc)
		size = MAX_MESSAGE_SIZE;
	if (buffer_init(&src, size)) {
		free(list_file);
		return html_error(NULL);
	}
	fd = open(list_file, O_RDONLY);
	free(list_file);
	if (fd < 0) {
		buffer_free(&src);
		return html_error("mbox open error");
	}
	error =
	    lseek(fd, offset, SEEK_SET) != offset ||
	    read_loop(fd, src.start, size) != size;
	if (close(fd) || error || mime_init(&mime, &src)) {
		buffer_free(&src);
		return html_error("mbox read error");
	}
	if (buffer_init(&dst, size)) {
		buffer_free(&src);
		mime_free(&mime);
		return html_error(NULL);
	}

	body = NULL;
	while (src.end - src.ptr > 9 && *src.ptr != '\n') {
		switch (*src.ptr) {
		case 'C':
		case 'c':
			mime_decode_header(&mime);
			continue;
		}
		mime_skip_header(&mime);
	}
	if (src.ptr >= src.end) {
		buffer_free(&src);
		buffer_free(&dst);
		mime_free(&mime);
		return html_error(NULL);
	}
	if (*src.ptr == '\n')
		body = ++src.ptr;

	const char *error_msg = "Attachment not found";
	unsigned int attachment_count = 0;
	if (a)
	do {
		if (mime.entities->boundary) {
			body = mime_next_body_part(&mime);
			if (!body || body >= src.end)
				break;
			body = mime_next_body(&mime);
		}
		if (mime.entities->boundary || !is_attachment(&mime) || ++attachment_count != a)
			body = NULL;
		if (!body) {
			bend = mime_skip_body(&mime);
			if (!bend)
				break;
			continue;
		}

		int text = !strncasecmp(mime.entities->type, "text/", 5);
		if (text) {
			buffer_appends(&dst, "Content-Type: text/plain");
			if (mime.entities->charset && enc_allowed_charset(mime.entities->charset))
				buffer_appendf(&dst, "; charset=%s", mime.entities->charset);
			buffer_appendc(&dst, '\n');
		} else {
			buffer_appends(&dst, "Content-Type: application/octet-stream\n");
		}
		buffer_appendf(&dst, "Content-Disposition: %s; filename=\"", text ? "inline" : "attachment");
		buffer_append_filename(&dst, mime.entities->filename, text);
		buffer_appends(&dst, "\"\n");

		body = mime_decode_body(&mime, RECODE_NO, &bend);
		if (trunc && (!body || bend >= src.end)) {
			error_msg = "Attachment is truncated";
			break;
		}

		buffer_appendf(&dst, "Content-Length: %llu\n\n", (unsigned long long)(mime.dst.ptr - body));
		buffer_append(&dst, body, mime.dst.ptr - body);
		error_msg = NULL;
		break;
	} while (bend < src.end && mime.entities);

	buffer_free(&src);

	if (error_msg || mime.dst.error || dst.error) {
		mime_free(&mime);
		buffer_free(&dst);
		return html_error(error_msg);
	}

	mime_free(&mime);

	return html_send(&dst);
}
Beispiel #10
0
static int
valid_request(struct passwd *pw, char *host, Key **ret, u_char *data,
    u_int datalen)
{
	Buffer b;
	Key *key = NULL;
	u_char *pkblob;
	u_int blen, len;
	char *pkalg, *p;
	int pktype, fail;

	fail = 0;

	buffer_init(&b);
	buffer_append(&b, data, datalen);

	/* session id, currently limited to SHA1 (20 bytes) */
	p = buffer_get_string(&b, &len);
	if (len != 20)
		fail++;
	xfree(p);

	if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST)
		fail++;

	/* server user */
	buffer_skip_string(&b);

	/* service */
	p = buffer_get_string(&b, NULL);
	if (strcmp("ssh-connection", p) != 0)
		fail++;
	xfree(p);

	/* method */
	p = buffer_get_string(&b, NULL);
	if (strcmp("hostbased", p) != 0)
		fail++;
	xfree(p);

	/* pubkey */
	pkalg = buffer_get_string(&b, NULL);
	pkblob = buffer_get_string(&b, &blen);

	pktype = key_type_from_name(pkalg);
	if (pktype == KEY_UNSPEC)
		fail++;
	else if ((key = key_from_blob(pkblob, blen)) == NULL)
		fail++;
	else if (key->type != pktype)
		fail++;
	xfree(pkalg);
	xfree(pkblob);

	/* client host name, handle trailing dot */
	p = buffer_get_string(&b, &len);
	debug2("valid_request: check expect chost %s got %s", host, p);
	if (strlen(host) != len - 1)
		fail++;
	else if (p[len - 1] != '.')
		fail++;
	else if (strncasecmp(host, p, len - 1) != 0)
		fail++;
	xfree(p);

	/* local user */
	p = buffer_get_string(&b, NULL);

	if (strcmp(pw->pw_name, p) != 0)
		fail++;
	xfree(p);

	/* end of message */
	if (buffer_len(&b) != 0)
		fail++;
	buffer_free(&b);

	debug3("valid_request: fail %d", fail);

	if (fail && key != NULL)
		key_free(key);
	else
		*ret = key;

	return (fail ? -1 : 0);
}
Beispiel #11
0
void
userauth_finish(Authctxt *authctxt, int authenticated, const char *method,
    const char *submethod)
{
	char *methods;
	int partial = 0;

	if (!authctxt->valid && authenticated)
		fatal("INTERNAL ERROR: authenticated invalid user %s",
		    authctxt->user);
	if (authenticated && authctxt->postponed)
		fatal("INTERNAL ERROR: authenticated and postponed");

	/* Special handling for root */
	if (authenticated && authctxt->pw->pw_uid == 0 &&
	    !auth_root_allowed(method)) {
		authenticated = 0;
#ifdef SSH_AUDIT_EVENTS
		PRIVSEP(audit_event(SSH_LOGIN_ROOT_DENIED));
#endif
	}

	if (authenticated && options.num_auth_methods != 0) {
		if (!auth2_update_methods_lists(authctxt, method, submethod)) {
			authenticated = 0;
			partial = 1;
		}
	}

	/* Log before sending the reply */
	auth_log(authctxt, authenticated, partial, method, submethod);

	if (authctxt->postponed)
		return;

#ifdef USE_PAM
	if (options.use_pam && authenticated) {
		if (!PRIVSEP(do_pam_account())) {
			/* if PAM returned a message, send it to the user */
			if (buffer_len(&loginmsg) > 0) {
				buffer_append(&loginmsg, "\0", 1);
				userauth_send_banner(buffer_ptr(&loginmsg));
				packet_write_wait();
			}
			fatal("Access denied for user %s by PAM account "
			    "configuration", authctxt->user);
		}
	}
#endif

#ifdef _UNICOS
	if (authenticated && cray_access_denied(authctxt->user)) {
		authenticated = 0;
		fatal("Access denied for user %s.", authctxt->user);
	}
#endif /* _UNICOS */

	if (authenticated == 1) {
		/* turn off userauth */
		dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &dispatch_protocol_ignore);
		packet_start(SSH2_MSG_USERAUTH_SUCCESS);
		packet_send();
		packet_write_wait();
		/* now we can break out */
		authctxt->success = 1;
	} else {

		/* Allow initial try of "none" auth without failure penalty */
		if (!authctxt->server_caused_failure &&
		    (authctxt->attempt > 1 || strcmp(method, "none") != 0))
			authctxt->failures++;
		if (authctxt->failures >= options.max_authtries) {
#ifdef SSH_AUDIT_EVENTS
			PRIVSEP(audit_event(SSH_LOGIN_EXCEED_MAXTRIES));
#endif
			auth_maxtries_exceeded(authctxt);
		}
		methods = authmethods_get(authctxt);
		debug3("%s: failure partial=%d next methods=\"%s\"", __func__,
		    partial, methods);
		packet_start(SSH2_MSG_USERAUTH_FAILURE);
		packet_put_cstring(methods);
		packet_put_char(partial);
		packet_send();
		packet_write_wait();
		free(methods);
	}
}
Beispiel #12
0
int
main(int ac, char **av)
{
	fd_set *rset, *wset;
	int in, out, max;
	ssize_t len, olen, set_size;

	/* XXX should use getopt */

	__progname = get_progname(av[0]);
	handle_init();

#ifdef DEBUG_SFTP_SERVER
	log_init("sftp-server", SYSLOG_LEVEL_DEBUG1, SYSLOG_FACILITY_AUTH, 0);
#endif

	in = dup(STDIN_FILENO);
	out = dup(STDOUT_FILENO);

#ifdef HAVE_CYGWIN
	setmode(in, O_BINARY);
	setmode(out, O_BINARY);
#endif

	max = 0;
	if (in > max)
		max = in;
	if (out > max)
		max = out;

	buffer_init(&iqueue);
	buffer_init(&oqueue);

	set_size = howmany(max + 1, NFDBITS) * sizeof(fd_mask);
	rset = (fd_set *)xmalloc(set_size);
	wset = (fd_set *)xmalloc(set_size);

	for (;;) {
		memset(rset, 0, set_size);
		memset(wset, 0, set_size);

		FD_SET(in, rset);
		olen = buffer_len(&oqueue);
		if (olen > 0)
			FD_SET(out, wset);

		if (select(max+1, rset, wset, NULL, NULL) < 0) {
			if (errno == EINTR)
				continue;
			exit(2);
		}

		/* copy stdin to iqueue */
		if (FD_ISSET(in, rset)) {
			char buf[4*4096];
			len = read(in, buf, sizeof buf);
			if (len == 0) {
				debug("read eof");
				exit(0);
			} else if (len < 0) {
				error("read error");
				exit(1);
			} else {
				buffer_append(&iqueue, buf, len);
			}
		}
		/* send oqueue to stdout */
		if (FD_ISSET(out, wset)) {
			len = write(out, buffer_ptr(&oqueue), olen);
			if (len < 0) {
				error("write error");
				exit(1);
			} else {
				buffer_consume(&oqueue, len);
			}
		}
		/* process requests from client */
		process();
	}
}
Beispiel #13
0
static char *
authmethods_get(void)
{
	Buffer b;
	char *list;
	int i;
	int sufficient = 0;
	int required = 0;
	int authenticated = 0;
	int partial = 0;

	/*
	 * If at least one method succeeded partially then at least one
	 * authmethod will be required and only required methods should
	 * continue.
	 */
	for (i = 0; authmethods[i] != NULL; i++) {
		if (authmethods[i]->authenticated)
			authenticated++;
		if (authmethods[i]->required)
			required++;
		if (authmethods[i]->sufficient)
			sufficient++;
	}

	partial = (required + sufficient) > 0;

	buffer_init(&b);
	for (i = 0; authmethods[i] != NULL; i++) {
		if (strcmp(authmethods[i]->name, "none") == 0)
			continue;
		if (required && !authmethods[i]->required)
			continue;
		if (sufficient && !required && !authmethods[i]->sufficient)
			continue;
		if (authmethods[i]->not_again)
			continue;

		if (authmethods[i]->required) {
			if (buffer_len(&b) > 0)
				buffer_append(&b, ",", 1);
			buffer_append(&b, authmethods[i]->name,
			    strlen(authmethods[i]->name));
			continue;
		}

		/*
		 * A method can be enabled (marked sufficient)
		 * dynamically provided that at least one other method
		 * has succeeded partially.
		 */
		if ((partial && authmethods[i]->sufficient) ||
		    (authmethods[i]->enabled != NULL &&
		    *(authmethods[i]->enabled) != 0)) {
			if (buffer_len(&b) > 0)
				buffer_append(&b, ",", 1);
			buffer_append(&b, authmethods[i]->name,
			    strlen(authmethods[i]->name));
		}
	}
	buffer_append(&b, "\0", 1);
	list = xstrdup(buffer_ptr(&b));
	buffer_free(&b);
	return list;
}
Beispiel #14
0
/*
 * Main program for the ssh client.
 */
int
main(int ac, char **av)
{
	int i, r, opt, exit_status, use_syslog;
	char *p, *cp, *line, *argv0, buf[MAXPATHLEN], *host_arg, *logfile;
	char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV];
	struct stat st;
	struct passwd *pw;
	int dummy, timeout_ms;
	extern int optind, optreset;
	extern char *optarg;

	struct servent *sp;
	Forward fwd;

	/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
	sanitise_stdfd();

	__progname = ssh_get_progname(av[0]);

#ifndef HAVE_SETPROCTITLE
	/* Prepare for later setproctitle emulation */
	/* Save argv so it isn't clobbered by setproctitle() emulation */
	saved_av = xcalloc(ac + 1, sizeof(*saved_av));
	for (i = 0; i < ac; i++)
		saved_av[i] = xstrdup(av[i]);
	saved_av[i] = NULL;
	compat_init_setproctitle(ac, av);
	av = saved_av;
#endif

	/*
	 * Discard other fds that are hanging around. These can cause problem
	 * with backgrounded ssh processes started by ControlPersist.
	 */
	closefrom(STDERR_FILENO + 1);

	/*
	 * Save the original real uid.  It will be needed later (uid-swapping
	 * may clobber the real uid).
	 */
	original_real_uid = getuid();
	original_effective_uid = geteuid();

	/*
	 * Use uid-swapping to give up root privileges for the duration of
	 * option processing.  We will re-instantiate the rights when we are
	 * ready to create the privileged port, and will permanently drop
	 * them when the port has been created (actually, when the connection
	 * has been made, as we may need to create the port several times).
	 */
	PRIV_END;

#ifdef HAVE_SETRLIMIT
	/* If we are installed setuid root be careful to not drop core. */
	if (original_real_uid != original_effective_uid) {
		struct rlimit rlim;
		rlim.rlim_cur = rlim.rlim_max = 0;
		if (setrlimit(RLIMIT_CORE, &rlim) < 0)
			fatal("setrlimit failed: %.100s", strerror(errno));
	}
#endif
	/* Get user data. */
	pw = getpwuid(original_real_uid);
	if (!pw) {
		logit("No user exists for uid %lu", (u_long)original_real_uid);
		exit(255);
	}
	/* Take a copy of the returned structure. */
	pw = pwcopy(pw);

	/*
	 * Set our umask to something reasonable, as some files are created
	 * with the default umask.  This will make them world-readable but
	 * writable only by the owner, which is ok for all files for which we
	 * don't set the modes explicitly.
	 */
	umask(022);

	/*
	 * Initialize option structure to indicate that no values have been
	 * set.
	 */
	initialize_options(&options);

	/* Parse command-line arguments. */
	host = NULL;
	use_syslog = 0;
	logfile = NULL;
	argv0 = av[0];

 again:
	while ((opt = getopt(ac, av, "1246ab:c:e:fgi:kl:m:no:p:qstvx"
	    "ACD:E:F:I:KL:MNO:PQ:R:S:TVw:W:XYy")) != -1) {
		switch (opt) {
		case '1':
			options.protocol = SSH_PROTO_1;
			break;
		case '2':
			options.protocol = SSH_PROTO_2;
			break;
		case '4':
			options.address_family = AF_INET;
			break;
		case '6':
			options.address_family = AF_INET6;
			break;
		case 'n':
			stdin_null_flag = 1;
			break;
		case 'f':
			fork_after_authentication_flag = 1;
			stdin_null_flag = 1;
			break;
		case 'x':
			options.forward_x11 = 0;
			break;
		case 'X':
			options.forward_x11 = 1;
			break;
		case 'y':
			use_syslog = 1;
			break;
		case 'E':
			logfile = xstrdup(optarg);
			break;
		case 'Y':
			options.forward_x11 = 1;
			options.forward_x11_trusted = 1;
			break;
		case 'g':
			options.gateway_ports = 1;
			break;
		case 'O':
			if (stdio_forward_host != NULL)
				fatal("Cannot specify multiplexing "
				    "command with -W");
			else if (muxclient_command != 0)
				fatal("Multiplexing command already specified");
			if (strcmp(optarg, "check") == 0)
				muxclient_command = SSHMUX_COMMAND_ALIVE_CHECK;
			else if (strcmp(optarg, "forward") == 0)
				muxclient_command = SSHMUX_COMMAND_FORWARD;
			else if (strcmp(optarg, "exit") == 0)
				muxclient_command = SSHMUX_COMMAND_TERMINATE;
			else if (strcmp(optarg, "stop") == 0)
				muxclient_command = SSHMUX_COMMAND_STOP;
			else if (strcmp(optarg, "cancel") == 0)
				muxclient_command = SSHMUX_COMMAND_CANCEL_FWD;
			else
				fatal("Invalid multiplex command.");
			break;
		case 'P':	/* deprecated */
			options.use_privileged_port = 0;
			break;
		case 'Q':	/* deprecated */
			cp = NULL;
			if (strcasecmp(optarg, "cipher") == 0)
				cp = cipher_alg_list();
			else if (strcasecmp(optarg, "mac") == 0)
				cp = mac_alg_list();
			else if (strcasecmp(optarg, "kex") == 0)
				cp = kex_alg_list();
			else if (strcasecmp(optarg, "key") == 0)
				cp = key_alg_list();
			if (cp == NULL)
				fatal("Unsupported query \"%s\"", optarg);
			printf("%s\n", cp);
			free(cp);
			exit(0);
			break;
		case 'a':
			options.forward_agent = 0;
			break;
		case 'A':
			options.forward_agent = 1;
			break;
		case 'k':
			options.gss_deleg_creds = 0;
			break;
		case 'K':
			options.gss_authentication = 1;
			options.gss_deleg_creds = 1;
			break;
		case 'i':
			if (stat(optarg, &st) < 0) {
				fprintf(stderr, "Warning: Identity file %s "
				    "not accessible: %s.\n", optarg,
				    strerror(errno));
				break;
			}
			add_identity_file(&options, NULL, optarg, 1);
			break;
		case 'I':
#ifdef ENABLE_PKCS11
			options.pkcs11_provider = xstrdup(optarg);
#else
			fprintf(stderr, "no support for PKCS#11.\n");
#endif
			break;
		case 't':
			if (options.request_tty == REQUEST_TTY_YES)
				options.request_tty = REQUEST_TTY_FORCE;
			else
				options.request_tty = REQUEST_TTY_YES;
			break;
		case 'v':
			if (debug_flag == 0) {
				debug_flag = 1;
				options.log_level = SYSLOG_LEVEL_DEBUG1;
			} else {
				if (options.log_level < SYSLOG_LEVEL_DEBUG3)
					options.log_level++;
			}
			break;
		case 'V':
			if (options.version_addendum &&
			    *options.version_addendum != '\0')
				fprintf(stderr, "%s%s %s, %s\n", SSH_RELEASE,
				    options.hpn_disabled ? "" : SSH_VERSION_HPN,
				    options.version_addendum,
				    SSLeay_version(SSLEAY_VERSION));
			else
				fprintf(stderr, "%s%s, %s\n", SSH_RELEASE,
				    options.hpn_disabled ? "" : SSH_VERSION_HPN,
				    SSLeay_version(SSLEAY_VERSION));
			if (opt == 'V')
				exit(0);
			break;
		case 'w':
			if (options.tun_open == -1)
				options.tun_open = SSH_TUNMODE_DEFAULT;
			options.tun_local = a2tun(optarg, &options.tun_remote);
			if (options.tun_local == SSH_TUNID_ERR) {
				fprintf(stderr,
				    "Bad tun device '%s'\n", optarg);
				exit(255);
			}
			break;
		case 'W':
			if (stdio_forward_host != NULL)
				fatal("stdio forward already specified");
			if (muxclient_command != 0)
				fatal("Cannot specify stdio forward with -O");
			if (parse_forward(&fwd, optarg, 1, 0)) {
				stdio_forward_host = fwd.listen_host;
				stdio_forward_port = fwd.listen_port;
				free(fwd.connect_host);
			} else {
				fprintf(stderr,
				    "Bad stdio forwarding specification '%s'\n",
				    optarg);
				exit(255);
			}
			options.request_tty = REQUEST_TTY_NO;
			no_shell_flag = 1;
			options.clear_forwardings = 1;
			options.exit_on_forward_failure = 1;
			break;
		case 'q':
			options.log_level = SYSLOG_LEVEL_QUIET;
			break;
		case 'e':
			if (optarg[0] == '^' && optarg[2] == 0 &&
			    (u_char) optarg[1] >= 64 &&
			    (u_char) optarg[1] < 128)
				options.escape_char = (u_char) optarg[1] & 31;
			else if (strlen(optarg) == 1)
				options.escape_char = (u_char) optarg[0];
			else if (strcmp(optarg, "none") == 0)
				options.escape_char = SSH_ESCAPECHAR_NONE;
			else {
				fprintf(stderr, "Bad escape character '%s'.\n",
				    optarg);
				exit(255);
			}
			break;
		case 'c':
			if (ciphers_valid(optarg)) {
				/* SSH2 only */
				options.ciphers = xstrdup(optarg);
				options.cipher = SSH_CIPHER_INVALID;
			} else {
				/* SSH1 only */
				options.cipher = cipher_number(optarg);
				if (options.cipher == -1) {
					fprintf(stderr,
					    "Unknown cipher type '%s'\n",
					    optarg);
					exit(255);
				}
				if (options.cipher == SSH_CIPHER_3DES)
					options.ciphers = "3des-cbc";
				else if (options.cipher == SSH_CIPHER_BLOWFISH)
					options.ciphers = "blowfish-cbc";
				else
					options.ciphers = (char *)-1;
			}
			break;
		case 'm':
			if (mac_valid(optarg))
				options.macs = xstrdup(optarg);
			else {
				fprintf(stderr, "Unknown mac type '%s'\n",
				    optarg);
				exit(255);
			}
			break;
		case 'M':
			if (options.control_master == SSHCTL_MASTER_YES)
				options.control_master = SSHCTL_MASTER_ASK;
			else
				options.control_master = SSHCTL_MASTER_YES;
			break;
		case 'p':
			options.port = a2port(optarg);
			if (options.port <= 0) {
				fprintf(stderr, "Bad port '%s'\n", optarg);
				exit(255);
			}
			break;
		case 'l':
			options.user = optarg;
			break;

		case 'L':
			if (parse_forward(&fwd, optarg, 0, 0))
				add_local_forward(&options, &fwd);
			else {
				fprintf(stderr,
				    "Bad local forwarding specification '%s'\n",
				    optarg);
				exit(255);
			}
			break;

		case 'R':
			if (parse_forward(&fwd, optarg, 0, 1)) {
				add_remote_forward(&options, &fwd);
			} else {
				fprintf(stderr,
				    "Bad remote forwarding specification "
				    "'%s'\n", optarg);
				exit(255);
			}
			break;

		case 'D':
			if (parse_forward(&fwd, optarg, 1, 0)) {
				add_local_forward(&options, &fwd);
			} else {
				fprintf(stderr,
				    "Bad dynamic forwarding specification "
				    "'%s'\n", optarg);
				exit(255);
			}
			break;

		case 'C':
			options.compression = 1;
			break;
		case 'N':
			no_shell_flag = 1;
			options.request_tty = REQUEST_TTY_NO;
			break;
		case 'T':
			options.request_tty = REQUEST_TTY_NO;
#ifdef	NONE_CIPHER_ENABLED
			/*
			 * Ensure that the user does not try to backdoor a
			 * NONE cipher switch on an interactive session by
			 * explicitly disabling it if the user asks for a
			 * session without a tty.
			 */
			options.none_switch = 0;
#endif
			break;
		case 'o':
			dummy = 1;
			line = xstrdup(optarg);
			if (process_config_line(&options, host ? host : "",
			    line, "command-line", 0, &dummy, SSHCONF_USERCONF)
			    != 0)
				exit(255);
			free(line);
			break;
		case 's':
			subsystem_flag = 1;
			break;
		case 'S':
			if (options.control_path != NULL)
				free(options.control_path);
			options.control_path = xstrdup(optarg);
			break;
		case 'b':
			options.bind_address = optarg;
			break;
		case 'F':
			config = optarg;
			break;
		default:
			usage();
		}
	}

	ac -= optind;
	av += optind;

	if (ac > 0 && !host) {
		if (strrchr(*av, '@')) {
			p = xstrdup(*av);
			cp = strrchr(p, '@');
			if (cp == NULL || cp == p)
				usage();
			options.user = p;
			*cp = '\0';
			host = ++cp;
		} else
			host = *av;
		if (ac > 1) {
			optind = optreset = 1;
			goto again;
		}
		ac--, av++;
	}

	/* Check that we got a host name. */
	if (!host)
		usage();

	OpenSSL_add_all_algorithms();
	ERR_load_crypto_strings();

	/* Initialize the command to execute on remote host. */
	buffer_init(&command);

	/*
	 * Save the command to execute on the remote host in a buffer. There
	 * is no limit on the length of the command, except by the maximum
	 * packet size.  Also sets the tty flag if there is no command.
	 */
	if (!ac) {
		/* No command specified - execute shell on a tty. */
		if (subsystem_flag) {
			fprintf(stderr,
			    "You must specify a subsystem to invoke.\n");
			usage();
		}
	} else {
		/* A command has been specified.  Store it into the buffer. */
		for (i = 0; i < ac; i++) {
			if (i)
				buffer_append(&command, " ", 1);
			buffer_append(&command, av[i], strlen(av[i]));
		}
	}

	/* Cannot fork to background if no command. */
	if (fork_after_authentication_flag && buffer_len(&command) == 0 &&
	    !no_shell_flag)
		fatal("Cannot fork into background without a command "
		    "to execute.");

	/*
	 * Initialize "log" output.  Since we are the client all output
	 * goes to stderr unless otherwise specified by -y or -E.
	 */
	if (use_syslog && logfile != NULL)
		fatal("Can't specify both -y and -E");
	if (logfile != NULL) {
		log_redirect_stderr_to(logfile);
		free(logfile);
	}
	log_init(argv0,
	    options.log_level == -1 ? SYSLOG_LEVEL_INFO : options.log_level,
	    SYSLOG_FACILITY_USER, !use_syslog);

	if (debug_flag)
		logit("%s, %s", SSH_VERSION, SSLeay_version(SSLEAY_VERSION));

	/*
	 * Read per-user configuration file.  Ignore the system wide config
	 * file if the user specifies a config file on the command line.
	 */
	if (config != NULL) {
		if (strcasecmp(config, "none") != 0 &&
		    !read_config_file(config, host, &options, SSHCONF_USERCONF))
			fatal("Can't open user config file %.100s: "
			    "%.100s", config, strerror(errno));
	} else {
		r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir,
		    _PATH_SSH_USER_CONFFILE);
		if (r > 0 && (size_t)r < sizeof(buf))
			(void)read_config_file(buf, host, &options,
			     SSHCONF_CHECKPERM|SSHCONF_USERCONF);

		/* Read systemwide configuration file after user config. */
		(void)read_config_file(_PATH_HOST_CONFIG_FILE, host,
		    &options, 0);
	}

	/* Fill configuration defaults. */
	fill_default_options(&options);

	channel_set_af(options.address_family);

	/* reinit */
	log_init(argv0, options.log_level, SYSLOG_FACILITY_USER, !use_syslog);

	if (options.request_tty == REQUEST_TTY_YES ||
	    options.request_tty == REQUEST_TTY_FORCE)
		tty_flag = 1;

	/* Allocate a tty by default if no command specified. */
	if (buffer_len(&command) == 0)
		tty_flag = options.request_tty != REQUEST_TTY_NO;

	/* Force no tty */
	if (options.request_tty == REQUEST_TTY_NO || muxclient_command != 0)
		tty_flag = 0;
	/* Do not allocate a tty if stdin is not a tty. */
	if ((!isatty(fileno(stdin)) || stdin_null_flag) &&
	    options.request_tty != REQUEST_TTY_FORCE) {
		if (tty_flag)
			logit("Pseudo-terminal will not be allocated because "
			    "stdin is not a terminal.");
		tty_flag = 0;
	}

	seed_rng();

	if (options.user == NULL)
		options.user = xstrdup(pw->pw_name);

	/* Get default port if port has not been set. */
	if (options.port == 0) {
		sp = getservbyname(SSH_SERVICE_NAME, "tcp");
		options.port = sp ? ntohs(sp->s_port) : SSH_DEFAULT_PORT;
	}

	/* preserve host name given on command line for %n expansion */
	host_arg = host;
	if (options.hostname != NULL) {
		host = percent_expand(options.hostname,
		    "h", host, (char *)NULL);
	}

	if (gethostname(thishost, sizeof(thishost)) == -1)
		fatal("gethostname: %s", strerror(errno));
	strlcpy(shorthost, thishost, sizeof(shorthost));
	shorthost[strcspn(thishost, ".")] = '\0';
	snprintf(portstr, sizeof(portstr), "%d", options.port);

	if (options.local_command != NULL) {
		debug3("expanding LocalCommand: %s", options.local_command);
		cp = options.local_command;
		options.local_command = percent_expand(cp, "d", pw->pw_dir,
		    "h", host, "l", thishost, "n", host_arg, "r", options.user,
		    "p", portstr, "u", pw->pw_name, "L", shorthost,
		    (char *)NULL);
		debug3("expanded LocalCommand: %s", options.local_command);
		free(cp);
	}

	/* Find canonic host name. */
	if (strchr(host, '.') == 0) {
		struct addrinfo hints;
		struct addrinfo *ai = NULL;
		int errgai;
		memset(&hints, 0, sizeof(hints));
		hints.ai_family = options.address_family;
		hints.ai_flags = AI_CANONNAME;
		hints.ai_socktype = SOCK_STREAM;
		errgai = getaddrinfo(host, NULL, &hints, &ai);
		if (errgai == 0) {
			if (ai->ai_canonname != NULL)
				host = xstrdup(ai->ai_canonname);
			freeaddrinfo(ai);
		}
	}

	/* force lowercase for hostkey matching */
	if (options.host_key_alias != NULL) {
		for (p = options.host_key_alias; *p; p++)
			if (isupper(*p))
				*p = (char)tolower(*p);
	}

	if (options.proxy_command != NULL &&
	    strcmp(options.proxy_command, "none") == 0) {
		free(options.proxy_command);
		options.proxy_command = NULL;
	}
	if (options.control_path != NULL &&
	    strcmp(options.control_path, "none") == 0) {
		free(options.control_path);
		options.control_path = NULL;
	}

	if (options.control_path != NULL) {
		cp = tilde_expand_filename(options.control_path,
		    original_real_uid);
		free(options.control_path);
		options.control_path = percent_expand(cp, "h", host,
		    "l", thishost, "n", host_arg, "r", options.user,
		    "p", portstr, "u", pw->pw_name, "L", shorthost,
		    (char *)NULL);
		free(cp);
	}
	if (muxclient_command != 0 && options.control_path == NULL)
		fatal("No ControlPath specified for \"-O\" command");
	if (options.control_path != NULL)
		muxclient(options.control_path);

	timeout_ms = options.connection_timeout * 1000;

	/* Open a connection to the remote host. */
	if (ssh_connect(host, &hostaddr, options.port,
	    options.address_family, options.connection_attempts, &timeout_ms,
	    options.tcp_keep_alive, 
#ifdef HAVE_CYGWIN
	    options.use_privileged_port,
#else
	    original_effective_uid == 0 && options.use_privileged_port,
#endif
	    options.proxy_command) != 0)
		exit(255);

	if (timeout_ms > 0)
		debug3("timeout: %d ms remain after connect", timeout_ms);

	/*
	 * If we successfully made the connection, load the host private key
	 * in case we will need it later for combined rsa-rhosts
	 * authentication. This must be done before releasing extra
	 * privileges, because the file is only readable by root.
	 * If we cannot access the private keys, load the public keys
	 * instead and try to execute the ssh-keysign helper instead.
	 */
	sensitive_data.nkeys = 0;
	sensitive_data.keys = NULL;
	sensitive_data.external_keysign = 0;
	if (options.rhosts_rsa_authentication ||
	    options.hostbased_authentication) {
		sensitive_data.nkeys = 7;
		sensitive_data.keys = xcalloc(sensitive_data.nkeys,
		    sizeof(Key));
		for (i = 0; i < sensitive_data.nkeys; i++)
			sensitive_data.keys[i] = NULL;

		PRIV_START;
		sensitive_data.keys[0] = key_load_private_type(KEY_RSA1,
		    _PATH_HOST_KEY_FILE, "", NULL, NULL);
		sensitive_data.keys[1] = key_load_private_cert(KEY_DSA,
		    _PATH_HOST_DSA_KEY_FILE, "", NULL);
#ifdef OPENSSL_HAS_ECC
		sensitive_data.keys[2] = key_load_private_cert(KEY_ECDSA,
		    _PATH_HOST_ECDSA_KEY_FILE, "", NULL);
#endif
		sensitive_data.keys[3] = key_load_private_cert(KEY_RSA,
		    _PATH_HOST_RSA_KEY_FILE, "", NULL);
		sensitive_data.keys[4] = key_load_private_type(KEY_DSA,
		    _PATH_HOST_DSA_KEY_FILE, "", NULL, NULL);
#ifdef OPENSSL_HAS_ECC
		sensitive_data.keys[5] = key_load_private_type(KEY_ECDSA,
		    _PATH_HOST_ECDSA_KEY_FILE, "", NULL, NULL);
#endif
		sensitive_data.keys[6] = key_load_private_type(KEY_RSA,
		    _PATH_HOST_RSA_KEY_FILE, "", NULL, NULL);
		PRIV_END;

		if (options.hostbased_authentication == 1 &&
		    sensitive_data.keys[0] == NULL &&
		    sensitive_data.keys[4] == NULL &&
		    sensitive_data.keys[5] == NULL &&
		    sensitive_data.keys[6] == NULL) {
			sensitive_data.keys[1] = key_load_cert(
			    _PATH_HOST_DSA_KEY_FILE);
#ifdef OPENSSL_HAS_ECC
			sensitive_data.keys[2] = key_load_cert(
			    _PATH_HOST_ECDSA_KEY_FILE);
#endif
			sensitive_data.keys[3] = key_load_cert(
			    _PATH_HOST_RSA_KEY_FILE);
			sensitive_data.keys[4] = key_load_public(
			    _PATH_HOST_DSA_KEY_FILE, NULL);
#ifdef OPENSSL_HAS_ECC
			sensitive_data.keys[5] = key_load_public(
			    _PATH_HOST_ECDSA_KEY_FILE, NULL);
#endif
			sensitive_data.keys[6] = key_load_public(
			    _PATH_HOST_RSA_KEY_FILE, NULL);
			sensitive_data.external_keysign = 1;
		}
	}
	/*
	 * Get rid of any extra privileges that we may have.  We will no
	 * longer need them.  Also, extra privileges could make it very hard
	 * to read identity files and other non-world-readable files from the
	 * user's home directory if it happens to be on a NFS volume where
	 * root is mapped to nobody.
	 */
	if (original_effective_uid == 0) {
		PRIV_START;
		permanently_set_uid(pw);
	}

	/*
	 * Now that we are back to our own permissions, create ~/.ssh
	 * directory if it doesn't already exist.
	 */
	if (config == NULL) {
		r = snprintf(buf, sizeof buf, "%s%s%s", pw->pw_dir,
		    strcmp(pw->pw_dir, "/") ? "/" : "", _PATH_SSH_USER_DIR);
		if (r > 0 && (size_t)r < sizeof(buf) && stat(buf, &st) < 0) {
#ifdef WITH_SELINUX
			ssh_selinux_setfscreatecon(buf);
#endif
			if (mkdir(buf, 0700) < 0)
				error("Could not create directory '%.200s'.",
				    buf);
#ifdef WITH_SELINUX
			ssh_selinux_setfscreatecon(NULL);
#endif
		}
	}
	/* load options.identity_files */
	load_public_identity_files();

	/* Expand ~ in known host file names. */
	tilde_expand_paths(options.system_hostfiles,
	    options.num_system_hostfiles);
	tilde_expand_paths(options.user_hostfiles, options.num_user_hostfiles);

	signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE early */
	signal(SIGCHLD, main_sigchld_handler);

	/* Log into the remote system.  Never returns if the login fails. */
	ssh_login(&sensitive_data, host, (struct sockaddr *)&hostaddr,
	    options.port, pw, timeout_ms);

	if (packet_connection_is_on_socket()) {
		verbose("Authenticated to %s ([%s]:%d).", host,
		    get_remote_ipaddr(), get_remote_port());
	} else {
		verbose("Authenticated to %s (via proxy).", host);
	}

	/* We no longer need the private host keys.  Clear them now. */
	if (sensitive_data.nkeys != 0) {
		for (i = 0; i < sensitive_data.nkeys; i++) {
			if (sensitive_data.keys[i] != NULL) {
				/* Destroys contents safely */
				debug3("clear hostkey %d", i);
				key_free(sensitive_data.keys[i]);
				sensitive_data.keys[i] = NULL;
			}
		}
		free(sensitive_data.keys);
	}
	for (i = 0; i < options.num_identity_files; i++) {
		free(options.identity_files[i]);
		options.identity_files[i] = NULL;
		if (options.identity_keys[i]) {
			key_free(options.identity_keys[i]);
			options.identity_keys[i] = NULL;
		}
	}

	exit_status = compat20 ? ssh_session2() : ssh_session();
	packet_close();

	if (options.control_path != NULL && muxserver_sock != -1)
		unlink(options.control_path);

	/* Kill ProxyCommand if it is running. */
	ssh_kill_proxy_command();

	return exit_status;
}
Beispiel #15
0
int
ssh_ecdsa_verify(const Key *key, const u_char *signature, u_int signaturelen,
    const u_char *data, u_int datalen)
{
	ECDSA_SIG *sig;
	const EVP_MD *evp_md;
	EVP_MD_CTX md;
	u_char digest[EVP_MAX_MD_SIZE], *sigblob;
	u_int len, dlen;
	int rlen, ret;
	Buffer b, bb;
	char *ktype;

	if (key == NULL || key->ecdsa == NULL ||
	    (key->type != KEY_ECDSA && key->type != KEY_ECDSA_CERT)) {
		error("%s: no ECDSA key", __func__);
		return -1;
	}
	evp_md = key_ec_nid_to_evpmd(key->ecdsa_nid);

	/* fetch signature */
	buffer_init(&b);
	buffer_append(&b, signature, signaturelen);
	ktype = buffer_get_string(&b, NULL);
	if (strcmp(key_ssh_name_plain(key), ktype) != 0) {
		error("%s: cannot handle type %s", __func__, ktype);
		buffer_free(&b);
		free(ktype);
		return -1;
	}
	free(ktype);
	sigblob = buffer_get_string(&b, &len);
	rlen = buffer_len(&b);
	buffer_free(&b);
	if (rlen != 0) {
		error("%s: remaining bytes in signature %d", __func__, rlen);
		free(sigblob);
		return -1;
	}

	/* parse signature */
	if ((sig = ECDSA_SIG_new()) == NULL)
		fatal("%s: ECDSA_SIG_new failed", __func__);
	if ((sig->r = BN_new()) == NULL ||
	    (sig->s = BN_new()) == NULL)
		fatal("%s: BN_new failed", __func__);

	buffer_init(&bb);
	buffer_append(&bb, sigblob, len);
	buffer_get_bignum2(&bb, sig->r);
	buffer_get_bignum2(&bb, sig->s);
	if (buffer_len(&bb) != 0)
		fatal("%s: remaining bytes in inner sigblob", __func__);
	buffer_free(&bb);

	/* clean up */
	memset(sigblob, 0, len);
	free(sigblob);

	/* hash the data */
	EVP_DigestInit(&md, evp_md);
	EVP_DigestUpdate(&md, data, datalen);
	EVP_DigestFinal(&md, digest, &dlen);

	ret = ECDSA_do_verify(digest, dlen, sig, key->ecdsa);
	memset(digest, 'd', sizeof(digest));

	ECDSA_SIG_free(sig);

	debug("%s: signature %s", __func__,
	    ret == 1 ? "correct" : ret == 0 ? "incorrect" : "error");
	return ret;
}
Beispiel #16
0
int
ssh_dss_verify(const Key *key, const u_char *signature, u_int signaturelen,
    const u_char *data, u_int datalen)
{
	DSA_SIG *sig;
	const EVP_MD *evp_md = EVP_sha1();
	EVP_MD_CTX md;
	u_char digest[EVP_MAX_MD_SIZE], *sigblob;
	u_int len, dlen;
	int rlen, ret;
	Buffer b;

	if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) {
		error("ssh_dss_verify: no DSA key");
		return -1;
	}

	/* fetch signature */
	if (datafellows & SSH_BUG_SIGBLOB) {
		sigblob = xmalloc(signaturelen);
		memcpy(sigblob, signature, signaturelen);
		len = signaturelen;
	} else {
		/* ietf-drafts */
		char *ktype;
		buffer_init(&b);
		buffer_append(&b, signature, signaturelen);
		ktype = buffer_get_string(&b, NULL);
		if (strcmp("ssh-dss", ktype) != 0) {
			error("ssh_dss_verify: cannot handle type %s", ktype);
			buffer_free(&b);
			xfree(ktype);
			return -1;
		}
		xfree(ktype);
		sigblob = buffer_get_string(&b, &len);
		rlen = buffer_len(&b);
		buffer_free(&b);
		if (rlen != 0) {
			error("ssh_dss_verify: "
			    "remaining bytes in signature %d", rlen);
			xfree(sigblob);
			return -1;
		}
	}

	if (len != SIGBLOB_LEN) {
		fatal("bad sigbloblen %u != SIGBLOB_LEN", len);
	}

	/* parse signature */
	if ((sig = DSA_SIG_new()) == NULL)
		fatal("ssh_dss_verify: DSA_SIG_new failed");
	if ((sig->r = BN_new()) == NULL)
		fatal("ssh_dss_verify: BN_new failed");
	if ((sig->s = BN_new()) == NULL)
		fatal("ssh_dss_verify: BN_new failed");
	if ((BN_bin2bn(sigblob, INTBLOB_LEN, sig->r) == NULL) ||
	    (BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, sig->s) == NULL))
		fatal("ssh_dss_verify: BN_bin2bn failed");

	/* clean up */
	memset(sigblob, 0, len);
	xfree(sigblob);

	/* sha1 the data */
	EVP_DigestInit(&md, evp_md);
	EVP_DigestUpdate(&md, data, datalen);
	EVP_DigestFinal(&md, digest, &dlen);

	ret = DSA_do_verify(digest, dlen, sig, key->dsa);
	memset(digest, 'd', sizeof(digest));

	DSA_SIG_free(sig);

	debug("ssh_dss_verify: signature %s",
	    ret == 1 ? "correct" : ret == 0 ? "incorrect" : "error");
	return ret;
}
int
build_presentation_page (struct ushare_t *ut)
{
  int i;
  char *mycodeset = NULL;
  char infoBuf[256];
  FILE *disk = NULL;
  char *ptr;
  long diskSize = 0;
  long freeSpace = 0;
  long useSpace = 0;
  extern int scanDir_flag;

  if (!ut)
    return -1;

  if (ut->presentation)
    buffer_free (ut->presentation);
  ut->presentation = buffer_new ();

#if HAVE_LANGINFO_CODESET
  mycodeset = nl_langinfo (CODESET);
#endif
  if (!mycodeset)
    mycodeset = UTF8;

  buffer_append (ut->presentation, "<html>");
  
  buffer_append (ut->presentation, "<head>");
  buffer_appendf (ut->presentation, "<title>%s</title>",
                 _("uShare Information Page"));
  buffer_appendf (ut->presentation,
                  "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=%s\"/>",
                  mycodeset);
  buffer_append (ut->presentation,
                 "<meta http-equiv=\"pragma\" content=\"no-cache\"/>");
  buffer_append (ut->presentation,
                 "<meta http-equiv=\"expires\" content=\"1970-01-01\"/>");
  buffer_append (ut->presentation, "</head>");
  buffer_append (ut->presentation, "<body onLoad=\"preload()\">");
  buffer_append (ut->presentation,"<script language=\"javascript\">\nfunction preload(){}\n");
  buffer_append (ut->presentation,"function showhide(what){\nif (what.style.display=='none'){what.style.display='';}\nelse{what.style.display='none'}}\n</script>");
  
  
  
  buffer_append (ut->presentation, "<h1 align=\"center\">");
  buffer_appendf (ut->presentation, "<tt>%s</tt><br/>",
                  _("DLNA/UPnP A/V Media Server"));
  buffer_append (ut->presentation, _("Information Page"));
  buffer_append (ut->presentation, "</h1>");
  buffer_append (ut->presentation, "<br/>");

	buffer_append (ut->presentation, "<center>");
  buffer_append (ut->presentation, "<tr width=\"500\">");
  buffer_appendf (ut->presentation, "<b>%s :</b> %s<br/>",
                  _("Version"), VERSION);
  buffer_append (ut->presentation, "</tr>");
  buffer_appendf (ut->presentation, "<b>%s :</b> %s<br/>",
                  _("Device UDN"), ut->udn);
  buffer_appendf (ut->presentation, "<b>%s :</b> %d<br/>",
                  _("Number of shared files and directories"), ut->nr_entries);
  buffer_append (ut->presentation, "</center><br/>");
///
	buffer_append (ut->presentation, "<center>");
	buffer_append (ut->presentation, "<table border=2 cellspacing=5 cellpadding=5 align=\"center\">");
	buffer_append (ut->presentation, "<tr><td>Disk Information</td>");
	if( (videoIn.cameraname == NULL) )
	{
		buffer_append (ut->presentation, "<td>Webcam does not initialize!</td></tr>");
	}
	else
	{
		buffer_appendf (ut->presentation, "<td>Found a webcam: <b>%s</b></td></tr>",videoIn.cameraname);
	}
	buffer_append (ut->presentation, "<tr><td>");
	//disk info
	system( "df /dev/sda1 > /tmp/diskinfo" );
	bzero( infoBuf,sizeof(infoBuf) );
	disk = fopen( "/tmp/diskinfo", "r" );
	if( disk )
	{
		fgets( infoBuf, sizeof( infoBuf), disk );bzero( infoBuf,sizeof(infoBuf) );
		if(!feof(disk))
			fgets( infoBuf, sizeof( infoBuf), disk );
		if( *infoBuf != '\0' )
		{
			ptr = strtok( infoBuf, " \n" );
			if( ptr != NULL ) ptr = strtok( NULL, " \n" );
			if( ptr != NULL ) { diskSize = atoi( ptr ); ptr = strtok( NULL, " \n" ); }
			if( ptr != NULL ) { useSpace = atoi( ptr ); ptr = strtok( NULL, " \n" ); }
			if( ptr != NULL ) { freeSpace = atoi( ptr ); ptr = strtok( NULL, " \n" ); }
			while( ptr )
				ptr = strtok( NULL, " \n" ); 
		}
		buffer_appendf (ut->presentation, "<b>Disk space size:</b> %dKB<br>",diskSize);
		buffer_appendf (ut->presentation, "<b>Used space size:</b> %dKB<br>",useSpace);
		buffer_appendf (ut->presentation, "<b>Free space size:</b> %dKB<br>",freeSpace);
		int picT = freeSpace/8;
		int movT = freeSpace/80;
		buffer_appendf (ut->presentation, "May store up <b>%d</b> pictures or <b>%d</b> second movies<br>",picT, movT);
		fclose( disk );
		disk = NULL;
		diskSize = 0;
		useSpace = 0;
		freeSpace = 0;
	}
	if( scanDir_flag )
	{
		buffer_append (ut->presentation, "Building metadata list, please wait few minute.<br>");
	}
	else
	{
		buffer_append (ut->presentation, "<p align=\"left\">");
		build_item_tree(ut, ut->root_entry, 0);
		buffer_append (ut->presentation, "</p>");
	}
	//
  buffer_append (ut->presentation, "</td>");
  
	
	if( (videoIn.cameraname != NULL) && (capFlag ==1) )
	{
		buffer_append (ut->presentation, "<td>");
		buffer_appendf (ut->presentation, "<applet codebase=\"http://%s/webcam/\" ",ut->ip);
		buffer_append (ut->presentation, "archive=\"webcam.jar\" code=\"webcamplayer/Main.class\" name=\"WebcamPlayer\"  align=\"center\" width=\"352\" height=\"570\">");

		buffer_appendf (ut->presentation, "<param name=\"Server\" value=\"%s\">",ut->ip);
		buffer_append (ut->presentation, "<param name=\"Port\" value=\"7070\">");

		buffer_append (ut->presentation, "<strong>You need to download Java.<br>");
		buffer_append (ut->presentation, "Click <a href=\"http://www.java.com/en/download/manual.jsp\">here:");
		buffer_append (ut->presentation, "http://www.java.com/en/download/manual.jsp</a></strong><br>");
		buffer_append (ut->presentation, "</applet>");
		if( (videoIn.cameraname != NULL) && (capFlag ==1) )
		{
			
			buffer_appendf (ut->presentation,
		              "<form method=\"get\" action=\"%s\">", USHARE_CGI);
			buffer_appendf (ut->presentation,
						      "<input type=\"hidden\" name=\"action\" value=\"%s\"/>",
						      CGI_WebCam_Stop);
			buffer_appendf (ut->presentation, "<input type=\"submit\" value=\"%s\"/>",
						      _("Stop the webcam"));
			buffer_append (ut->presentation, "</form>");
		
		}
		buffer_append (ut->presentation, "</td></tr>");
	}
	else
	{
		buffer_append (ut->presentation, "<td>");
		buffer_appendf (ut->presentation,
                  "<form method=\"get\" action=\"%s\">", USHARE_CGI);
		buffer_appendf (ut->presentation,
				          "<input type=\"hidden\" name=\"action\" value=\"%s\"/>",
				          CGI_WebCam_Start);
		if(videoIn.cameraname == NULL)
		buffer_appendf (ut->presentation, "<input type=\"submit\" value=\"%s\"/>",
				          _("Detect Webcam and start it"));
	    else
	    	buffer_appendf (ut->presentation, "<input type=\"submit\" value=\"%s\"/>",
				          _("Start webcam stream server"));
		buffer_append (ut->presentation, "</form>");
		if( capOK == 1 )
		{
			buffer_append (ut->presentation, "Can't found any webcam or not support");
			capOK = 0;
		}
		
		
		buffer_append (ut->presentation, "</td></tr>");
	}
	//upload file
	/*buffer_append (ut->presentation, "<td>");
	buffer_append (ut->presentation,"<form enctype=\"multipart/form-data\"  method=\"post\" >");
	buffer_append (ut->presentation,"<input type=\"file\" name=\"file\" size=\"20\" >");
	buffer_append (ut->presentation,_("<input type=\"Submit\" name=\"Submit\" value=\"Upload\">") );
	buffer_append (ut->presentation, "</form>");
	buffer_append (ut->presentation, "</td>");*/
	//
	buffer_append (ut->presentation, "</table>");
	//ushare
	/*buffer_appendf (ut->presentation,
                  "<form method=\"get\" action=\"%s\">", USHARE_CGI);
	buffer_appendf (ut->presentation,
	                "<input type=\"hidden\" name=\"action\" value=\"%s\"/>",
	                CGI_ACTION_DEL);
	for (i = 0 ; i < ut->contentlist->count ; i++)
	{
	buffer_appendf (ut->presentation, "<b>%s #%d :</b>", _("Share"), i + 1);
	buffer_appendf (ut->presentation,
	                "<input type=\"checkbox\" name=\""CGI_SHARE"[%d]\"/>", i);
	buffer_appendf (ut->presentation, "%s<br/>", ut->contentlist->content[i]);
	}
	buffer_appendf (ut->presentation,
	                "<input type=\"submit\" value=\"%s\"/>", _("unShare!"));
	buffer_append (ut->presentation, "</form>");
	buffer_append (ut->presentation, "<br/>");*/

	buffer_appendf (ut->presentation,
	                "<form method=\"get\" action=\"%s\">", USHARE_CGI);
	buffer_append (ut->presentation, _("Add a new share :  "));
	buffer_appendf (ut->presentation,
	                "<input type=\"hidden\" name=\"action\" value=\"%s\"/>",
	                CGI_ACTION_ADD);
	buffer_append (ut->presentation, "<input type=\"text\" name=\""CGI_PATH"\"/>");
	buffer_appendf (ut->presentation,
	                "<input type=\"submit\" value=\"%s\"/>", _("Share!"));
	buffer_append (ut->presentation, "</form>");

	buffer_append (ut->presentation, "<br/>");

	buffer_appendf (ut->presentation,
	                "<form method=\"get\" action=\"%s\">", USHARE_CGI);
	buffer_appendf (ut->presentation,
	                "<input type=\"hidden\" name=\"action\" value=\"%s\"/>",
	                CGI_ACTION_REFRESH);
	buffer_appendf (ut->presentation, "<input type=\"submit\" value=\"%s\"/>",
	                _("Refresh Shares ..."));
	buffer_append (ut->presentation, "</form>");
	///
	buffer_append (ut->presentation, "</center>");
///
  

  
  buffer_append (ut->presentation, "</center>");

  buffer_append (ut->presentation, "</body>");
  buffer_append (ut->presentation, "</html>");

  return 0;
}
Beispiel #18
0
static int
userauth_pubkey(Authctxt *authctxt)
{
	Buffer b;
	Key *key = NULL;
	char *pkalg, *userstyle;
	u_char *pkblob, *sig;
	u_int alen, blen, slen;
	int have_sig, pktype;
	int authenticated = 0;

	if (!authctxt->valid) {
		debug2("userauth_pubkey: disabled because of invalid user");
		return 0;
	}
	have_sig = packet_get_char();
	if (datafellows & SSH_BUG_PKAUTH) {
		debug2("userauth_pubkey: SSH_BUG_PKAUTH");
		/* no explicit pkalg given */
		pkblob = packet_get_string(&blen);
		buffer_init(&b);
		buffer_append(&b, pkblob, blen);
		/* so we have to extract the pkalg from the pkblob */
		pkalg = buffer_get_string(&b, &alen);
		buffer_free(&b);
	} else {
		pkalg = packet_get_string(&alen);
		pkblob = packet_get_string(&blen);
	}
	pktype = key_type_from_name(pkalg);
	if (pktype == KEY_UNSPEC) {
		/* this is perfectly legal */
		logit("userauth_pubkey: unsupported public key algorithm: %s",
		    pkalg);
		goto done;
	}
	key = key_from_blob(pkblob, blen);
	if (key == NULL) {
		error("userauth_pubkey: cannot decode key: %s", pkalg);
		goto done;
	}
	if (key->type != pktype) {
		error("userauth_pubkey: type mismatch for decoded key "
		    "(received %d, expected %d)", key->type, pktype);
		goto done;
	}
	if (key_type_plain(key->type) == KEY_RSA &&
	    (datafellows & SSH_BUG_RSASIGMD5) != 0) {
		logit("Refusing RSA key because client uses unsafe "
		    "signature scheme");
		goto done;
	}
	if (have_sig) {
		sig = packet_get_string(&slen);
		packet_check_eom();
		buffer_init(&b);
		if (datafellows & SSH_OLD_SESSIONID) {
			buffer_append(&b, session_id2, session_id2_len);
		} else {
			buffer_put_string(&b, session_id2, session_id2_len);
		}
		/* reconstruct packet */
		buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
		xasprintf(&userstyle, "%s%s%s", authctxt->user,
		    authctxt->style ? ":" : "",
		    authctxt->style ? authctxt->style : "");
		buffer_put_cstring(&b, userstyle);
		free(userstyle);
		buffer_put_cstring(&b,
		    datafellows & SSH_BUG_PKSERVICE ?
		    "ssh-userauth" :
		    authctxt->service);
		if (datafellows & SSH_BUG_PKAUTH) {
			buffer_put_char(&b, have_sig);
		} else {
			buffer_put_cstring(&b, "publickey");
			buffer_put_char(&b, have_sig);
			buffer_put_cstring(&b, pkalg);
		}
		buffer_put_string(&b, pkblob, blen);
#ifdef DEBUG_PK
		buffer_dump(&b);
#endif
		pubkey_auth_info(authctxt, key, NULL);

		/* test for correct signature */
		authenticated = 0;
		if (PRIVSEP(user_key_allowed(authctxt->pw, key)) &&
		    PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b),
		    buffer_len(&b))) == 1)
			authenticated = 1;
		buffer_free(&b);
		free(sig);
	} else {
		debug("test whether pkalg/pkblob are acceptable");
		packet_check_eom();

		/* XXX fake reply and always send PK_OK ? */
		/*
		 * XXX this allows testing whether a user is allowed
		 * to login: if you happen to have a valid pubkey this
		 * message is sent. the message is NEVER sent at all
		 * if a user is not allowed to login. is this an
		 * issue? -markus
		 */
		if (PRIVSEP(user_key_allowed(authctxt->pw, key))) {
			packet_start(SSH2_MSG_USERAUTH_PK_OK);
			packet_put_string(pkalg, alen);
			packet_put_string(pkblob, blen);
			packet_send();
			packet_write_wait();
			authctxt->postponed = 1;
		}
	}
	if (authenticated != 1)
		auth_clear_options();
done:
	debug2("userauth_pubkey: authenticated %d pkalg %s", authenticated, pkalg);
	if (key != NULL)
		key_free(key);
	free(pkalg);
	free(pkblob);
	return authenticated;
}
int
process_cgi (struct ushare_t *ut, char *cgiargs)
{
  char *action = NULL;
  int refresh = 0;

  if (!ut || !cgiargs)
    return -1;

  if (strncmp (cgiargs, CGI_ACTION, strlen (CGI_ACTION)))
    return -1;

  action = cgiargs + strlen (CGI_ACTION);

  if (!strncmp (action, CGI_ACTION_ADD, strlen (CGI_ACTION_ADD)))
  {
    char *path = NULL;
    path = action + strlen (CGI_ACTION_ADD) + 1;

    if (path && !strncmp (path, CGI_PATH"=", strlen (CGI_PATH) + 1))
    {
      ut->contentlist = content_add (ut->contentlist,
                                     path + strlen (CGI_PATH) + 1);
      refresh = 1;
    }
  }
  else if (!strncmp (action, CGI_ACTION_DEL, strlen (CGI_ACTION_DEL)))
  {
    char *shares,*share;
    char *m_buffer = NULL, *buffer;
    int num, shift=0;

    shares = strdup (action + strlen (CGI_ACTION_DEL) + 1);
    m_buffer = (char*) malloc (strlen (shares) * sizeof (char));
    if (m_buffer)
    {
      buffer = m_buffer;
      for (share = strtok_r (shares, "&", &buffer) ; share ;
           share = strtok_r (NULL, "&", &buffer))
      {
        if (sscanf (share, CGI_SHARE"[%d]=on", &num) < 0)
          continue;
        ut->contentlist = content_del (ut->contentlist, num - shift++);
      }
      free (m_buffer);
    }

    refresh = 1;
    free (shares);
  }
  else if (!strncmp (action, CGI_ACTION_REFRESH, strlen (CGI_ACTION_REFRESH)))
    refresh = 1;
  else if (!strncmp (action, CGI_WebCam_Start, strlen (CGI_WebCam_Start)))
  {
  	  extern pthread_mutex_t grab_ctrl_mutex;
  	  extern pthread_cond_t grab_ctrl_cond;
	  if( videoIn.cameraname == NULL )
	  {
	  	if( init_dev(WebCam_DEV, 0)== 0)
	  	{
			pthread_mutex_lock (&grab_ctrl_mutex);
			pthread_cond_signal (&grab_ctrl_cond);
			pthread_mutex_unlock (&grab_ctrl_mutex);
			capFlag = 1;capOK = 0;
	  	}
	  	else
	  	{
	  		close_v4l(&videoIn);
	  		memset (&videoIn, 0, sizeof (struct vdIn));
	  		capFlag = 0;capOK = 1;
	  	}
  	  }
  	  else
  	  {
  	  		pthread_mutex_lock (&grab_ctrl_mutex);
			pthread_cond_signal (&grab_ctrl_cond);
			pthread_mutex_unlock (&grab_ctrl_mutex);
			capFlag = 1;capOK = 0;
  	  }
  	
  }
  else if (!strncmp (action, CGI_WebCam_Stop, strlen (CGI_WebCam_Stop)))
  {
  	extern int webcam_exit_flag,Pic_exit_flag, Mov_exit_flag;
  	extern pthread_mutex_t Pic_mutex,Mov_mutex;
  	extern pthread_cond_t Mov_cond,Pic_cond;
  	capFlag = 0;
  	if( videoIn.cameraname != NULL )
  	{
		 webcam_exit_flag = 1;
		 if( Pic_exit_flag == 1 )
		 {
		 	pthread_mutex_lock (&Pic_mutex);
			pthread_cond_signal (&Pic_cond);
			pthread_mutex_unlock (&Pic_mutex);
		 }
		 else
		 	Pic_exit_flag = 1;
		 if( Mov_exit_flag == 1 )
		 {
		 	pthread_mutex_lock (&Mov_mutex);
			pthread_cond_signal (&Mov_cond);
			pthread_mutex_unlock (&Mov_mutex);
		 }
		 else
		 	Mov_exit_flag = 1;
	}
  	
  }
  extern int scanDir_flag;
  if (refresh && ut->contentlist && !scanDir_flag)
  {
  	scanDir_flag = 1;
    free_metadata_list (ut);
    build_metadata_list (ut);
    scanDir_flag = 0;
  }

  if (ut->presentation)
    buffer_free (ut->presentation);
  ut->presentation = buffer_new ();

  buffer_append (ut->presentation, "<html>");
  buffer_append (ut->presentation, "<head>");
  buffer_appendf (ut->presentation, "<title>%s</title>",
                  _("uShare Information Page"));
  buffer_append (ut->presentation,
                 "<meta http-equiv=\"pragma\" content=\"no-cache\"/>");
  buffer_append (ut->presentation,
                 "<meta http-equiv=\"expires\" content=\"1970-01-01\"/>");
  buffer_append (ut->presentation,
                 "<meta http-equiv=\"refresh\" content=\"0; URL=/web/ushare.html\"/>");
  buffer_append (ut->presentation, "</head>");
  buffer_append (ut->presentation, "</html>");

  return 0;
}
char *
ssh_gssapi_kex_mechs(gss_OID_set gss_supported, ssh_gssapi_check_fn *check,
    const char *data) {
	Buffer buf;
	size_t i;
	int oidpos, enclen;
	char *mechs, *encoded;
	u_char digest[EVP_MAX_MD_SIZE];
	char deroid[2];
	const EVP_MD *evp_md = EVP_md5();
	EVP_MD_CTX md;

	if (gss_enc2oid != NULL) {
		for (i = 0; gss_enc2oid[i].encoded != NULL; i++)
			xfree(gss_enc2oid[i].encoded);
		xfree(gss_enc2oid);
	}

	gss_enc2oid = xmalloc(sizeof(ssh_gss_kex_mapping) *
	    (gss_supported->count + 1));

	buffer_init(&buf);

	oidpos = 0;
	for (i = 0; i < gss_supported->count; i++) {
		if (gss_supported->elements[i].length < 128 &&
		    (*check)(NULL, &(gss_supported->elements[i]), data)) {

			deroid[0] = SSH_GSS_OIDTYPE;
			deroid[1] = gss_supported->elements[i].length;

			EVP_DigestInit(&md, evp_md);
			EVP_DigestUpdate(&md, deroid, 2);
			EVP_DigestUpdate(&md,
			    gss_supported->elements[i].elements,
			    gss_supported->elements[i].length);
			EVP_DigestFinal(&md, digest, NULL);

			encoded = xmalloc(EVP_MD_size(evp_md) * 2);
			enclen = __b64_ntop(digest, EVP_MD_size(evp_md),
			    encoded, EVP_MD_size(evp_md) * 2);

			if (oidpos != 0)
				buffer_put_char(&buf, ',');

			buffer_append(&buf, KEX_GSS_GEX_SHA1_ID,
			    sizeof(KEX_GSS_GEX_SHA1_ID) - 1);
			buffer_append(&buf, encoded, enclen);
			buffer_put_char(&buf, ',');
			buffer_append(&buf, KEX_GSS_GRP1_SHA1_ID, 
			    sizeof(KEX_GSS_GRP1_SHA1_ID) - 1);
			buffer_append(&buf, encoded, enclen);
			buffer_put_char(&buf, ',');
			buffer_append(&buf, KEX_GSS_GRP14_SHA1_ID,
			    sizeof(KEX_GSS_GRP14_SHA1_ID) - 1);
			buffer_append(&buf, encoded, enclen);

			gss_enc2oid[oidpos].oid = &(gss_supported->elements[i]);
			gss_enc2oid[oidpos].encoded = encoded;
			oidpos++;
		}
	}
	gss_enc2oid[oidpos].oid = NULL;
	gss_enc2oid[oidpos].encoded = NULL;

	buffer_put_char(&buf, '\0');

	mechs = xmalloc(buffer_len(&buf));
	buffer_get(&buf, mechs, buffer_len(&buf));
	buffer_free(&buf);

	if (strlen(mechs) == 0) {
		xfree(mechs);
		mechs = NULL;
	}
	
	return (mechs);
}
Beispiel #21
0
int main() {
  struct tm t;
  time_t zero = 0;
  struct buffer b[1];

  buffer_init(b);
  assert(b->base == NULL);
  assert(b->pos == 0);
  assert(b->size == 0);

  buffer_putc(b, 'a');
  assert(b->base != NULL);
  assert(!strncmp(b->base, "a", 1));
  assert(b->pos == 1);
  assert(b->pos < b->size);

  buffer_putc(b, 'b');
  assert(b->base != NULL);
  assert(!strncmp(b->base, "ab", 2));
  assert(b->pos == 2);
  assert(b->pos < b->size);

  buffer_append(b, "12345678901234567890");
  assert(b->base != NULL);
  assert(!strncmp(b->base, "ab12345678901234567890", 22));
  assert(b->pos == 22);
  assert(b->pos < b->size);

  buffer_append_n(b, "spong", 4);
  assert(b->base != NULL);
  assert(!strncmp(b->base, "ab12345678901234567890spon", 26));
  assert(b->pos == 26);
  assert(b->pos < b->size);

  buffer_printf(b, "%s", "");
  assert(b->base != NULL);
  assert(!strncmp(b->base, "ab12345678901234567890spon", 26));
  assert(b->pos == 26);
  assert(b->pos < b->size);

  buffer_printf(b, "%s", "123456");
  assert(b->base != NULL);
  assert(!strncmp(b->base, "ab12345678901234567890spon123456", 32));
  assert(b->pos == 32);
  assert(b->pos < b->size);
  b->pos -= 6;

  buffer_printf(b, "%s", "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
  assert(b->base != NULL);
  assert(!strncmp(b->base, "ab12345678901234567890sponABCDEFGHIJKLMNOPQRSTUVWXYZ", 52));
  assert(b->pos == 52);
  assert(b->pos < b->size);

  buffer_terminate(b);
  assert(b->base != NULL);
  assert(!strcmp(b->base, "ab12345678901234567890sponABCDEFGHIJKLMNOPQRSTUVWXYZ"));
  assert(b->pos == 52);
  assert(b->pos < b->size);

  b->pos = 0;
  gmtime_r(&zero, &t);
  buffer_strftime(b, "", &t);
  assert(b->pos == 0);
  buffer_strftime(b, "%F %T", &t);
  buffer_terminate(b);
  assert(!strcmp(b->base, "1970-01-01 00:00:00"));

  free(b->base);
  return 0;
}