Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
emulab
emulab-devel
Commits
5008ab6b
Commit
5008ab6b
authored
Aug 21, 2015
by
Leigh B Stoller
Browse files
Merge branch 'features/ipmi-separate-encryption-keys'
parents
2a1b2451
609ca2e0
Changes
4
Hide whitespace changes
Inline
Side-by-side
sql/database-create.sql
View file @
5008ab6b
...
...
@@ -3527,6 +3527,10 @@ CREATE TABLE `outlets_remoteauth` (
`key_role`
varchar
(
64
)
NOT
NULL
default
''
,
`key_uid`
varchar
(
64
)
NOT
NULL
default
''
,
`mykey`
text
NOT
NULL
,
-- NOTE: These are mostly pulled from ipmitool. Other protocols may need
-- other values or not care at all, hence the addition of OTHER to the
-- list and a default of NULL.
`key_privlvl`
enum
(
'CALLBACK'
,
'USER'
,
'OPERATOR'
,
'ADMINISTRATOR'
,
'OTHER'
)
DEFAULT
NULL
,
PRIMARY
KEY
(
`node_id`
,
`key_type`
,
`key_role`
,
`key_uid`
)
)
ENGINE
=
MyISAM
DEFAULT
CHARSET
=
latin1
;
...
...
sql/updates/4/467
0 → 100644
View file @
5008ab6b
#
# IPMIv2 Separate (Kg) Encryption Key and Privileges Levels
#
# Actually, it turns out that the current schema's PRIMARY KEY already supports
# storing a separate Kg key from the user(s) passwords, so we just need to
# update the libs to pull all of the rows for that part.
#
use
strict
;
use
libdb
;
sub
DoUpdate
($$$)
{
my
(
$dbhandle
,
$dbname
,
$version
)
=
@_
;
DBQueryFatal
(
<<'SQL'
ALTER TABLE outlets_remoteauth
ADD COLUMN key_privlvl
ENUM ('CALLBACK', 'USER', 'OPERATOR', 'ADMINISTRATOR', 'OTHER') DEFAULT NULL
SQL
);
return
0
;
}
1
;
# Local Variables:
# mode:perl
# End:
# vim: set ft=perl et sw=4 ts=4:
tbsetup/power_ilo.pm.in
View file @
5008ab6b
...
...
@@ -40,9 +40,12 @@
package
power_ilo
;
use
strict
;
use
warnings
;
use
Exporter
;
@ISA = ("Exporter");
@EXPORT = qw( iloctrl );
our
@ISA
=
("
Exporter
");
our
@EXPORT
=
qw( iloctrl )
;
use
lib
"
@prefix
@/lib
";
use
libdb
;
...
...
@@ -55,6 +58,7 @@ use POSIX ":sys_wait_h";
my
$debug
=
0
;
# Always parallelize for now cause we are vulnerable to timeouts with
# unreachable nodes or weird iLO crap.
# NOTE: ipmi doesn't appear to be handled if $parallelize isn't set.
my
$parallelize
=
1
;
# Turn off line buffering on output
...
...
@@ -99,7 +103,9 @@ sub iloctrl($$@) {
}
my
(
$IP
)
=
$res
->
fetchrow
();
$
res
=
DBQueryFatal
(
"select key_role,key_uid,mykey"
.
# FIXED: Handle multiple rows here like power_ipmi.pm does.
# This is so we can grab a kgkey separately from the user password.
$res
=
DBQueryFatal
("
select key_role,key_uid,mykey,key_privlvl
"
.
"
from outlets_remoteauth
"
.
"
where node_id='
$n
' and key_type='
$type
'
");
if
(
!
defined
(
$res
)
||
!
$res
||
$res
->
num_rows
()
==
0
)
{
...
...
@@ -107,20 +113,53 @@ sub iloctrl($$@) {
++
$exitval
;
next
;
}
my
($
krole
,$
kuid
,$
kkey
)
=
$
res
->
fetchrow
();
my
(
$krole
,
$kuid
,
$kkey
,
$kgkey
,
$kprivlvl
);
while
(
my
$row
=
$res
->
fetchrow_hashref
())
{
$krole
=
$row
->
{'
key_role
'};
if
(
$krole
eq
"
ipmi-passwd
")
{
$kuid
=
$row
->
{'
key_uid
'};
$kkey
=
$row
->
{'
mykey
'};
if
(
$row
->
{'
key_privlvl
'})
{
$kprivlvl
=
$row
->
{'
key_privlvl
'};
}
}
elsif
(
$krole
eq
"
ipmi-kgkey
")
{
(
$kgkey
=
$row
->
{'
mykey
'})
=~
s/^0x//
;
# NOTE: key_privlvl is currently ignored in case this is the
# only authentication mechanism being used.
}
}
$
ilo_nodeinfo
{$
n
}
=
[
$
n
,$
IP
,$
krole
,$
kuid
,$
kkey
];
if
(
$kgkey
&&
$kkey
)
{
$krole
=
'
ipmi-kgkey-passwd
';
}
elsif
(
$kkey
)
{
$krole
=
'
ipmi-passwd
';
}
elsif
(
$kgkey
)
{
$krole
=
'
ipmi-kgkey
';
# restore previous behavior
$kkey
=
$kgkey
;
$kgkey
=
undef
;
$kprivlvl
=
undef
;
}
else
{
# all of the keys were empty which is weird and the last key_role
# returned from the db wins
}
$ilo_nodeinfo
{
$n
}
=
[
$n
,
$IP
,
$krole
,
$kuid
,
$kkey
,
$kgkey
,
$kprivlvl
];
}
my
$timeout
=
30
;
if
(
$parallelize
)
{
my
$coderef
=
sub
{
my
($
n
,$
IP
,$
krole
,$
kuid
,$
kkey
)
=
@{
$
_
[
0
]
};
my
(
$n
,
$IP
,
$krole
,
$kuid
,
$kkey
,
$kgkey
,
$kprivlvl
)
=
@
{
$_
[
0
]
};
my
$tret
;
eval
{
if
(
$type
=~
/^ipmi/
)
{
$
tret
=
ipmiexec
($
n
,$
type
,$
cmd
,$
IP
,$
krole
,$
kuid
,$
kkey
,$
timeout
);
$tret
=
ipmiexec
(
$n
,
$type
,
$cmd
,
$IP
,
$krole
,
$kuid
,
$kkey
,
$
kgkey
,
$kprivlvl
,
$
timeout
);
}
else
{
$tret
=
iloexec
(
$n
,
$type
,
$cmd
,
$IP
,
$krole
,
$kuid
,
$kkey
,
$timeout
);
}
...
...
@@ -252,11 +291,11 @@ sub iloexec($$$$$$$;$) {
$SIG
{'
ALRM
'}
=
sub
{
$SIG
{'
PIPE
'}
=
'
IGNORE
';
$SIG
{'
CHLD
'}
=
'
IGNORE
';
kill
(
INT
,$
pid
);
kill
(
'
INT
'
,
$pid
);
select
(
undef
,
undef
,
undef
,
0.1
);
kill
(
TERM
,$
pid
);
kill
(
'
TERM
'
,
$pid
);
select
(
undef
,
undef
,
undef
,
0.1
);
kill
(
KILL
,$
pid
);
kill
(
'
KILL
'
,
$pid
);
die
"
iloexec(
$node_id
) timed out in ssh!
";
};
...
...
@@ -301,7 +340,7 @@ sub iloexec($$$$$$$;$) {
# Talk to ssh over the pty: wait for expected output and send responses
#
my
@lines
=
();
foreach $es (@expect_seq) {
foreach
my
$es
(
@expect_seq
)
{
my
(
$rval
,
$sval
)
=
@$es
;
my
$found
=
0
;
...
...
@@ -361,17 +400,17 @@ sub iloexec($$$$$$$;$) {
}
sleep
(
1
);
}
kill
(
KILL
,$
pid
)
if
(
!$dead);
kill
(
'
KILL
'
,
$pid
)
if
(
!
$dead
);
# if we get here, things probably went ok...
return
0
;
}
#
#
Arguments
:
$
node_id
,$
type
,$
cmd
,$
IP
,$
key_role
,$
key_uid
,$
key
[,$
timeout
]
# Arguments: $node_id,$type,$cmd,$IP,$key_role,$key_uid,$key[,$
kgkey,$privlvl,$
timeout]
#
sub
ipmiexec
($$$$$$$;$)
{
my
($
node_id
,$
type
,$
cmd
,$
IP
,$
key_role
,$
key_uid
,$
key
,$
timeout
)
=
@
_
;
sub
ipmiexec
($$$$$$$;$
$$
) {
my
(
$node_id
,
$type
,
$cmd
,
$IP
,
$key_role
,
$key_uid
,
$key
,
$
kgkey
,
$privlvl
,
$
timeout
)
=
@_
;
if
(
$debug
)
{
print
"
ipmiexec called with (
"
.
join
('
,
',
@
_
)
.
"
)
\n
";
...
...
@@ -407,12 +446,15 @@ sub ipmiexec($$$$$$$;$) {
if
(
$key_role
eq
'
ipmi-passwd
')
{
$usekey
=
0
;
}
elsif
(
$key_role
eq
'
ipmi-kgkey-passwd
')
{
$usekey
=
1
;
}
elsif
(
$key_role
eq
'
ipmi-kgkey
')
{
if
(
$type
eq
'
ipmi15
')
{
warn
"
Cannot use key_role 'kgkey' for IPMI 1.5!
";
return
-
21
;
}
$usekey
=
1
;
$kgkey
=
$key
;
}
else
{
warn
"
Unsupported IPMI key_role
$key_role
!
";
return
-
14
;
...
...
@@ -421,13 +463,14 @@ sub ipmiexec($$$$$$$;$) {
# XXX IPMI takes about 40 seconds to timeout and doesn't
# have an option to control?!
my $ipmicmd = "ipmitool -I $iface -H $IP -U $key_uid -E -K power $cmd";
my
$privlvl_args
=
(
$privlvl
)
?
"
-L
$privlvl
"
:
'';
my
$ipmicmd
=
"
ipmitool -I
$iface
-H
$IP
-U
$key_uid
$privlvl_args
-E -K power
$cmd
";
print
"
*** Executing '
$ipmicmd
', output:
\n
"
if
(
$debug
>
1
);
# Set the password and key environment variables
$ENV
{'
IPMI_PASSWORD
'}
=
substr
(
$key
,
0
,
$pwdmax
);
$ENV{'
IPMI_KGKEY
'} = $key
$ENV
{'
IPMI_KGKEY
'}
=
$
kg
key
if
(
$usekey
);
my
$output
=
`
$ipmicmd
2>&1
`;
...
...
@@ -447,3 +490,7 @@ sub ipmiexec($$$$$$$;$) {
}
1
;
# vim: set ft=perl et sw=4 ts=8:
# Not sure what the (no)et sw=? ts=? rules should be in this file - they're kind of mixed.
# Seems like a leading tab in some places and then 4 expanded spaces. Maybe et sw=4 ts=8.
tbsetup/power_ipmi.pm.in
View file @
5008ab6b
...
...
@@ -81,7 +81,7 @@ sub new($$$;$) {
$self
->
{
KGKEY
}
=
"";
# Fetch authentication credentials from the DB.
my
$
res
=
DBQueryFatal
(
"select key_role,key_uid,mykey"
.
my
$res
=
DBQueryFatal
("
select key_role,key_uid,mykey
,key_privlvl
"
.
"
from outlets_remoteauth
"
.
"
where node_id='
$devicename
'
"
.
"
and key_type='
$KTYPE
'
");
...
...
@@ -93,9 +93,12 @@ sub new($$$;$) {
if
(
$role
eq
"
ipmi-passwd
")
{
$self
->
{
USERNAME
}
=
$row
->
{'
key_uid
'};
$self
->
{
PASSWORD
}
=
$row
->
{'
mykey
'};
if
(
$row
->
{'
key_privlvl
'})
{
$self
->
{
PRIVLVL
}
=
$row
->
{'
key_privlvl
'};
}
}
elsif
(
$role
eq
"
ipmi-kgkey
")
{
$
self
->{
KGKEY
}
=
$
row
->{
'mykey'
}
=~
s
/^
0x
//;
(
$self
->
{
KGKEY
}
=
$row
->
{'
mykey
'}
)
=~
s/^0x//
;
}
}
}
...
...
@@ -106,6 +109,9 @@ sub new($$$;$) {
}
elsif
(
$self
->
{
DEVICETYPE
}
eq
"
ipmi-ms
")
{
$self
->
{
IPMICMD
}
.=
"
-I lanplus
";
}
if
(
$self
->
{
PRIVLVL
})
{
$self
->
{
IPMICMD
}
.=
"
-L
$self
->{PRIVLVL}
";
}
# Do a quick query, to see if it works
system
("
$self
->{IPMICMD} power status >/dev/null 2>
\
&1
");
...
...
@@ -274,3 +280,7 @@ sub _get_msaddr($$) {
# End with true
1
;
# vim: set ft=perl et sw=4 ts=8:
# Not sure what the (no)et sw=? ts=? rules should be in this file - they're kind of mixed.
# Seems like a leading tab in some places and then 4 expanded spaces. Maybe et sw=4 ts=8.
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment