예제 #1
0
파일: libnuclient.c 프로젝트: regit/nufw
/**
 * \ingroup nuclientAPI
 * Initialize TLS:
 *    - Set key filename (and test if the file does exist)
 *    - Set certificate (if key and cert. are present)
 *
 * \param session Pointer to client session
 * \param keyfile Complete path to a key file stored in PEM format (can be NULL)
 * \param certfile Complete path to a certificate file stored in PEM format (can be NULL)
 * \param err Pointer to a nuclient_error_t: which contains the error
 * \return Returns 0 on error (error description in err), 1 otherwise
 */
int nu_client_load_key(nuauth_session_t * session,
			const char *keyfile, const char *certfile,
			nuclient_error_t * err)
{
	char certstring[256];
	char keystring[256];
	char *home = nu_get_home_dir();
	int exit_on_error = 0;
	int ret;

	/* If the user specified a certficate and a key on command line,
	 * exit if we fail loading them.
	 * Elsewise, try loading certs from ~/.nufw/, but continue if we fail
	 */
	if (certfile || keyfile)
		exit_on_error = 1;

	/* compute patch keyfile */
	if (keyfile == NULL && home != NULL) {
		ret = secure_snprintf(keystring, sizeof(keystring),
				     "%s/.nufw/key.pem", home);
		if (ret)
			keyfile = keystring;
	}

	if (certfile == NULL && home != NULL) {
		ret = secure_snprintf(certstring, sizeof(certstring),
				     "%s/.nufw/cert.pem", home);
		if (ret)
			certfile = certstring;
	}

	if (certfile != NULL || keyfile != NULL) {
		ret = nussl_ssl_set_keypair(session->nussl, certfile, keyfile);

		if (ret != NUSSL_OK) {
			if (exit_on_error) {
				if (home)
					free(home);
				SET_ERROR(err, NUSSL_ERR, ret);
				return 0;
			}
			else {
				log_printf(DEBUG_LEVEL_WARNING, "Warning: Failed to load default certificate and key.");
			}
		}
	}

	if (home)
		free(home);

	return 1;
}
예제 #2
0
char *compute_user_config_path()
{
	char path_dir[254];
	char *home = nu_get_home_dir();
	if (home == NULL)
		return NULL;
	secure_snprintf(path_dir, sizeof(path_dir), "%s/.nufw", home);
	if (access(path_dir, R_OK) != 0) {
		return NULL;
	}
	secure_snprintf(path_dir, sizeof(path_dir), "%s/.nufw/ufwiclient.conf", home);
	free(home);
	if (access(path_dir, R_OK) != 0) {
		return NULL;
	}
	return strdup(path_dir);
}
예제 #3
0
파일: proc.c 프로젝트: regit/nufw
/**
 * Load program cache
 */
void prg_cache_load()
{
	char path_process[PATH_MAX];
	char path_fd[PATH_MAX];
	DIR *dirproc = NULL;
	DIR *dirfd = NULL;
	struct dirent *file;

	if (prg_cache_loaded)
		return;
	prg_cache_loaded = 1;

	/* open directory "/proc" */
	dirproc = opendir("/proc");
	if (dirproc == NULL)
		panic("Fail to open /proc directory!");

	while ((file = readdir(dirproc)) != NULL) {
#ifdef HAVE_STRUCT_DIRENT_D_TYPE
		if (file->d_type != DT_DIR)
			continue;
#endif
		if (!str_is_integer(file->d_name))
			continue;

		/* create path like "/proc/123" */
		if (!secure_snprintf
		    (path_process, sizeof(path_process), "/proc/%s",
		     file->d_name))
			continue;

		/* create path like "/proc/123/fd" */
		if (!secure_snprintf
		    (path_fd, sizeof(path_fd), "%s/fd", path_process))
			continue;

		/* open directory like "/proc/123/fd" */
		dirfd = opendir(path_fd);
		if (dirfd != NULL) {
			prg_cache_load_sub(dirfd, path_process, path_fd);
			closedir(dirfd);
		}
	}
	closedir(dirproc);
}
예제 #4
0
파일: proc.c 프로젝트: regit/nufw
/**
 * Walk in directoty like "/proc/123/fd/"
 */
void prg_cache_load_sub(DIR * dir, const char *path_process,
			const char *path_fd)
{
	char path[PATH_MAX];
	char lname[30];
	char finbuf[PROGNAME_WIDTH];
	unsigned long inode;
	struct dirent *file;

	while ((file = readdir(dir)) != NULL) {
#ifdef HAVE_STRUCT_DIRENT_D_TYPE
		if (file->d_type != DT_LNK)
			continue;
#endif

		/* read link of "/proc/123/fd/FILENAME" */
		if (!secure_snprintf
		    (path, sizeof(path), "%s/%s", path_fd, file->d_name))
			continue;
		if (!secure_readlink(path, lname, sizeof(lname)))
			continue;

		/*
		 * extract inode number from name like "socket:[12345]"
		 * or "[0000]:12345"
		 */
		if (extract_type_1_socket_inode(lname, &inode) < 0)
			if (extract_type_2_socket_inode(lname, &inode) < 0)
				continue;

		/* get exec fullpath */
		if (!secure_snprintf
		    (path, sizeof(path), "%s/exe", path_process))
			continue;
		if (!secure_readlink(path, finbuf, sizeof(finbuf)))
			continue;

		/* add item to the cache */
		prg_cache_add(inode, finbuf);
	}
}
예제 #5
0
파일: libnuclient.c 프로젝트: regit/nufw
/**
 * \ingroup nuclientAPI
 * Initialize TLS:
 *    - Set trust file of credentials (if needed)
 *
 * \param session Pointer to client session
 * \param cafile Complete path to a certificate authority file stored in PEM format (can be NULL)
 * \param err Pointer to a nuclient_error_t: which contains the error
 * \return Returns 0 on error (error description in err), 1 otherwise
 */
