###
###  Copyright 2000-2007 University of Illinois Board of Trustees
###  All rights reserved. 
###
###  sshd.pm - sshd module for psgconf
###
###  Campus Information Technologies and Educational Services
###  University of Illinois at Urbana-Champaign
###


package PSGConf::Control::sshd;

use strict;

use PSGConf::Action::RestartDaemon;
use PSGConf::Action::GenerateFile::sshd_config;
use PSGConf::Data::Boolean;
use PSGConf::Data::List;
use PSGConf::Data::Hash;
use PSGConf::Data::String;
use PSGConf::Control::Packages qw(_add_pkgs);


###############################################################################
###  Constructor
###############################################################################

sub new
{
	my ($class, $psgconf) = @_;
	my ($self);

	$self = {};
	bless($self, $class);

     ### So that _add_pkgs knows which directives to look at
     $self->{name} = 'sshd';
	$self->{enable} = $self->{name} . '_enable';
	$self->{packages} = $self->{name} . '_packages';

	$psgconf->register_data(
		'sshd_enable'		=> PSGConf::Data::Boolean->new(
						value => 'true',
					),
		'sshd_config_dir'	=> PSGConf::Data::String->new(
						'value_abspath' => 1,
						value => '/etc'
					),
		'sshd_listen_addrs'	=> PSGConf::Data::Hash->new(
						'value_optional' => 1
					),
		'ssh_enable'		=> PSGConf::Data::Boolean->new(
						value => 'true',
					),
		'ssh_options'		=> PSGConf::Data::Hash->new(),
		'sshd_options'		=> PSGConf::Data::Hash->new(),
 		'ssh_packages'		=> PSGConf::Data::List->new(),
 		'sshd_packages'	=> PSGConf::Data::List->new(),
		'sshd_subsystems'	=> PSGConf::Data::Hash->new(),
		'sshd_cmd'		=> PSGConf::Data::String->new(
						'value_abspath' => 1,
						value => "/usr/sbin/sshd",
					)
	);

	$psgconf->register_policy($self,
		sshd_default_pidfile	=> '_policy_default_pidfile',
		sshd_enable_rc_scripts => '_policy_enable_rc_scripts',
		ssh_add_packages    => '_policy_add_packages'
	);

	return $self;
}


###############################################################################
###  policy method
###############################################################################

sub _policy_add_packages
{
     my ($self, $psgconf) = @_;

	### Call the _add_pkgs for the sshd stuff.
	$self->_add_pkgs($psgconf);

	### Now hack up the call and call again fir the ssh itself.
	$self->{enable} = 'ssh_enable';
	$self->{packages} = 'ssh_packages';
	$self->_add_pkgs($psgconf);
}


### set default pidfile location
sub _policy_default_pidfile
{
	my ($self, $psgconf) = @_;

	$psgconf->data_obj('sshd_options')->insert(
		{ 'PidFile' => $psgconf->data_obj('pidfile_dir')->get() . '/sshd.pid' }
	) if (!defined $psgconf->data_obj('sshd_options')->find('PidFile'));
}


sub _policy_enable_rc_scripts
{
	my ($self, $psgconf) = @_;
	my ($pidfile);

	$pidfile = $psgconf->data_obj('sshd_options')->find('PidFile');

	if ( $psgconf->data_obj('sshd_enable')->equals('true')) {
		$psgconf->data_obj('rc_scripts')->insert(
			{ 'sshd' => {
					'state'		=> 'enable',
					'start_cmd'	=> $psgconf->data_obj('sshd_cmd')->get(),
					'stop_cmd'	=> "kill `cat $pidfile`"
				}
			}
		);
	}
}


###############################################################################
###  decide() method
###############################################################################

