5 * Copyright (c) 2001-2002 Maksim Yevmenkin <m_evmenkin@yahoo.com>
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * $Id: parser.y,v 1.5 2003/06/07 21:22:30 max Exp $
30 * $FreeBSD: src/usr.sbin/bluetooth/hcsecd/parser.y,v 1.4 2004/09/14 20:04:33 emax Exp $
33 #include <sys/fcntl.h>
34 #include <sys/queue.h>
35 #include <bluetooth.h>
46 #if YYPATCH < 20180510
50 static void free_key
(link_key_p key
);
51 static int hexa2int4
(char *a
);
52 static int hexa2int8
(char *a
);
54 extern
void yyerror(const char *);
58 static LIST_HEAD
(, link_key
) link_keys
;
60 const char *config_file
= "/etc/bluetooth/bthcid.conf";
61 static link_key_p key
= NULL
;
68 %token
<string> T_BDADDRSTRING T_HEXSTRING T_STRING
69 %token T_DEVICE T_BDADDR T_NAME T_KEY T_PIN T_NOKEY T_NOPIN T_JUNK
79 key
= (link_key_p
) malloc
(sizeof
(*key
));
81 syslog
(LOG_ERR
, "Could not allocate new " \
86 memset
(key
, 0, sizeof
(*key
));
90 if
(get_key
(&key
->bdaddr
, 1) != NULL
) {
91 syslog
(LOG_ERR
, "Ignoring duplicated entry " \
93 bt_ntoa
(&key
->bdaddr
, NULL
));
96 LIST_INSERT_HEAD
(&link_keys
, key
, next
);
112 bdaddr: T_BDADDR T_BDADDRSTRING
114 if
(!bt_aton
($2, &key
->bdaddr
)) {
115 syslog
(LOG_ERR
, "Could not parse BD_ADDR " \
122 name: T_NAME T_STRING
124 if
(key
->name
!= NULL
)
127 key
->name
= strdup
($2);
128 if
(key
->name
== NULL
) {
129 syslog
(LOG_ERR
, "Could not allocate new " \
136 key: T_KEY T_HEXSTRING
140 if
(key
->key
!= NULL
)
143 key
->key
= (uint8_t *) malloc
(HCI_KEY_SIZE
);
144 if
(key
->key
== NULL
) {
145 syslog
(LOG_ERR
, "Could not allocate new " \
150 memset
(key
->key
, 0, HCI_KEY_SIZE
);
152 len
= strlen
($2) / 2;
153 if
(len
> HCI_KEY_SIZE
)
156 for
(i
= 0; i
< len
; i
++)
157 key
->key
[i
] = hexa2int8
((char *)($2) + 2*i
);
161 if
(key
->key
!= NULL
)
170 if
(key
->pin
!= NULL
)
173 key
->pin
= strdup
($2);
174 if
(key
->pin
== NULL
) {
175 syslog
(LOG_ERR
, "Could not allocate new " \
182 if
(key
->pin
!= NULL
)
191 /* Display parser error message */
193 yyerror(char const *message
)
195 syslog
(LOG_ERR
, "%s in line %d", message
, yylineno
);
198 /* Re-read config file */
200 read_config_file
(void)
202 if
(config_file
== NULL
) {
203 syslog
(LOG_ERR
, "Unknown config file name!");
207 if
((yyin
= fopen
(config_file
, "r")) == NULL
) {
208 syslog
(LOG_ERR
, "Could not open config file '%s'. %s (%d)",
209 config_file
, strerror
(errno
), errno
);
215 syslog
(LOG_ERR
, "Could not parse config file '%s'",config_file
);
222 #ifdef __config_debug__
231 link_key_p lkey
= NULL
;
233 while
((lkey
= LIST_FIRST
(&link_keys
)) != NULL
) {
234 LIST_REMOVE
(lkey
, next
);
239 /* Find link key entry in the list. Return exact or default match */
241 get_key
(bdaddr_p bdaddr
, int exact_match
)
243 link_key_p lkey
= NULL
, defkey
= NULL
;
245 LIST_FOREACH
(lkey
, &link_keys
, next
) {
246 if
(memcmp
(bdaddr
, &lkey
->bdaddr
, sizeof
(lkey
->bdaddr
)) == 0)
250 if
(memcmp
(BDADDR_ANY
, &lkey
->bdaddr
,
251 sizeof
(lkey
->bdaddr
)) == 0)
255 return
((lkey
!= NULL
)? lkey
: defkey
);
258 #ifdef __config_debug__
263 link_key_p lkey
= NULL
;
266 LIST_FOREACH
(lkey
, &link_keys
, next
) {
267 if
(lkey
->key
!= NULL
)
268 snprintf
(buffer
, sizeof
(buffer
),
269 "0x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
270 lkey
->key
[0], lkey
->key
[1], lkey
->key
[2],
271 lkey
->key
[3], lkey
->key
[4], lkey
->key
[5],
272 lkey
->key
[6], lkey
->key
[7], lkey
->key
[8],
273 lkey
->key
[9], lkey
->key
[10], lkey
->key
[11],
274 lkey
->key
[12], lkey
->key
[13], lkey
->key
[14],
282 (lkey
->name
!= NULL
)? lkey
->name
: "noname",
283 bt_ntoa
(&lkey
->bdaddr
, NULL
),
284 (lkey
->pin
!= NULL
)? lkey
->pin
: "nopin",
285 (lkey
->key
!= NULL
)? buffer
: "nokey");
295 link_key_t
*lkey
= NULL
;
296 char buf
[BTHCID_BUFFER_SIZE
], *p
= NULL
, *cp
= NULL
;
300 if
((f
= fopen
(BTHCID_KEYSFILE
, "r")) == NULL
) {
304 syslog
(LOG_ERR
, "Could not open keys file %s. %s (%d)\n",
305 BTHCID_KEYSFILE
, strerror
(errno
), errno
);
310 while
((p
= fgets
(buf
, sizeof
(buf
), f
)) != NULL
) {
313 if
((cp
= strpbrk
(p
, " ")) == NULL
)
318 if
(!bt_aton
(p
, &bdaddr
))
321 if
((lkey
= get_key
(&bdaddr
, 1)) == NULL
)
324 if
(lkey
->key
== NULL
) {
325 lkey
->key
= (uint8_t *) malloc
(HCI_KEY_SIZE
);
326 if
(lkey
->key
== NULL
) {
327 syslog
(LOG_ERR
, "Could not allocate link key");
332 memset
(lkey
->key
, 0, HCI_KEY_SIZE
);
334 len
= strlen
(cp
) / 2;
335 if
(len
> HCI_KEY_SIZE
)
338 for
(i
= 0; i
< len
; i
++)
339 lkey
->key
[i
] = hexa2int8
(cp
+ 2*i
);
341 syslog
(LOG_DEBUG
, "Restored link key for the entry, " \
342 "remote bdaddr %s, name '%s'",
343 bt_ntoa
(&lkey
->bdaddr
, NULL
),
344 (lkey
->name
!= NULL
)? lkey
->name
: "No name");
356 link_key_p lkey
= NULL
;
357 char tmp
[PATH_MAX
], buf
[BTHCID_BUFFER_SIZE
];
360 snprintf
(tmp
, sizeof
(tmp
), "%s.tmp", BTHCID_KEYSFILE
);
361 if
((f
= open
(tmp
, O_RDWR|O_CREAT|O_TRUNC|O_EXCL
, 0600)) < 0) {
362 syslog
(LOG_ERR
, "Could not create temp keys file %s. %s (%d)\n",
363 tmp
, strerror
(errno
), errno
);
367 LIST_FOREACH
(lkey
, &link_keys
, next
) {
368 if
(lkey
->key
== NULL
)
371 snprintf
(buf
, sizeof
(buf
),
372 "%s %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n",
373 bt_ntoa
(&lkey
->bdaddr
, NULL
),
374 lkey
->key
[0], lkey
->key
[1], lkey
->key
[2], lkey
->key
[3],
375 lkey
->key
[4], lkey
->key
[5], lkey
->key
[6], lkey
->key
[7],
376 lkey
->key
[8], lkey
->key
[9], lkey
->key
[10], lkey
->key
[11],
377 lkey
->key
[12], lkey
->key
[13], lkey
->key
[14], lkey
->key
[15]);
379 if
(write
(f
, buf
, strlen
(buf
)) < 0) {
380 syslog
(LOG_ERR
, "Could not write temp keys file. " \
381 "%s (%d)\n", strerror
(errno
), errno
);
388 if
(rename
(tmp
, BTHCID_KEYSFILE
) < 0) {
389 syslog
(LOG_ERR
, "Could not rename(%s, %s). %s (%d)\n",
390 tmp
, BTHCID_KEYSFILE
, strerror
(errno
), errno
);
400 free_key
(link_key_p lkey
)
402 if
(lkey
->name
!= NULL
)
404 if
(lkey
->key
!= NULL
)
406 if
(lkey
->pin
!= NULL
)
409 memset
(lkey
, 0, sizeof
(*lkey
));
413 /* Convert hex ASCII to int4 */
417 if
('0' <= *a
&& *a
<= '9')
420 if
('A' <= *a
&& *a
<= 'F')
421 return
(*a
- 'A' + 0xa);
423 if
('a' <= *a
&& *a
<= 'f')
424 return
(*a
- 'a' + 0xa);
426 syslog
(LOG_ERR
, "Invalid hex character: '%c' (%#x)", *a
, *a
);
430 /* Convert hex ASCII to int8 */
434 return
((hexa2int4
(a
) << 4) | hexa2int4
(a
+ 1));