Newer
Older
#!/usr/bin/perl
use strict;
use warnings;
use IO::File;
use IO::Pipe;
use feature 'switch';
my ($filename, $conf);
$filename = '/boot/firmware/sysconf.txt';
logger('info', "Reading the system configuration settings from $filename");
$conf = read_conf($filename);
if (my $pass = delete($conf->{root_password})) {
my $pipe;
logger('debug', 'Resetting root password');
unless (open($pipe, '|-', '/usr/sbin/chpasswd')) {
my $err = $!;
logger('error', "Could not run chpasswd: $err");
die $err;
}
$pipe->print("root:$pass");
close($pipe);
if (my $user_pass = delete($conf->{user_password})) {
logger('debug', "Resetting $current_user password");
unless (open($pipe, '|-', '/usr/sbin/chpasswd')) {
my $err = $!;
logger('error', "Could not run chpasswd: $err");
die $err;
}
$pipe->print("$current_user:$user_pass");
system("sed -i -e 's:\\] with a one time password of \\[temppwd\\]:\\]:g' /etc/issue");
system("sed -i -e 's:\\] with a one time password of \\[temppwd\\]:\\]:g' /etc/issue.net");
if (my $root_authorized_key = delete($conf->{root_authorized_key})) {
my $fh;
logger('debug', "Adding key to root's authorized_keys");
if(! -d "/root/.ssh") {
if(!mkdir("/root/.ssh", 0700)) {
my $err = sprintf("Could not create /root/.ssh directory: %s", $!);
logger('error', $err);
die $err;
}
}
unless ($fh = IO::File->new('/root/.ssh/authorized_keys', 'w', 0600)) {
my $err = $!;
logger('error', "Could not write /root/.ssh/authorized_keys: $err");
die $err;
}
$fh->print($root_authorized_key);
$fh->close;
}
if (my $user_authorized_key = delete($conf->{user_authorized_key})) {
logger('debug', "Adding key to $current_user authorized_keys");
if(! -d "/home/$current_user/.ssh") {
if(!mkdir("/home/$current_user/.ssh", 0700)) {
my $err = sprintf("Could not create /home/$current_user/.ssh directory: %s", $!);
logger('error', $err);
die $err;
}
}
unless ($fh = IO::File->new("/home/$current_user/.ssh/authorized_keys", 'w', 0600)) {
logger('error', "Could not write /home/$current_user/.ssh/authorized_keys: $err");
die $err;
}
$fh->print($user_authorized_key);
$fh->close;
system("chown -R $user:$group /home/$current_user/.ssh/");
if (my $new_user_name = delete($conf->{user_name})) {
logger('debug', "Changing $current_user to $new_user_name");
system("usermod --login $new_user_name --home /home/$new_user_name --move-home $current_user");
system("groupmod --new-name $new_user_name $current_user");
if( -f "/etc/lightdm/lightdm.conf") {
system("sed -i -e 's:$current_user :$new_user_name:g' /etc/lightdm/lightdm.conf");
}
}
$call_reboot = 1;
}
if (my $iwd_psk_file = delete($conf->{iwd_psk_file})) {
logger('debug', "Setting up iwd with '$iwd_psk_file'");
if( -f "/boot/firmware/services/$iwd_psk_file") {
system("cp /boot/firmware/services/$iwd_psk_file /var/lib/iwd/");
system("dos2unix -q /var/lib/iwd/$iwd_psk_file");
system("systemctl restart iwd.service");
if (my $hostapd_file = delete($conf->{hostapd_file})) {
logger('debug', "Setting up hostapd with '$hostapd_file'");
if( -f "/boot/firmware/services/$hostapd_file") {
system("cp /boot/firmware/services/$hostapd_file /etc/hostapd/SoftAp0.conf");
system("dos2unix -q /etc/hostapd/SoftAp0.conf");
system("systemctl restart hostapd\@SoftAp0.service");
if (my $name = delete($conf->{hostname})) {
my $fh;
logger('debug', "Setting hostname to '$name'");
unless ($fh = IO::File->new('/etc/hostname', 'w')) {
my $err = $!;
logger('error', "Could not write hostname '$name': $err");
die $err;
}
$fh->print($name);
$fh->close;
system('hostname', '--file', '/etc/hostname');
my $fha;
logger('debug', "Adding '$name' to /etc/hosts");
unless ($fha = IO::File->new('/etc/hosts', 'w')) {
my $err = $!;
logger('error', "Could not write to /etc/hosts '$name': $err");
die $err;
}
$fha->print("127.0.0.1 localhost\n");
$fha->print("127.0.1.1 ", $name, ".localdomain ", $name, "\n");
$fha->print("\n");
$fha->print("# The following lines are desirable for IPv6 capable hosts\n");
$fha->print("::1 localhost ip6-localhost ip6-loopback\n");
$fha->print("ff02::1 ip6-allnodes\n");
$fha->print("ff02::2 ip6-allrouters\n");
$fha->close;
if (my $legacy_rndis_support = delete($conf->{legacy_rndis_support})) {
logger('debug', "Enabling Legacy RNDIS support");
if( -f "/etc/default/bb-boot") {
system("sed -i -e 's:USB_RNDIS_DISABLED=yes:#USB_RNDIS_DISABLED=yes:g' /etc/default/bb-boot");
$call_reboot = 1;
}
}
rewrite_conf_file($filename, $conf);
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
exit 0;
sub read_conf {
my ($file, $conf, $fh);
$file = shift;
$conf = {};
unless ($fh = IO::File->new($filename, 'r')) {
my $err = $!;
logger('error', "Could not read from configuration file '$filename': $err");
# Not finding the config file is not fatal: there is just
# nothing to configure!
return $conf;
}
while (my $line = $fh->getline) {
my ($key, $value);
# Allow for comments, and properly ignore them
$line =~ s/#.+//;
if ( ($key, $value) = ($line =~ m/^\s*([^=]+)\s*=\s*(.*)\s*$/)) {
$key = lc($key);
if (exists($conf->{$key})) {
logger('warn',
"Repeated configuration key: $key. " .
"Overwriting with new value ($value)");
}
$conf->{$key} = $value;
}
}
$fh->close;
return $conf;
}
sub logger {
my ($prio, $msg) = @_;
system('logger', '-p', "daemon.$prio",
'-t', 'bbbio-set-sysconf', $msg);
}
sub rewrite_conf_file {
my ($filename, $conf) = @_;
my $fh;
unless ($fh = IO::File->new($filename, 'w')) {
my $err = $!;
logger('error', "Could not write to configuration file '$filename': $err");
die $err;
}
$fh->print(
q(# This file will be automatically evaluated and installed at next boot
# time, and regenerated (to avoid leaking passwords and such information).
#
# To force it to be evaluated immediately, you can run (as root):
#
# /usr/sbin/bbbio-set-sysconf
#
# You can disable the file evaluation by disabling the bbbio-set-sysconf
# service in systemd:
#
# systemctl disable bbbio-set-sysconf
#
# Comments (all portions of a line following a '#' character) are
# ignored. This file is read line by line. Valid
# configuration lines are of the form 'key=value'. Whitespace around
# 'key' and 'value' is ignored. This file will be _regenerated_ every
# time it is evaluated.
#
# We follow the convention to indent with one space comments, and
# leave no space to indicate the line is an example that could be
# uncommented.
# user_name - Set a user name for the user (1000)
# user_password - Set a password for user (1000)
#user_password=FooBar
# user_authorized_key - Set an authorized key for a user (1000) ssh login
#user_authorized_key=
# iwd_psk_file - Set a configuration for iwd https://wiki.archlinux.org/title/iwd
#iwd_psk_file=
# hostapd_file - Set a configuration for hostapd https://wiki.gentoo.org/wiki/Hostapd
#hostapd_file=SoftAp0.conf
));
if (scalar keys %$conf) {
logger('warn', 'Unprocessed keys left in $filename: ' .
join(', ', sort keys %$conf));
$fh->print(
q(
# We found the following unhandled keys - That means, the
# configuration script does not know how to handle them. Please
# double-check them!
));
$fh->print(join('', map {sprintf("%s=%s\n", $_, $conf->{$_})} sort keys %$conf));
}
$fh->close;
}