#!/usr/bin/perl
# Author: Erik Ziegenbalg <ez681d@att.com>
# Date: Feb 2018
# Description: Scripts to update the /etc/ppp/chaps file based on resources
# defined in the vyatta config.
#
# Copyright (c) 2017-2018, AT&T Intellectual Property.
#
# All Rights Reserved.
#
# SPDX-License-Identifier: GPL-2.0-only

use strict;
use warnings;

use lib "/opt/vyatta/share/perl5";
use Vyatta::Configd;

# Read in chap secrets. Returns array with each index containing a hashmap to a chap-entry.
#
sub parse_chap {
    my $read_entry = sub {
        my ( $name, $server, $secret, $local_addrs, @comment ) = @_;
        my $out = {
            "name"            => $name,
            "server"          => $server,
            "secret"          => $secret,
            "local-addresses" => $local_addrs,
            "comment"         => join( " ", @comment ),
        };
        $out->{'comment'} = "" unless defined $out->{'comment'};
        if ( "$out->{'comment'}" =~ "# Auto-generated by vyatta-update-chap" ) {
            return;    #Don't read in Vyatta auto generated enteries
        }
        return $out;
    };

    open( my $FH, '<', "/etc/ppp/chap-secrets" )
      or die "Could not open chap-secrets\n";
    my @ret;
    while ( my $row = <$FH> ) {
        my @line_in = split /[ \t\n]/, $row;
        next if !defined $line_in[0];
        next if $line_in[0] =~ /\#[\s\$]*/;
        next if scalar(@line_in) < 4;
        push @ret, $read_entry->(@line_in);
    }
    return @ret;
}

sub write_to_file {
    my (@out) = @_;
    open( my $fh, '>', '/etc/ppp/chap-secrets' )
      or die "Could not open chaps file for writing\n";
    foreach my $line (@out) {
        print $fh
"$line->{'name'}\t$line->{'server'}\t$line->{'secret'}\t$line->{'local-addresses'}\t$line->{'comment'}\n";
    }
    close($fh);
}

sub update_chap {
    my @chaps        = parse_chap();
    my @config_chaps = ();
    my $conf         = Vyatta::Configd::Client->new();

    die "Config not found"
      unless defined($conf);

    if (
        $conf->node_exists(
            $Vyatta::Configd::Client::AUTO,
            "resources chap-secrets user"
        )
      )
    {
        my $chap_tree = $conf->tree_get_hash("resources chap-secrets user");
        my $convert_config_to_chap = sub {
            my ($element) = @_;
            $element->{'comment'} = "# Auto-generated by vyatta-update-chap";
            $element->{'local-addresses'} = '*'
              unless defined $element->{'local-addresses'};
            $element->{'server'} = '*'
              unless defined $element->{'server'};
            return $element;
        };
        @config_chaps =
          map { $convert_config_to_chap->($_); } @{ $chap_tree->{'user'} };
    }

    my @merge = ( @chaps, @config_chaps );

    # Updates /etc/ppp/chap-secrets
    #
    write_to_file(@merge);

}

update_chap();