int nu_client_load_ca(nuauth_session_t * session,
			const char *cafile,
			nuclient_error_t * err)
{
	char castring[256];
	char *home = nu_get_home_dir();
	int exit_on_error = 0;
	int ret;

	if (cafile != NULL)
		exit_on_error = 1;

	if (cafile == NULL && home != NULL) {
		ret = secure_snprintf(castring, sizeof(castring),
				     "%s/.nufw/cacert.pem", home);
		if (ret)
			cafile = castring;
	}

	if (cafile != NULL) {
		ret = nussl_ssl_trust_cert_file(session->nussl, cafile);
		if (ret != NUSSL_OK) {
			if (exit_on_error) {
				if (home)
					free(home);
				SET_ERROR(err, NUSSL_ERR, ret);
				return 0;
			}
			else {
				if (!session->suppress_ca_warning) {
					log_printf(DEBUG_LEVEL_WARNING, "\nWARNING: you have not provided any certificate authority.\n"
							"nutcpc will *NOT* verify server certificate trust.\n"
							"Use the -A <cafile> option to set up CA.\n"
					       );
				}
				session->suppress_fqdn_verif = 1;
				nussl_set_session_flag(session->nussl, NUSSL_SESSFLAG_IGNORE_ID_MISMATCH, 1);
			}
		}
	} else {
		log_printf(DEBUG_LEVEL_WARNING, "Could not load any CA !");
		return 0;
	}
	return 1;
}
예제 #6
0
파일: tcptable.c 프로젝트: maximerobin/Ufwi
/**
 * Parse a Linux connection table (/proc/net/tcp or /proc/net/udp) and filter
 * connection: only keep session user connections in state "SYN packet sent".
 * Add connections to the our table using tcptable_add().
 */
int parse_tcptable_file(nuauth_session_t * session, conntable_t * ct, char *filename,
			FILE ** file, int protocol, int use_ipv6)
{
	char *buf;
	char fullbuf[1024*256];
	conn_t c;
	const char state_char = '2';	/* TCP_SYN_SENT written in hexadecimal */
	int state_pos;
	int uid_pos;
	char session_uid[20];
	int session_uid_len;
	int ret;
	char *pos;
	int fdfile;
	int i = 0;
	int readlen = 0;

	fdfile = open(filename, O_RDONLY);
	if (fdfile == -1) {
		panic("Unable to open proc file");
	}
	/* read all file */
	buf = fullbuf;
	while ( ((1024*256 - (buf - fullbuf)) > 0) &&
		(i = read(fdfile, buf, 1024*256 - (buf - fullbuf)))) {
		buf += i;
		readlen += i;
	}
	close(fdfile);

	/* convert session user identifier to string */
	secure_snprintf(session_uid, sizeof(session_uid), "%5lu",
			(long)session->userid);
	session_uid_len = strlen(session_uid);

	/* get state field position in header */
	pos = strstr(fullbuf, " st ");
	if (pos == NULL)
		panic
		    ("Can't find position of state field in /proc/net/tcp header!");
	state_pos = pos - fullbuf + 2;

	/* get user identifier position in header (it's just after 'retrnsmt' field) */
	pos = strstr(fullbuf, " retrnsmt ");
	if (pos == NULL)
		panic
		    ("Can't find position of user identifier field in /proc/net/tcp header!");
	uid_pos = pos - fullbuf + strlen(" retrnsmt ");

	buf = fullbuf;
	while (buf - fullbuf < readlen - uid_pos) {

		buf = strchr(buf, '\n') + 1;
		/* only keep connections in state "SYN packet sent" */
		if (buf[state_pos] != state_char) {
			continue;
		}

		/* only keep session user connections */
		if (strncmp(buf + uid_pos, session_uid, session_uid_len) !=
		    0) {
			continue;
		}

		/* get all fields */
		if (!use_ipv6) {
			uint32_t src, dst;
			ret = sscanf(buf,
				     "%*d: "
				     "%" SCNx32 ":%hx "
				     "%" SCNx32 ":%hx "
				     "%*x %*x:%*x %*x:%*x %x "
				     "%lu %*d %lu",
				     &src, &c.port_src,
				     &dst, &c.port_dst,
				     &c.retransmit, &c.uid,
				     &c.inode);
			if (ret != 7) {
				continue;
			}
			uint32_to_ipv6(src, &c.ip_src);
			uint32_to_ipv6(dst, &c.ip_dst);
		} else {
			char ip_src[33];
			char ip_dst[33];
			ret = sscanf(buf,
				     "%*d: "
				     "%32s"
				     ":%hx "
				     "%32s"
				     ":%hx "
				     "%*x %*x:%*x %*x:%*x %x "
				     "%lu %*d %lu",
				     ip_src,
				     &c.port_src,
				     ip_dst,
				     &c.port_dst,
				     &c.retransmit, &c.uid, &c.inode);
			if (ret != 7) {
				continue;
			}
			if (!hex2ipv6(ip_src, &c.ip_src))
				continue;
			if (!hex2ipv6(ip_dst, &c.ip_dst))
				continue;
		}

		/* skip nul inodes */
		if (c.inode == 0) {
			continue;
		}
#if DEBUG
		/*  Check if there is a matching rule in the filters list */
		printf("Packet dst = %ld (%lx)\n", c.rmt, c.rmt);
#endif

		c.protocol = protocol;
		tcptable_add(ct, &c);
	}
	return 1;
}