sub decide
{
	my ($self, $psgconf) = @_;
	my ($config_dir);

	$config_dir = $psgconf->data_obj('sshd_config_dir')->get();

	if ($psgconf->data_obj('sshd_enable')->equals('true')) {
		$psgconf->register_actions(
			PSGConf::Action::GenerateFile::sshd_config->new(
				name			=> $config_dir . '/sshd_config',
				description	=> 'sshd configuration file',
				listen_addrs	=> $psgconf->data_obj('sshd_listen_addrs')->get(),
				host_keys		=> [ glob($config_dir . '/ssh_host_*key') ],
				options		=> $psgconf->data_obj('sshd_options')->get(),
				subsystems	=> $psgconf->data_obj('sshd_subsystems')->get()
			),
			PSGConf::Action::RestartDaemon->new(
				name			=> 'sshd',
				pidfile		=> $psgconf->data_obj('sshd_options')->find('PidFile'),
				filename		=> [ $config_dir . '/sshd_config',
							# FIXME: Need to check that the sshd
							# command was updated so we know to bounce
							# the daemon itself.
							$psgconf->data_obj('sshd_cmd')->get() ]
			)
		);
	}

	$psgconf->register_actions(
		PSGConf::Action::GenerateFile::sshd_config->new(
			'name'		=> $config_dir . '/ssh_config',
			'description'	=> 'ssh configuration file',
			'options'	=> $psgconf->data_obj('ssh_options')->get()
		)
	) if ($psgconf->data_obj('ssh_enable')->equals('true'));
}


###############################################################################
###  documentation
###############################################################################

1;

__END__

=head1 NAME

PSGConf::Control::sshd - psgconf control class for sshd

=head1 SYNOPSIS

In F<psgconf_modules>:

  Control PSGConf::Control::sshd

=head1 DESCRIPTION

The B<PSGConf::Control::sshd> module provides a B<psgconf> control object
for configuring C<sshd>.  It supports the following methods:

=over 4

=item new()

The constructor.  Its parameter is a reference to the B<PSGConf>
object.  It registers the following data objects:

=over 4

=item I<ssh_enable>

A B<PSGConf::Data::Boolean> object to decide whether F<ssh_config>
should be mananged.

=item I<sshd_enable>

A B<PSGConf::Data::Boolean> object to decide whether F<sshd_config>
should be mananged.

=item I<ssh_packages>

A B<PSGConf::Data::List> object containing the SSH packages to install.

=item I<sshd_packages>

A B<PSGConf::Data::List> object containing the SSH server packages to install.

=item I<sshd_config_dir>

A B<PSGConf::Data::String> object that contains the absolute path to
the directory containing C<sshd> config files.  The default is F</etc>.

=item I<sshd_listen_addrs>

A B<PSGConf::Data::Hash> object whose keys are a list of addresses to
listen on.

=item I<ssh_options>

A B<PSGConf::Data::Hash> object containing C<ssh> options and their
settings.

=item I<sshd_options>

A B<PSGConf::Data::Hash> object containing C<sshd> options and their
settings.

=item I<sshd_subsystems>

A B<PSGConf::Data::Hash> object containing C<sshd> subsystems.  The hash
key is the name of the subsystem, and the value is the program that
implements the subsystem.

=back

The constructor also registers the following policy methods:

=over 4

=item I<sshd_default_pidfile>

If the I<sshd_options> object does not contain an entry for the
C<PidFile> option, set it to F<I<pidfile_dir>/sshd.pid>.  (The
I<pidfile_dir> object is provided by the B<PSGConf::Control::Core>
module.)

=item I<sshd_enable_rc_scripts>

Modifies the I<rc_scripts> data object (provided by
B<PSGConf::Control::InitScripts>) to enable C<sshd>, based on
the F<sshd_enable> data object.

=back

=item decide()

Registers B<PSGConf::Action::GenerateFile::sshd_config> action objects
to create F</etc/sshd_config> and F</etc/ssh_config>, if F<sshd_enable>
and I<ssh_enable> are set (respectively).

=back

=head1 SEE ALSO

L<perl>

sshd(8)

L<PSGConf>

L<PSGConf::Action::GenerateFile::sshd_config>

L<PSGConf::Action::RestartDaemon>

L<PSGConf::Control::Core>

L<PSGConf::Control::InitScripts>

L<PSGConf::Control::Packages>

L<PSGConf::Data::Boolean>

L<PSGConf::Data::Boolean>

L<PSGConf::Data::Hash>

L<PSGConf::Data::List>

L<PSGConf::Data::String>

L<psgconf-intro>

=cut



syntax highlighted by Code2HTML, v. 0.9.1