예제 #1
0
/* Signal handlers */
static void
sighup(int s)
{
	syslog(LOG_DEBUG, "Got SIGHUP (%d)", s);

	dump_keys_file();
	read_config_file();
	read_keys_file();
}
예제 #2
0
void
save_key(bdaddr_t *laddr, bdaddr_t *raddr, uint8_t * key)
{
	link_key_p	lkey = NULL;

	syslog(LOG_DEBUG, "Got Link_Key_Notification event from '%s', " \
			"remote bdaddr %s", bt_ntoa(laddr, NULL),
			bt_ntoa(raddr, NULL));

	if ((lkey = get_key(raddr, 1)) == NULL) {
		syslog(LOG_ERR, "Could not find entry for remote bdaddr %s",
				bt_ntoa(raddr, NULL));
		return;
	}
	
	syslog(LOG_DEBUG, "Updating link key for the entry, " \
			"remote bdaddr %s, name '%s', link key %s",
			bt_ntoa(&lkey->bdaddr, NULL),
			(lkey->name != NULL)? lkey->name : "No name",
			(lkey->key != NULL)? "exists" : "doesn't exist");

	if (lkey->key == NULL) {
		lkey->key = (uint8_t *) malloc(HCI_KEY_SIZE);
		if (lkey->key == NULL) {
			syslog(LOG_ERR, "Could not allocate link key");
			exit(1);
		}
	}

	memcpy(lkey->key, key, HCI_KEY_SIZE);

	dump_keys_file();
	read_config_file();
	read_keys_file();
	
	return;
}
예제 #3
0
/* Main */
int
main(int argc, char *argv[])
{
	int					 n, detach, sock;
	socklen_t				 size;
	struct sigaction			 sa;
	struct sockaddr_hci			 addr;
	struct ng_btsocket_hci_raw_filter	 filter;
	char					 buffer[HCSECD_BUFFER_SIZE];
	ng_hci_event_pkt_t			*event = NULL;

	detach = 1;

	while ((n = getopt(argc, argv, "df:h")) != -1) {
		switch (n) {
		case 'd':
			detach = 0;
			break;

		case 'f':
			config_file = optarg;
			break;

		case 'h':
		default:
			usage();
			/* NOT REACHED */
		}
	}

	if (config_file == NULL)
		usage();
		/* NOT REACHED */

	if (getuid() != 0)
		errx(1, "** ERROR: You should run %s as privileged user!",
			HCSECD_IDENT);

	/* Set signal handlers */
	memset(&sa, 0, sizeof(sa));
	sa.sa_handler = sigint;
	sa.sa_flags = SA_NOCLDWAIT;
	if (sigaction(SIGINT, &sa, NULL) < 0)
		err(1, "Could not sigaction(SIGINT)");
	if (sigaction(SIGTERM, &sa, NULL) < 0)
		err(1, "Could not sigaction(SIGINT)");

	memset(&sa, 0, sizeof(sa));
	sa.sa_handler = sighup;
	if (sigaction(SIGHUP, &sa, NULL) < 0)
		err(1, "Could not sigaction(SIGHUP)");

	/* Open socket and set filter */
	sock = socket(PF_BLUETOOTH, SOCK_RAW, BLUETOOTH_PROTO_HCI);
	if (sock < 0)
		err(1, "Could not create HCI socket");

	memset(&filter, 0, sizeof(filter));
	bit_set(filter.event_mask, NG_HCI_EVENT_PIN_CODE_REQ - 1);
	bit_set(filter.event_mask, NG_HCI_EVENT_LINK_KEY_REQ - 1);
	bit_set(filter.event_mask, NG_HCI_EVENT_LINK_KEY_NOTIFICATION - 1);

	if (setsockopt(sock, SOL_HCI_RAW, SO_HCI_RAW_FILTER,
			(void * const) &filter, sizeof(filter)) < 0)
		err(1, "Could not set HCI socket filter");

	if (detach && daemon(0, 0) < 0)
		err(1, "Could not daemon()ize");

	openlog(HCSECD_IDENT, LOG_NDELAY|LOG_PERROR|LOG_PID, LOG_DAEMON);

	read_config_file();
	read_keys_file();

	if (detach) {
		FILE	*pid = NULL;

		if ((pid = fopen(HCSECD_PIDFILE, "w")) == NULL) {
			syslog(LOG_ERR, "Could not create PID file %s. %s (%d)",
					HCSECD_PIDFILE, strerror(errno), errno);
			exit(1);
		}

		fprintf(pid, "%d", getpid());
		fclose(pid);
	}

	event = (ng_hci_event_pkt_t *) buffer;
	while (!done) {
		size = sizeof(addr);
		n = recvfrom(sock, buffer, sizeof(buffer), 0,
				(struct sockaddr *) &addr, &size);
		if (n < 0) {
			if (errno == EINTR)
				continue;

			syslog(LOG_ERR, "Could not receive from HCI socket. " \
					"%s (%d)", strerror(errno), errno);
			exit(1);
		}

		if (event->type != NG_HCI_EVENT_PKT) {
			syslog(LOG_ERR, "Received unexpected HCI packet, " \
					"type=%#x", event->type);
			continue;
		}

		switch (event->event) {
		case NG_HCI_EVENT_PIN_CODE_REQ:
			process_pin_code_request_event(sock, &addr,
							(bdaddr_p)(event + 1));
			break;

		case NG_HCI_EVENT_LINK_KEY_REQ:
			process_link_key_request_event(sock, &addr,
							(bdaddr_p)(event + 1));
			break;

		case NG_HCI_EVENT_LINK_KEY_NOTIFICATION:
			process_link_key_notification_event(sock, &addr,
				(ng_hci_link_key_notification_ep *)(event + 1));
			break;

		default:
			syslog(LOG_ERR, "Received unexpected HCI event, " \
					"event=%#x", event->event);
			break;
		}
	}

	if (detach)
		if (remove(HCSECD_PIDFILE) < 0)
			syslog(LOG_ERR, "Could not remove PID file %s. %s (%d)",
					HCSECD_PIDFILE, strerror(errno), errno);

	dump_keys_file();
	clean_config();
	closelog();
	close(sock);

	return (0);
}