11a63eb31SJulian Elischer %{ 21a63eb31SJulian Elischer /* 31a63eb31SJulian Elischer * parser.y 41a63eb31SJulian Elischer * 51a63eb31SJulian Elischer * Copyright (c) 2001-2002 Maksim Yevmenkin <m_evmenkin@yahoo.com> 61a63eb31SJulian Elischer * All rights reserved. 71a63eb31SJulian Elischer * 81a63eb31SJulian Elischer * Redistribution and use in source and binary forms, with or without 91a63eb31SJulian Elischer * modification, are permitted provided that the following conditions 101a63eb31SJulian Elischer * are met: 111a63eb31SJulian Elischer * 1. Redistributions of source code must retain the above copyright 121a63eb31SJulian Elischer * notice, this list of conditions and the following disclaimer. 131a63eb31SJulian Elischer * 2. Redistributions in binary form must reproduce the above copyright 141a63eb31SJulian Elischer * notice, this list of conditions and the following disclaimer in the 151a63eb31SJulian Elischer * documentation and/or other materials provided with the distribution. 161a63eb31SJulian Elischer * 171a63eb31SJulian Elischer * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 181a63eb31SJulian Elischer * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 191a63eb31SJulian Elischer * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 201a63eb31SJulian Elischer * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 211a63eb31SJulian Elischer * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 221a63eb31SJulian Elischer * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 231a63eb31SJulian Elischer * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 241a63eb31SJulian Elischer * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 251a63eb31SJulian Elischer * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 261a63eb31SJulian Elischer * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 271a63eb31SJulian Elischer * SUCH DAMAGE. 281a63eb31SJulian Elischer * 290986ab12SMaksim Yevmenkin * $Id: parser.y,v 1.5 2003/06/07 21:22:30 max Exp $ 301a63eb31SJulian Elischer * $FreeBSD$ 311a63eb31SJulian Elischer */ 321a63eb31SJulian Elischer 330986ab12SMaksim Yevmenkin #include <sys/fcntl.h> 341a63eb31SJulian Elischer #include <sys/queue.h> 350986ab12SMaksim Yevmenkin #include <bluetooth.h> 361a63eb31SJulian Elischer #include <errno.h> 370986ab12SMaksim Yevmenkin #include <limits.h> 381a63eb31SJulian Elischer #include <stdio.h> 39*5e2a209aSBaptiste Daroussin #include <stdlib.h> 401a63eb31SJulian Elischer #include <stdarg.h> 411a63eb31SJulian Elischer #include <string.h> 421a63eb31SJulian Elischer #include <syslog.h> 438dc77a61SMaksim Yevmenkin #include <unistd.h> 441a63eb31SJulian Elischer #include "hcsecd.h" 451a63eb31SJulian Elischer 461a63eb31SJulian Elischer int yyparse (void); 471a63eb31SJulian Elischer int yylex (void); 481a63eb31SJulian Elischer 491a63eb31SJulian Elischer static void free_key (link_key_p key); 501a63eb31SJulian Elischer static int hexa2int4(char *a); 511a63eb31SJulian Elischer static int hexa2int8(char *a); 521a63eb31SJulian Elischer 531a63eb31SJulian Elischer extern int yylineno; 541a63eb31SJulian Elischer static LIST_HEAD(, link_key) link_keys; 550986ab12SMaksim Yevmenkin char *config_file = "/etc/bluetooth/hcsecd.conf"; 561a63eb31SJulian Elischer 571a63eb31SJulian Elischer static link_key_p key = NULL; 581a63eb31SJulian Elischer %} 591a63eb31SJulian Elischer 601a63eb31SJulian Elischer %union { 611a63eb31SJulian Elischer char *string; 621a63eb31SJulian Elischer } 631a63eb31SJulian Elischer 641a63eb31SJulian Elischer %token <string> T_BDADDRSTRING T_HEXSTRING T_STRING 651a63eb31SJulian Elischer %token T_DEVICE T_BDADDR T_NAME T_KEY T_PIN T_NOKEY T_NOPIN T_JUNK 661a63eb31SJulian Elischer 671a63eb31SJulian Elischer %% 681a63eb31SJulian Elischer 691a63eb31SJulian Elischer config: line 701a63eb31SJulian Elischer | config line 711a63eb31SJulian Elischer ; 721a63eb31SJulian Elischer 731a63eb31SJulian Elischer line: T_DEVICE 741a63eb31SJulian Elischer { 751a63eb31SJulian Elischer key = (link_key_p) malloc(sizeof(*key)); 761a63eb31SJulian Elischer if (key == NULL) { 771a63eb31SJulian Elischer syslog(LOG_ERR, "Could not allocate new " \ 781a63eb31SJulian Elischer "config entry"); 791a63eb31SJulian Elischer exit(1); 801a63eb31SJulian Elischer } 811a63eb31SJulian Elischer 821a63eb31SJulian Elischer memset(key, 0, sizeof(*key)); 831a63eb31SJulian Elischer } 841a63eb31SJulian Elischer '{' options '}' 851a63eb31SJulian Elischer { 861a63eb31SJulian Elischer if (get_key(&key->bdaddr, 1) != NULL) { 871a63eb31SJulian Elischer syslog(LOG_ERR, "Ignoring duplicated entry " \ 880986ab12SMaksim Yevmenkin "for bdaddr %s", 890986ab12SMaksim Yevmenkin bt_ntoa(&key->bdaddr, NULL)); 901a63eb31SJulian Elischer free_key(key); 911a63eb31SJulian Elischer } else 921a63eb31SJulian Elischer LIST_INSERT_HEAD(&link_keys, key, next); 931a63eb31SJulian Elischer 941a63eb31SJulian Elischer key = NULL; 951a63eb31SJulian Elischer } 961a63eb31SJulian Elischer ; 971a63eb31SJulian Elischer 981a63eb31SJulian Elischer options: option ';' 991a63eb31SJulian Elischer | options option ';' 1001a63eb31SJulian Elischer ; 1011a63eb31SJulian Elischer 1021a63eb31SJulian Elischer option: bdaddr 1031a63eb31SJulian Elischer | name 1041a63eb31SJulian Elischer | key 1051a63eb31SJulian Elischer | pin 1061a63eb31SJulian Elischer ; 1071a63eb31SJulian Elischer 1081a63eb31SJulian Elischer bdaddr: T_BDADDR T_BDADDRSTRING 1091a63eb31SJulian Elischer { 1100986ab12SMaksim Yevmenkin if (!bt_aton($2, &key->bdaddr)) { 1112aa65cf7SMaksim Yevmenkin syslog(LOG_ERR, "Cound not parse BD_ADDR " \ 1121a63eb31SJulian Elischer "'%s'", $2); 1131a63eb31SJulian Elischer exit(1); 1141a63eb31SJulian Elischer } 1151a63eb31SJulian Elischer } 1161a63eb31SJulian Elischer ; 1171a63eb31SJulian Elischer 1181a63eb31SJulian Elischer name: T_NAME T_STRING 1191a63eb31SJulian Elischer { 1201a63eb31SJulian Elischer if (key->name != NULL) 1211a63eb31SJulian Elischer free(key->name); 1221a63eb31SJulian Elischer 1231a63eb31SJulian Elischer key->name = strdup($2); 1241a63eb31SJulian Elischer if (key->name == NULL) { 1251a63eb31SJulian Elischer syslog(LOG_ERR, "Could not allocate new " \ 1261a63eb31SJulian Elischer "device name"); 1271a63eb31SJulian Elischer exit(1); 1281a63eb31SJulian Elischer } 1291a63eb31SJulian Elischer } 1301a63eb31SJulian Elischer ; 1311a63eb31SJulian Elischer 1321a63eb31SJulian Elischer key: T_KEY T_HEXSTRING 1331a63eb31SJulian Elischer { 1341a63eb31SJulian Elischer int i, len; 1351a63eb31SJulian Elischer 1361a63eb31SJulian Elischer if (key->key != NULL) 1371a63eb31SJulian Elischer free(key->key); 1381a63eb31SJulian Elischer 1392aa65cf7SMaksim Yevmenkin key->key = (uint8_t *) malloc(NG_HCI_KEY_SIZE); 1401a63eb31SJulian Elischer if (key->key == NULL) { 1411a63eb31SJulian Elischer syslog(LOG_ERR, "Could not allocate new " \ 1421a63eb31SJulian Elischer "link key"); 1431a63eb31SJulian Elischer exit(1); 1441a63eb31SJulian Elischer } 1451a63eb31SJulian Elischer 1461a63eb31SJulian Elischer memset(key->key, 0, NG_HCI_KEY_SIZE); 1471a63eb31SJulian Elischer 1481a63eb31SJulian Elischer len = strlen($2) / 2; 1491a63eb31SJulian Elischer if (len > NG_HCI_KEY_SIZE) 1501a63eb31SJulian Elischer len = NG_HCI_KEY_SIZE; 1511a63eb31SJulian Elischer 1521a63eb31SJulian Elischer for (i = 0; i < len; i ++) 1531a63eb31SJulian Elischer key->key[i] = hexa2int8((char *)($2) + 2*i); 1541a63eb31SJulian Elischer } 1551a63eb31SJulian Elischer | T_KEY T_NOKEY 1561a63eb31SJulian Elischer { 1571a63eb31SJulian Elischer if (key->key != NULL) 1581a63eb31SJulian Elischer free(key->key); 1591a63eb31SJulian Elischer 1601a63eb31SJulian Elischer key->key = NULL; 1611a63eb31SJulian Elischer } 1621a63eb31SJulian Elischer ; 1631a63eb31SJulian Elischer 1641a63eb31SJulian Elischer pin: T_PIN T_STRING 1651a63eb31SJulian Elischer { 1661a63eb31SJulian Elischer if (key->pin != NULL) 1671a63eb31SJulian Elischer free(key->pin); 1681a63eb31SJulian Elischer 1691a63eb31SJulian Elischer key->pin = strdup($2); 1701a63eb31SJulian Elischer if (key->pin == NULL) { 1711a63eb31SJulian Elischer syslog(LOG_ERR, "Could not allocate new " \ 1721a63eb31SJulian Elischer "PIN code"); 1731a63eb31SJulian Elischer exit(1); 1741a63eb31SJulian Elischer } 1751a63eb31SJulian Elischer } 1761a63eb31SJulian Elischer | T_PIN T_NOPIN 1771a63eb31SJulian Elischer { 1781a63eb31SJulian Elischer if (key->pin != NULL) 1791a63eb31SJulian Elischer free(key->pin); 1801a63eb31SJulian Elischer 1811a63eb31SJulian Elischer key->pin = NULL; 1821a63eb31SJulian Elischer } 1831a63eb31SJulian Elischer ; 1841a63eb31SJulian Elischer 1851a63eb31SJulian Elischer %% 1861a63eb31SJulian Elischer 1871a63eb31SJulian Elischer /* Display parser error message */ 1881a63eb31SJulian Elischer void 1891a63eb31SJulian Elischer yyerror(char const *message) 1901a63eb31SJulian Elischer { 1911a63eb31SJulian Elischer syslog(LOG_ERR, "%s in line %d", message, yylineno); 1921a63eb31SJulian Elischer } 1931a63eb31SJulian Elischer 1941a63eb31SJulian Elischer /* Re-read config file */ 1951a63eb31SJulian Elischer void 1960986ab12SMaksim Yevmenkin read_config_file(void) 1971a63eb31SJulian Elischer { 1981a63eb31SJulian Elischer extern FILE *yyin; 1991a63eb31SJulian Elischer 2001a63eb31SJulian Elischer if (config_file == NULL) { 2011a63eb31SJulian Elischer syslog(LOG_ERR, "Unknown config file name!"); 2021a63eb31SJulian Elischer exit(1); 2031a63eb31SJulian Elischer } 2041a63eb31SJulian Elischer 2051a63eb31SJulian Elischer if ((yyin = fopen(config_file, "r")) == NULL) { 2061a63eb31SJulian Elischer syslog(LOG_ERR, "Could not open config file '%s'. %s (%d)", 2071a63eb31SJulian Elischer config_file, strerror(errno), errno); 2081a63eb31SJulian Elischer exit(1); 2091a63eb31SJulian Elischer } 2101a63eb31SJulian Elischer 2111a63eb31SJulian Elischer clean_config(); 2121a63eb31SJulian Elischer if (yyparse() < 0) { 2131a63eb31SJulian Elischer syslog(LOG_ERR, "Could not parse config file '%s'",config_file); 2141a63eb31SJulian Elischer exit(1); 2151a63eb31SJulian Elischer } 2161a63eb31SJulian Elischer 2171a63eb31SJulian Elischer fclose(yyin); 2181a63eb31SJulian Elischer yyin = NULL; 2191a63eb31SJulian Elischer 2201a63eb31SJulian Elischer #if __config_debug__ 2211a63eb31SJulian Elischer dump_config(); 2221a63eb31SJulian Elischer #endif 2231a63eb31SJulian Elischer } 2241a63eb31SJulian Elischer 2251a63eb31SJulian Elischer /* Clean config */ 2261a63eb31SJulian Elischer void 2271a63eb31SJulian Elischer clean_config(void) 2281a63eb31SJulian Elischer { 2291a63eb31SJulian Elischer link_key_p key = NULL; 2301a63eb31SJulian Elischer 2311a63eb31SJulian Elischer while ((key = LIST_FIRST(&link_keys)) != NULL) { 2321a63eb31SJulian Elischer LIST_REMOVE(key, next); 2331a63eb31SJulian Elischer free_key(key); 2341a63eb31SJulian Elischer } 2351a63eb31SJulian Elischer } 2361a63eb31SJulian Elischer 2371a63eb31SJulian Elischer /* Find link key entry in the list. Return exact or default match */ 2381a63eb31SJulian Elischer link_key_p 2391a63eb31SJulian Elischer get_key(bdaddr_p bdaddr, int exact_match) 2401a63eb31SJulian Elischer { 2411a63eb31SJulian Elischer link_key_p key = NULL, defkey = NULL; 2421a63eb31SJulian Elischer 2431a63eb31SJulian Elischer LIST_FOREACH(key, &link_keys, next) { 2441a63eb31SJulian Elischer if (memcmp(bdaddr, &key->bdaddr, sizeof(key->bdaddr)) == 0) 2451a63eb31SJulian Elischer break; 2461a63eb31SJulian Elischer 2471a63eb31SJulian Elischer if (!exact_match) 2481a63eb31SJulian Elischer if (memcmp(NG_HCI_BDADDR_ANY, &key->bdaddr, 2491a63eb31SJulian Elischer sizeof(key->bdaddr)) == 0) 2501a63eb31SJulian Elischer defkey = key; 2511a63eb31SJulian Elischer } 2521a63eb31SJulian Elischer 2531a63eb31SJulian Elischer return ((key != NULL)? key : defkey); 2541a63eb31SJulian Elischer } 2551a63eb31SJulian Elischer 2561a63eb31SJulian Elischer #if __config_debug__ 2571a63eb31SJulian Elischer /* Dump config */ 2581a63eb31SJulian Elischer void 2591a63eb31SJulian Elischer dump_config(void) 2601a63eb31SJulian Elischer { 2611a63eb31SJulian Elischer link_key_p key = NULL; 2621a63eb31SJulian Elischer char buffer[64]; 2631a63eb31SJulian Elischer 2641a63eb31SJulian Elischer LIST_FOREACH(key, &link_keys, next) { 2651a63eb31SJulian Elischer if (key->key != NULL) 2661a63eb31SJulian Elischer snprintf(buffer, sizeof(buffer), 2671a63eb31SJulian Elischer "0x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", 2681a63eb31SJulian Elischer key->key[0], key->key[1], key->key[2], 2691a63eb31SJulian Elischer key->key[3], key->key[4], key->key[5], 2701a63eb31SJulian Elischer key->key[6], key->key[7], key->key[8], 2711a63eb31SJulian Elischer key->key[9], key->key[10], key->key[11], 2721a63eb31SJulian Elischer key->key[12], key->key[13], key->key[14], 2731a63eb31SJulian Elischer key->key[15]); 2741a63eb31SJulian Elischer 2751a63eb31SJulian Elischer syslog(LOG_DEBUG, 2761a63eb31SJulian Elischer "device %s " \ 2770986ab12SMaksim Yevmenkin "bdaddr %s " \ 2781a63eb31SJulian Elischer "pin %s " \ 2791a63eb31SJulian Elischer "key %s", 2801a63eb31SJulian Elischer (key->name != NULL)? key->name : "noname", 2810986ab12SMaksim Yevmenkin bt_ntoa(&key->bdaddr, NULL), 2821a63eb31SJulian Elischer (key->pin != NULL)? key->pin : "nopin", 2831a63eb31SJulian Elischer (key->key != NULL)? buffer : "nokey"); 2841a63eb31SJulian Elischer } 2851a63eb31SJulian Elischer } 2861a63eb31SJulian Elischer #endif 2871a63eb31SJulian Elischer 2880986ab12SMaksim Yevmenkin /* Read keys file */ 2890986ab12SMaksim Yevmenkin int 2900986ab12SMaksim Yevmenkin read_keys_file(void) 2910986ab12SMaksim Yevmenkin { 2920986ab12SMaksim Yevmenkin FILE *f = NULL; 2930986ab12SMaksim Yevmenkin link_key_t *key = NULL; 2940986ab12SMaksim Yevmenkin char buf[HCSECD_BUFFER_SIZE], *p = NULL, *cp = NULL; 2950986ab12SMaksim Yevmenkin bdaddr_t bdaddr; 2960986ab12SMaksim Yevmenkin int i, len; 2970986ab12SMaksim Yevmenkin 2980986ab12SMaksim Yevmenkin if ((f = fopen(HCSECD_KEYSFILE, "r")) == NULL) { 2990986ab12SMaksim Yevmenkin if (errno == ENOENT) 3000986ab12SMaksim Yevmenkin return (0); 3010986ab12SMaksim Yevmenkin 3020986ab12SMaksim Yevmenkin syslog(LOG_ERR, "Could not open keys file %s. %s (%d)\n", 3030986ab12SMaksim Yevmenkin HCSECD_KEYSFILE, strerror(errno), errno); 3040986ab12SMaksim Yevmenkin 3050986ab12SMaksim Yevmenkin return (-1); 3060986ab12SMaksim Yevmenkin } 3070986ab12SMaksim Yevmenkin 3080986ab12SMaksim Yevmenkin while ((p = fgets(buf, sizeof(buf), f)) != NULL) { 3090986ab12SMaksim Yevmenkin if (*p == '#') 3100986ab12SMaksim Yevmenkin continue; 3110986ab12SMaksim Yevmenkin if ((cp = strpbrk(p, " ")) == NULL) 3120986ab12SMaksim Yevmenkin continue; 3130986ab12SMaksim Yevmenkin 3140986ab12SMaksim Yevmenkin *cp++ = '\0'; 3150986ab12SMaksim Yevmenkin 3160986ab12SMaksim Yevmenkin if (!bt_aton(p, &bdaddr)) 3170986ab12SMaksim Yevmenkin continue; 3180986ab12SMaksim Yevmenkin 3190986ab12SMaksim Yevmenkin if ((key = get_key(&bdaddr, 1)) == NULL) 3200986ab12SMaksim Yevmenkin continue; 3210986ab12SMaksim Yevmenkin 3220986ab12SMaksim Yevmenkin if (key->key == NULL) { 3232aa65cf7SMaksim Yevmenkin key->key = (uint8_t *) malloc(NG_HCI_KEY_SIZE); 3240986ab12SMaksim Yevmenkin if (key->key == NULL) { 3250986ab12SMaksim Yevmenkin syslog(LOG_ERR, "Could not allocate link key"); 3260986ab12SMaksim Yevmenkin exit(1); 3270986ab12SMaksim Yevmenkin } 3280986ab12SMaksim Yevmenkin } 3290986ab12SMaksim Yevmenkin 3300986ab12SMaksim Yevmenkin memset(key->key, 0, NG_HCI_KEY_SIZE); 3310986ab12SMaksim Yevmenkin 3320986ab12SMaksim Yevmenkin len = strlen(cp) / 2; 3330986ab12SMaksim Yevmenkin if (len > NG_HCI_KEY_SIZE) 3340986ab12SMaksim Yevmenkin len = NG_HCI_KEY_SIZE; 3350986ab12SMaksim Yevmenkin 3360986ab12SMaksim Yevmenkin for (i = 0; i < len; i ++) 3370986ab12SMaksim Yevmenkin key->key[i] = hexa2int8(cp + 2*i); 3380986ab12SMaksim Yevmenkin 3390986ab12SMaksim Yevmenkin syslog(LOG_DEBUG, "Restored link key for the entry, " \ 3400986ab12SMaksim Yevmenkin "remote bdaddr %s, name '%s'", 3410986ab12SMaksim Yevmenkin bt_ntoa(&key->bdaddr, NULL), 3420986ab12SMaksim Yevmenkin (key->name != NULL)? key->name : "No name"); 3430986ab12SMaksim Yevmenkin } 3440986ab12SMaksim Yevmenkin 3450986ab12SMaksim Yevmenkin fclose(f); 3460986ab12SMaksim Yevmenkin 3470986ab12SMaksim Yevmenkin return (0); 3480986ab12SMaksim Yevmenkin } 3490986ab12SMaksim Yevmenkin 3500986ab12SMaksim Yevmenkin /* Dump keys file */ 3510986ab12SMaksim Yevmenkin int 3520986ab12SMaksim Yevmenkin dump_keys_file(void) 3530986ab12SMaksim Yevmenkin { 3540986ab12SMaksim Yevmenkin link_key_p key = NULL; 3550986ab12SMaksim Yevmenkin char tmp[PATH_MAX], buf[HCSECD_BUFFER_SIZE]; 3560986ab12SMaksim Yevmenkin int f; 3570986ab12SMaksim Yevmenkin 3580986ab12SMaksim Yevmenkin snprintf(tmp, sizeof(tmp), "%s.tmp", HCSECD_KEYSFILE); 3590986ab12SMaksim Yevmenkin if ((f = open(tmp, O_RDWR|O_CREAT|O_TRUNC|O_EXCL, 0600)) < 0) { 3600986ab12SMaksim Yevmenkin syslog(LOG_ERR, "Could not create temp keys file %s. %s (%d)\n", 3610986ab12SMaksim Yevmenkin tmp, strerror(errno), errno); 3620986ab12SMaksim Yevmenkin return (-1); 3630986ab12SMaksim Yevmenkin } 3640986ab12SMaksim Yevmenkin 3650986ab12SMaksim Yevmenkin LIST_FOREACH(key, &link_keys, next) { 3660986ab12SMaksim Yevmenkin if (key->key == NULL) 3670986ab12SMaksim Yevmenkin continue; 3680986ab12SMaksim Yevmenkin 3690986ab12SMaksim Yevmenkin snprintf(buf, sizeof(buf), 3700986ab12SMaksim Yevmenkin "%s %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", 3710986ab12SMaksim Yevmenkin bt_ntoa(&key->bdaddr, NULL), 3720986ab12SMaksim Yevmenkin key->key[0], key->key[1], key->key[2], key->key[3], 3730986ab12SMaksim Yevmenkin key->key[4], key->key[5], key->key[6], key->key[7], 3740986ab12SMaksim Yevmenkin key->key[8], key->key[9], key->key[10], key->key[11], 3750986ab12SMaksim Yevmenkin key->key[12], key->key[13], key->key[14], key->key[15]); 3760986ab12SMaksim Yevmenkin 3770986ab12SMaksim Yevmenkin if (write(f, buf, strlen(buf)) < 0) { 3780986ab12SMaksim Yevmenkin syslog(LOG_ERR, "Could not write temp keys file. " \ 3790986ab12SMaksim Yevmenkin "%s (%d)\n", strerror(errno), errno); 3800986ab12SMaksim Yevmenkin break; 3810986ab12SMaksim Yevmenkin } 3820986ab12SMaksim Yevmenkin } 3830986ab12SMaksim Yevmenkin 3840986ab12SMaksim Yevmenkin close(f); 3850986ab12SMaksim Yevmenkin 3860986ab12SMaksim Yevmenkin if (rename(tmp, HCSECD_KEYSFILE) < 0) { 3870986ab12SMaksim Yevmenkin syslog(LOG_ERR, "Could not rename(%s, %s). %s (%d)\n", 3880986ab12SMaksim Yevmenkin tmp, HCSECD_KEYSFILE, strerror(errno), errno); 3890986ab12SMaksim Yevmenkin unlink(tmp); 3900986ab12SMaksim Yevmenkin return (-1); 3910986ab12SMaksim Yevmenkin } 3920986ab12SMaksim Yevmenkin 3930986ab12SMaksim Yevmenkin return (0); 3940986ab12SMaksim Yevmenkin } 3950986ab12SMaksim Yevmenkin 3961a63eb31SJulian Elischer /* Free key entry */ 3971a63eb31SJulian Elischer static void 3981a63eb31SJulian Elischer free_key(link_key_p key) 3991a63eb31SJulian Elischer { 4001a63eb31SJulian Elischer if (key->name != NULL) 4011a63eb31SJulian Elischer free(key->name); 4021a63eb31SJulian Elischer if (key->key != NULL) 4031a63eb31SJulian Elischer free(key->key); 4041a63eb31SJulian Elischer if (key->pin != NULL) 4051a63eb31SJulian Elischer free(key->pin); 4061a63eb31SJulian Elischer 4071a63eb31SJulian Elischer memset(key, 0, sizeof(*key)); 4081a63eb31SJulian Elischer free(key); 4091a63eb31SJulian Elischer } 4101a63eb31SJulian Elischer 4111a63eb31SJulian Elischer /* Convert hex ASCII to int4 */ 4121a63eb31SJulian Elischer static int 4131a63eb31SJulian Elischer hexa2int4(char *a) 4141a63eb31SJulian Elischer { 4151a63eb31SJulian Elischer if ('0' <= *a && *a <= '9') 4161a63eb31SJulian Elischer return (*a - '0'); 4171a63eb31SJulian Elischer 4181a63eb31SJulian Elischer if ('A' <= *a && *a <= 'F') 4191a63eb31SJulian Elischer return (*a - 'A' + 0xa); 4201a63eb31SJulian Elischer 4211a63eb31SJulian Elischer if ('a' <= *a && *a <= 'f') 4221a63eb31SJulian Elischer return (*a - 'a' + 0xa); 4231a63eb31SJulian Elischer 4241a63eb31SJulian Elischer syslog(LOG_ERR, "Invalid hex character: '%c' (%#x)", *a, *a); 4251a63eb31SJulian Elischer exit(1); 4261a63eb31SJulian Elischer } 4271a63eb31SJulian Elischer 4281a63eb31SJulian Elischer /* Convert hex ASCII to int8 */ 4291a63eb31SJulian Elischer static int 4301a63eb31SJulian Elischer hexa2int8(char *a) 4311a63eb31SJulian Elischer { 4321a63eb31SJulian Elischer return ((hexa2int4(a) << 4) | hexa2int4(a + 1)); 4331a63eb31SJulian Elischer } 4341a63eb31SJulian Elischer 435