shuffle things around so that it works for a user created via an assertion
This commit is contained in:
parent
e8850b4a74
commit
7c7fc8218f
|
@ -2,6 +2,8 @@
|
|||
set -e
|
||||
|
||||
trap true HUP INT QUIT TSTP
|
||||
echo_on () { stty echo; }
|
||||
trap echo_on EXIT
|
||||
|
||||
# agetty only sets ICRNL if it has read the username and seen whether
|
||||
# it was terminated by CR or NL. We pass -n to agetty so that hasn't
|
||||
|
@ -11,9 +13,12 @@ stty icrnl -echo
|
|||
if [ "$(snap managed)" = "true" ]; then
|
||||
# check if we have extrausers that have no password set
|
||||
if grep -qE '^[-a-z0-9+.-_]+:x:' /var/lib/extrausers/passwd && ! grep -qE '^[-a-z0-9+.-_]+:\$[0-9]+\$.*:' /var/lib/extrausers/shadow; then
|
||||
cat /var/lib/console-conf/login-details.txt
|
||||
if [ ! -f /run/console-conf/login-details.txt ]; then
|
||||
mkdir -p /run/console-conf
|
||||
/usr/share/subiquity/console-conf-write-login-details > /run/console-conf/login-details.txt
|
||||
fi
|
||||
cat /run/console-conf/login-details.txt
|
||||
read REPLY
|
||||
stty echo
|
||||
else
|
||||
touch /var/lib/console-conf/complete
|
||||
fi
|
||||
|
@ -22,5 +27,4 @@ fi
|
|||
|
||||
cat /usr/share/subiquity/console-conf-wait
|
||||
read REPLY
|
||||
stty echo
|
||||
exec console-conf "$@"
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
#!/usr/bin/env python3
|
||||
# Copyright 2015 Canonical, Ltd.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import sys
|
||||
|
||||
from console_conf.controllers.identity import write_login_details_standalone
|
||||
|
||||
sys.exit(write_login_details_standalone())
|
|
@ -15,7 +15,9 @@
|
|||
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
from subiquitycore.controllers.identity import BaseIdentityController
|
||||
from subiquitycore.utils import disable_first_boot_service, run_command
|
||||
|
@ -34,6 +36,64 @@ Public SSH keys were added to the device for remote access.
|
|||
"""
|
||||
|
||||
|
||||
def get_device_owner():
|
||||
""" Check if device is owned """
|
||||
|
||||
# TODO: use proper snap APIs.
|
||||
try:
|
||||
extrausers_fp = open('/var/lib/extrausers/passwd', 'r')
|
||||
except FileNotFoundError:
|
||||
return None
|
||||
with extrausers_fp:
|
||||
passwd_line = extrausers_fp.readline()
|
||||
if passwd_line and len(passwd_line) > 0:
|
||||
passwd = passwd_line.split(':')
|
||||
result = {
|
||||
'realname': passwd[4].split(',')[0],
|
||||
'username': passwd[0],
|
||||
'homedir': passwd[5],
|
||||
}
|
||||
return result
|
||||
return None
|
||||
|
||||
|
||||
def write_login_details(fp, realname, username, ips, fingerprints):
|
||||
fp.write(login_details_tmpl.format(realname=realname, username=username))
|
||||
for ip in ips:
|
||||
fp.write(" ssh %s@%s\n"%(username, ip))
|
||||
fp.write("\nSSH keys with the following fingerprints can be used to log in:\n\n")
|
||||
for fingerprint in fingerprints:
|
||||
fp.write(" " + fingerprint + "\n")
|
||||
fp.write("\nPressing enter after setting a password will allow you to log in here.\n")
|
||||
|
||||
|
||||
def write_login_details_standalone():
|
||||
owner = get_device_owner()
|
||||
if owner is None:
|
||||
# Nothing much we can do :/
|
||||
print("No device owner details found")
|
||||
return 0
|
||||
from probert import network
|
||||
from subiquitycore.models.network import NETDEV_IGNORED_IFACE_NAMES, NETDEV_IGNORED_IFACE_TYPES
|
||||
import ipaddress
|
||||
import operator
|
||||
import socket
|
||||
observer = network.UdevObserver()
|
||||
observer.start()
|
||||
ips = []
|
||||
for l in sorted(observer.links.values(), key=operator.attrgetter('name')):
|
||||
if l.type in NETDEV_IGNORED_IFACE_TYPES:
|
||||
continue
|
||||
if l.name in NETDEV_IGNORED_IFACE_NAMES:
|
||||
continue
|
||||
ips.extend([str(ipaddress.IPv4Interface(a).ip) for a in l.ip.get(socket.AF_INET, [])])
|
||||
ips.extend([str(ipaddress.IPv6Interface(a).ip) for a in l.ip.get(socket.AF_INET6, [])])
|
||||
key_file = os.path.join(owner['homedir'], ".ssh/authorized_keys")
|
||||
fingerprints = run_command(['ssh-keygen', '-lf', key_file])['output'].replace('\r', '').splitlines()
|
||||
write_login_details(sys.stdout, owner['realname'], owner['username'], ips, fingerprints)
|
||||
return 0
|
||||
|
||||
|
||||
class IdentityController(BaseIdentityController):
|
||||
identity_view = IdentityView
|
||||
|
||||
|
@ -44,30 +104,11 @@ class IdentityController(BaseIdentityController):
|
|||
self.ui.set_header(title, excerpt)
|
||||
self.ui.set_footer(footer, 40)
|
||||
self.ui.set_body(self.identity_view(self.model, self, self.opts, self.loop))
|
||||
device_owner = self.get_device_owner()
|
||||
device_owner = get_device_owner()
|
||||
if device_owner is not None:
|
||||
self.model.add_user(device_owner)
|
||||
self.login()
|
||||
|
||||
def get_device_owner(self):
|
||||
""" Check if device is owned """
|
||||
|
||||
# TODO: use proper snap APIs.
|
||||
try:
|
||||
extrausers_fp = open('/var/lib/extrausers/passwd', 'r')
|
||||
except FileNotFoundError:
|
||||
return None
|
||||
with extrausers_fp:
|
||||
passwd_line = extrausers_fp.readline()
|
||||
if passwd_line and len(passwd_line) > 0:
|
||||
passwd = passwd_line.split(':')
|
||||
result = {
|
||||
'realname': passwd[4].split(',')[0],
|
||||
'username': passwd[0],
|
||||
}
|
||||
return result
|
||||
return None
|
||||
|
||||
def identity_done(self, email):
|
||||
if self.opts.dry_run:
|
||||
result = {
|
||||
|
@ -92,25 +133,22 @@ class IdentityController(BaseIdentityController):
|
|||
'username': data['username'],
|
||||
}
|
||||
ssh_keys = data['ssh-keys']
|
||||
login_details_path = '/var/lib/console-conf/login-details.txt'
|
||||
os.makedirs('/run/console-conf', exist_ok=True)
|
||||
login_details_path = '/run/console-conf/login-details.txt'
|
||||
self.model.add_user(result)
|
||||
log.debug('ssh_keys %s', ssh_keys)
|
||||
fingerprints = []
|
||||
for key in ssh_keys:
|
||||
keygen_result = subprocess.Popen(['ssh-keygen', '-lf', '-'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
|
||||
fingerprint, err = keygen_result.communicate(key.encode('utf-8'))
|
||||
fingerprints.append(fingerprint.decode('utf-8', 'replace').replace('\r', ''))
|
||||
fingerprints.append(fingerprint.decode('utf-8', 'replace').replace('\r', '').strip())
|
||||
log.debug('fingerprints %s', fingerprints)
|
||||
ips = []
|
||||
net_model = self.controllers['Network'].model
|
||||
for dev in net_model.get_all_netdevs():
|
||||
ips.extend(dev.actual_ip_addresses)
|
||||
with open(login_details_path, 'w') as fp:
|
||||
fp.write(login_details_tmpl.format(**result))
|
||||
for dev in net_model.get_all_netdevs():
|
||||
for ip in dev.actual_ip_addresses:
|
||||
fp.write(" ssh %s@%s\n"%(result['username'], ip))
|
||||
fp.write("\nSSH keys with the following fingerprints can be used to log in:\n\n")
|
||||
for fingerprint in fingerprints:
|
||||
fp.write(" " + fingerprint)
|
||||
fp.write("\nPressing enter after setting a password will allow you to log in here.\n")
|
||||
write_login_details(fp, result['realname'], result['username'], ips, fingerprints)
|
||||
self.login()
|
||||
|
||||
def cancel(self):
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
subiquity (0.0.24~ppa4) xenial; urgency=medium
|
||||
subiquity (0.0.24~ppa5) xenial; urgency=medium
|
||||
|
||||
* Rework network model and UI significantly.
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
bin/console-conf-tui usr/share/subiquity
|
||||
bin/console-conf-wait usr/share/subiquity
|
||||
bin/console-conf-wrapper usr/share/subiquity
|
||||
bin/console-conf-write-login-details usr/share/subiquity
|
||||
usr/share/subiquity/console_conf
|
||||
|
|
Loading…
Reference in New Issue