1 1.3 pooka /* $NetBSD: keylock.c,v 1.3 2014/02/25 18:30:09 pooka Exp $ */ 2 1.1 mbalmer 3 1.1 mbalmer /* 4 1.1 mbalmer * Copyright (c) 2009 Marc Balmer <marc (at) msys.ch> 5 1.1 mbalmer * All rights reserved. 6 1.1 mbalmer * 7 1.1 mbalmer * Redistribution and use in source and binary forms, with or without 8 1.1 mbalmer * modification, are permitted provided that the following conditions 9 1.1 mbalmer * are met: 10 1.1 mbalmer * 1. Redistributions of source code must retain the above copyright 11 1.1 mbalmer * notice, this list of conditions and the following disclaimer. 12 1.1 mbalmer * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 mbalmer * notice, this list of conditions and the following disclaimer in the 14 1.1 mbalmer * documentation and/or other materials provided with the distribution. 15 1.1 mbalmer * 16 1.1 mbalmer * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 1.1 mbalmer * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 1.1 mbalmer * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 1.1 mbalmer * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 1.1 mbalmer * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 1.1 mbalmer * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 1.1 mbalmer * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 1.1 mbalmer * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 1.1 mbalmer * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 1.1 mbalmer * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 1.1 mbalmer */ 27 1.1 mbalmer 28 1.1 mbalmer #include "opt_secmodel_keylock.h" 29 1.1 mbalmer 30 1.1 mbalmer /* Support for multi-position electro-mechanical keylocks */ 31 1.1 mbalmer 32 1.1 mbalmer #include <sys/param.h> 33 1.1 mbalmer #include <sys/kernel.h> 34 1.1 mbalmer #include <sys/sysctl.h> 35 1.1 mbalmer 36 1.2 mbalmer #include <dev/keylock.h> 37 1.2 mbalmer 38 1.1 mbalmer #ifdef secmodel_keylock 39 1.1 mbalmer #include <sys/kauth.h> 40 1.1 mbalmer #include <secmodel/keylock/keylock.h> 41 1.1 mbalmer #endif 42 1.1 mbalmer 43 1.1 mbalmer static int (*keylock_pos_cb)(void *) = NULL; 44 1.1 mbalmer static void *keylock_pos_cb_arg = NULL; 45 1.1 mbalmer static int keylock_npos = 0; 46 1.1 mbalmer static int keylock_order = 0; 47 1.1 mbalmer 48 1.1 mbalmer int keylock_pos_sysctl(SYSCTLFN_PROTO); 49 1.1 mbalmer int keylock_state_sysctl(SYSCTLFN_PROTO); 50 1.1 mbalmer int keylock_order_sysctl(SYSCTLFN_PROTO); 51 1.1 mbalmer 52 1.1 mbalmer SYSCTL_SETUP(sysctl_keylock_setup, "sysctl keylock setup") 53 1.1 mbalmer { 54 1.1 mbalmer const struct sysctlnode *node = NULL; 55 1.1 mbalmer 56 1.1 mbalmer sysctl_createv(clog, 0, NULL, &node, 57 1.1 mbalmer CTLFLAG_PERMANENT, 58 1.1 mbalmer CTLTYPE_NODE, "keylock", 59 1.1 mbalmer SYSCTL_DESCR("Keylock state"), 60 1.1 mbalmer NULL, 0, NULL, 0, 61 1.1 mbalmer CTL_HW, CTL_CREATE, CTL_EOL); 62 1.1 mbalmer 63 1.1 mbalmer if (node == NULL) 64 1.1 mbalmer return; 65 1.1 mbalmer 66 1.1 mbalmer sysctl_createv(clog, 0, &node, NULL, 67 1.1 mbalmer CTLFLAG_PERMANENT | CTLFLAG_READONLY, 68 1.1 mbalmer CTLTYPE_INT, "pos", 69 1.1 mbalmer SYSCTL_DESCR("Current keylock position"), 70 1.1 mbalmer keylock_pos_sysctl, 0, NULL, 0, 71 1.1 mbalmer CTL_CREATE, CTL_EOL); 72 1.1 mbalmer sysctl_createv(clog, 0, &node, NULL, 73 1.1 mbalmer CTLFLAG_PERMANENT | CTLFLAG_READONLY, 74 1.1 mbalmer CTLTYPE_INT, "npos", 75 1.1 mbalmer SYSCTL_DESCR("Number of keylock positions"), 76 1.1 mbalmer NULL, 0, &keylock_npos, 0, 77 1.1 mbalmer CTL_CREATE, CTL_EOL); 78 1.1 mbalmer sysctl_createv(clog, 0, &node, NULL, 79 1.1 mbalmer CTLFLAG_PERMANENT | CTLFLAG_READONLY, 80 1.1 mbalmer CTLTYPE_INT, "state", 81 1.1 mbalmer SYSCTL_DESCR("Keylock state"), 82 1.1 mbalmer keylock_state_sysctl, 0, NULL, 0, 83 1.1 mbalmer CTL_CREATE, CTL_EOL); 84 1.1 mbalmer sysctl_createv(clog, 0, &node, NULL, 85 1.1 mbalmer CTLFLAG_PERMANENT | CTLFLAG_READWRITE, 86 1.1 mbalmer CTLTYPE_INT, "order", 87 1.1 mbalmer SYSCTL_DESCR("Keylock closedness order"), 88 1.1 mbalmer keylock_order_sysctl, 0, NULL, 0, 89 1.1 mbalmer CTL_CREATE, CTL_EOL); 90 1.1 mbalmer } 91 1.1 mbalmer 92 1.1 mbalmer int 93 1.1 mbalmer keylock_register(void *cb_arg, int npos, int (*cb)(void *)) 94 1.1 mbalmer { 95 1.1 mbalmer if (keylock_pos_cb != NULL) 96 1.1 mbalmer return -1; 97 1.1 mbalmer 98 1.1 mbalmer keylock_pos_cb = cb; 99 1.1 mbalmer keylock_pos_cb_arg = cb_arg; 100 1.1 mbalmer keylock_npos = npos; 101 1.1 mbalmer #ifdef secmodel_keylock 102 1.1 mbalmer secmodel_keylock_start(); 103 1.1 mbalmer #endif 104 1.1 mbalmer return 0; 105 1.1 mbalmer } 106 1.1 mbalmer 107 1.1 mbalmer void 108 1.1 mbalmer keylock_unregister(void *cb_arg, int (*cb)(void *)) 109 1.1 mbalmer { 110 1.1 mbalmer if (keylock_pos_cb != cb || keylock_pos_cb_arg != cb_arg) 111 1.1 mbalmer return; 112 1.1 mbalmer 113 1.1 mbalmer #ifdef secmodel_keylock 114 1.1 mbalmer secmodel_keylock_stop(); 115 1.1 mbalmer #endif 116 1.1 mbalmer keylock_pos_cb = NULL; 117 1.1 mbalmer keylock_pos_cb_arg = NULL; 118 1.1 mbalmer keylock_npos = 0; 119 1.1 mbalmer } 120 1.1 mbalmer 121 1.1 mbalmer int 122 1.1 mbalmer keylock_position(void) 123 1.1 mbalmer { 124 1.1 mbalmer if (keylock_pos_cb == NULL) 125 1.1 mbalmer return 0; 126 1.1 mbalmer 127 1.1 mbalmer return (*keylock_pos_cb)(keylock_pos_cb_arg); 128 1.1 mbalmer } 129 1.1 mbalmer 130 1.1 mbalmer int 131 1.1 mbalmer keylock_num_positions(void) 132 1.1 mbalmer { 133 1.1 mbalmer return keylock_npos; 134 1.1 mbalmer } 135 1.1 mbalmer 136 1.1 mbalmer int 137 1.1 mbalmer keylock_state(void) 138 1.1 mbalmer { 139 1.1 mbalmer int pos; 140 1.1 mbalmer 141 1.1 mbalmer if (keylock_npos == 0) 142 1.1 mbalmer return KEYLOCK_ABSENT; 143 1.1 mbalmer 144 1.1 mbalmer pos = keylock_position(); 145 1.1 mbalmer if (pos == 0) 146 1.1 mbalmer return KEYLOCK_TAMPER; 147 1.1 mbalmer 148 1.1 mbalmer /* 149 1.1 mbalmer * XXX How should the intermediate positions be handled? 150 1.1 mbalmer * At the moment only the ultimate positions are properly handled, 151 1.1 mbalmer * we need to think about what we do with the intermediate positions. 152 1.1 mbalmer * For now we return KEYLOCK_SEMIOPEN for them. 153 1.1 mbalmer */ 154 1.1 mbalmer if (pos == 1) 155 1.1 mbalmer return keylock_order == 0 ? KEYLOCK_CLOSE : KEYLOCK_OPEN; 156 1.1 mbalmer else if (pos == keylock_npos) 157 1.1 mbalmer return keylock_order == 0 ? KEYLOCK_OPEN : KEYLOCK_CLOSE; 158 1.1 mbalmer return KEYLOCK_SEMIOPEN; 159 1.1 mbalmer } 160 1.1 mbalmer 161 1.1 mbalmer int 162 1.1 mbalmer keylock_pos_sysctl(SYSCTLFN_ARGS) 163 1.1 mbalmer { 164 1.1 mbalmer struct sysctlnode node; 165 1.1 mbalmer int val; 166 1.1 mbalmer 167 1.1 mbalmer node = *rnode; 168 1.1 mbalmer node.sysctl_data = &val; 169 1.1 mbalmer 170 1.1 mbalmer val = keylock_position(); 171 1.1 mbalmer return sysctl_lookup(SYSCTLFN_CALL(&node)); 172 1.1 mbalmer } 173 1.1 mbalmer 174 1.1 mbalmer int 175 1.1 mbalmer keylock_state_sysctl(SYSCTLFN_ARGS) 176 1.1 mbalmer { 177 1.1 mbalmer struct sysctlnode node; 178 1.1 mbalmer int val; 179 1.1 mbalmer 180 1.1 mbalmer node = *rnode; 181 1.1 mbalmer node.sysctl_data = &val; 182 1.1 mbalmer 183 1.1 mbalmer val = keylock_state(); 184 1.1 mbalmer return sysctl_lookup(SYSCTLFN_CALL(&node)); 185 1.1 mbalmer } 186 1.1 mbalmer 187 1.1 mbalmer int 188 1.1 mbalmer keylock_order_sysctl(SYSCTLFN_ARGS) 189 1.1 mbalmer { 190 1.1 mbalmer struct sysctlnode node; 191 1.1 mbalmer int val, error; 192 1.1 mbalmer 193 1.1 mbalmer node = *rnode; 194 1.1 mbalmer node.sysctl_data = &val; 195 1.1 mbalmer 196 1.1 mbalmer val = keylock_order; 197 1.1 mbalmer error = sysctl_lookup(SYSCTLFN_CALL(&node)); 198 1.1 mbalmer if (error || newp == NULL) 199 1.1 mbalmer return error; 200 1.1 mbalmer if (keylock_state() != KEYLOCK_OPEN) 201 1.1 mbalmer return -1; 202 1.1 mbalmer 203 1.1 mbalmer keylock_order = val; 204 1.1 mbalmer return 0; 205 1.1 mbalmer } 206 1.1 mbalmer 207