1 /* $NetBSD: keylock.c,v 1.1 2009/08/14 21:17:22 mbalmer Exp $ */
4 * Copyright (c) 2009 Marc Balmer <marc@msys.ch>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #include "opt_secmodel_keylock.h"
30 /* Support for multi-position electro-mechanical keylocks */
32 #include <sys/param.h>
33 #include <sys/kernel.h>
34 #include <sys/sysctl.h>
36 #include <dev/keylock.h>
38 #ifdef secmodel_keylock
39 #include <sys/kauth.h>
40 #include <secmodel/keylock/keylock.h>
43 static int (*keylock_pos_cb
)(void *) = NULL
;
44 static void *keylock_pos_cb_arg
= NULL
;
45 static int keylock_npos
= 0;
46 static int keylock_order
= 0;
48 int keylock_pos_sysctl(SYSCTLFN_PROTO
);
49 int keylock_state_sysctl(SYSCTLFN_PROTO
);
50 int keylock_order_sysctl(SYSCTLFN_PROTO
);
52 SYSCTL_SETUP(sysctl_keylock_setup
, "sysctl keylock setup")
54 const struct sysctlnode
*node
= NULL
;
56 sysctl_createv(clog
, 0, NULL
, NULL
,
58 CTLTYPE_NODE
, "hw", NULL
,
61 sysctl_createv(clog
, 0, NULL
, &node
,
63 CTLTYPE_NODE
, "keylock",
64 SYSCTL_DESCR("Keylock state"),
66 CTL_HW
, CTL_CREATE
, CTL_EOL
);
71 sysctl_createv(clog
, 0, &node
, NULL
,
72 CTLFLAG_PERMANENT
| CTLFLAG_READONLY
,
74 SYSCTL_DESCR("Current keylock position"),
75 keylock_pos_sysctl
, 0, NULL
, 0,
77 sysctl_createv(clog
, 0, &node
, NULL
,
78 CTLFLAG_PERMANENT
| CTLFLAG_READONLY
,
80 SYSCTL_DESCR("Number of keylock positions"),
81 NULL
, 0, &keylock_npos
, 0,
83 sysctl_createv(clog
, 0, &node
, NULL
,
84 CTLFLAG_PERMANENT
| CTLFLAG_READONLY
,
86 SYSCTL_DESCR("Keylock state"),
87 keylock_state_sysctl
, 0, NULL
, 0,
89 sysctl_createv(clog
, 0, &node
, NULL
,
90 CTLFLAG_PERMANENT
| CTLFLAG_READWRITE
,
92 SYSCTL_DESCR("Keylock closedness order"),
93 keylock_order_sysctl
, 0, NULL
, 0,
98 keylock_register(void *cb_arg
, int npos
, int (*cb
)(void *))
100 if (keylock_pos_cb
!= NULL
)
104 keylock_pos_cb_arg
= cb_arg
;
106 #ifdef secmodel_keylock
107 secmodel_keylock_start();
113 keylock_unregister(void *cb_arg
, int (*cb
)(void *))
115 if (keylock_pos_cb
!= cb
|| keylock_pos_cb_arg
!= cb_arg
)
118 #ifdef secmodel_keylock
119 secmodel_keylock_stop();
121 keylock_pos_cb
= NULL
;
122 keylock_pos_cb_arg
= NULL
;
127 keylock_position(void)
129 if (keylock_pos_cb
== NULL
)
132 return (*keylock_pos_cb
)(keylock_pos_cb_arg
);
136 keylock_num_positions(void)
146 if (keylock_npos
== 0)
147 return KEYLOCK_ABSENT
;
149 pos
= keylock_position();
151 return KEYLOCK_TAMPER
;
154 * XXX How should the intermediate positions be handled?
155 * At the moment only the ultimate positions are properly handled,
156 * we need to think about what we do with the intermediate positions.
157 * For now we return KEYLOCK_SEMIOPEN for them.
160 return keylock_order
== 0 ? KEYLOCK_CLOSE
: KEYLOCK_OPEN
;
161 else if (pos
== keylock_npos
)
162 return keylock_order
== 0 ? KEYLOCK_OPEN
: KEYLOCK_CLOSE
;
163 return KEYLOCK_SEMIOPEN
;
167 keylock_pos_sysctl(SYSCTLFN_ARGS
)
169 struct sysctlnode node
;
173 node
.sysctl_data
= &val
;
175 val
= keylock_position();
176 return sysctl_lookup(SYSCTLFN_CALL(&node
));
180 keylock_state_sysctl(SYSCTLFN_ARGS
)
182 struct sysctlnode node
;
186 node
.sysctl_data
= &val
;
188 val
= keylock_state();
189 return sysctl_lookup(SYSCTLFN_CALL(&node
));
193 keylock_order_sysctl(SYSCTLFN_ARGS
)
195 struct sysctlnode node
;
199 node
.sysctl_data
= &val
;
202 error
= sysctl_lookup(SYSCTLFN_CALL(&node
));
203 if (error
|| newp
== NULL
)
205 if (keylock_state() != KEYLOCK_OPEN
)