Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • smradius/smradius
  • centiva-shail/smradius
  • nkukard/smradius
3 results
Show changes
Commits on Source (153)
Showing with 731 additions and 503 deletions
...@@ -3,15 +3,21 @@ stages: ...@@ -3,15 +3,21 @@ stages:
- tests - tests
- install - install
code-quality: code-quality:
stage: quality stage: quality
script: script:
- export DEBIAN_FRONTEND=noninteractive - export DEBIAN_FRONTEND=noninteractive
- apt-get update - apt-get update
- apt-get dist-upgrade -y - apt-get dist-upgrade -y
- apt-get install -y libperl-critic-perl make - apt-get install -y perl-modules
- apt-get install -y make
- apt-get install -y libperl-critic-perl
- perlcritic --gentle "$CI_PROJECT_DIR" - perlcritic --gentle "$CI_PROJECT_DIR"
make-test: make-test:
stage: tests stage: tests
script: script:
...@@ -19,11 +25,44 @@ make-test: ...@@ -19,11 +25,44 @@ make-test:
- apt-get update - apt-get update
- apt-get dist-upgrade -y - apt-get dist-upgrade -y
- apt-get install -y git make - apt-get install -y git make
- apt-get install -y mysql-server - apt-get install -y libdevel-cover-perl libpod-coverage-perl libtest-most-perl
- apt-get install -y libnet-server-perl libconfig-inifiles-perl libdatetime-perl libcache-fastmmap-perl libtimedate-perl
libcrypt-des-perl libcrypt-rc4-perl libdigest-sha-perl libdigest-md4-perl libmime-lite-perl
- apt-get install -y mariadb-server
# Start services and create dirs we need
- service mysql start
- mkdir /var/run/smradius
# Update our dependencies
- cd "$CI_PROJECT_DIR" - cd "$CI_PROJECT_DIR"
- ./update-git-modules - ./update-git-modules
- perl -MCPAN -e 'install Math::Expression' < /dev/null
# Build Makefile and make
- perl Makefile.PL - perl Makefile.PL
- make test - make
# Convert DB into MySQL
- blib/script/convert-tsql MySQL database/core.tsql > database/core.mysql
- blib/script/convert-tsql MySQL database/users-accounting-summary.tsql > database/users-accounting-summary.mysql
- blib/script/convert-tsql MySQL database/wisp.tsql > database/wisp.mysql
# Load SQL into DB
- echo "CREATE DATABASE smradiustest;" | mysql -u root
- mysql -u root smradiustest < database/core.mysql
- mysql -u root smradiustest < database/users-accounting-summary.mysql
- mysql -u root smradiustest < database/wisp.mysql
# Sort out config file
- cp smradiusd.conf smradiusd.conf.test
- perl -pi -e 's/database=smradius/database=smradiustest/' smradiusd.conf.test
# Run tests, exclude all but smradius
- DBTESTS=1 cover -test -ignore_re '.*' -select_re '^blib\/lib\/smradius\/' | tee devel-coverage.txt
- grep "^Total" devel-coverage.txt | awk '{ print "(" $8 "%) covered" }'
make-install: make-install:
stage: install stage: install
...@@ -32,7 +71,7 @@ make-install: ...@@ -32,7 +71,7 @@ make-install:
- apt-get update - apt-get update
- apt-get dist-upgrade -y - apt-get dist-upgrade -y
- apt-get install -y git make - apt-get install -y git make
- apt-get install -y mysql-server - apt-get install -y mariadb-server
- cd "$CI_PROJECT_DIR" - cd "$CI_PROJECT_DIR"
- ./update-git-modules - ./update-git-modules
- perl Makefile.PL - perl Makefile.PL
......
my @additionalDirs = ();
# Makefile # Makefile
# Copyright (C) 2014-2016, AllWorldIT # Copyright (C) 2014-2016, AllWorldIT
# #
...@@ -28,6 +27,8 @@ use File::Find; ...@@ -28,6 +27,8 @@ use File::Find;
my @additionalDirs = ();
find( find(
{ {
wanted => sub { wanted => sub {
...@@ -44,8 +45,6 @@ find( ...@@ -44,8 +45,6 @@ find(
".", ".",
); );
WriteMakefile( WriteMakefile(
'NAME' => 'SMRadius-3rdParty', 'NAME' => 'SMRadius-3rdParty',
......
awitpt @ 6944c201
Subproject commit 201569f905bade5bf06cb06866dcd54f6b99c100 Subproject commit 6944c2017372a13a334f902fdd8461e171393949
...@@ -27,7 +27,7 @@ Enhanced features: ...@@ -27,7 +27,7 @@ Enhanced features:
* Plugin: Topups * Plugin: Topups
* Plugin: Auto-topups * Plugin: Auto-topups
* Plugin: Usage/Time caps * Plugin: Usage/Time caps
* Plugin: Prepaid accounting based on usage/time * Plugin: Prepaid accounting based on usage/time
* Plugin: Creation of accounting START records when no START record has been received but an interim update has - helps on slow/lossly links * Plugin: Creation of accounting START records when no START record has been received but an interim update has - helps on slow/lossly links
* Plugin: Notifications, % based or approximate time based * Plugin: Notifications, % based or approximate time based
* Plugin: User blacklists * Plugin: User blacklists
......
...@@ -8,10 +8,10 @@ Installing SMRadius. ...@@ -8,10 +8,10 @@ Installing SMRadius.
- Cache::FastMmap (Debian based: libcache-fastmmap-perl, RPM based: perl-Cache-FastMmap) - Cache::FastMmap (Debian based: libcache-fastmmap-perl, RPM based: perl-Cache-FastMmap)
- DateTime (requires: perl-Class-Singleton) - DateTime (requires: perl-Class-Singleton)
- TimeDate - TimeDate
- Crypt::DES - Crypt::DES (Debian based: libcrypt-des-perl)
- Crytpt::RC4 - Crytpt::RC4 (Debian based: libcrypt-rc4-perl)
- Digest::SHA1 - Digest::SHA1 (Debian based: libdigest-sha-perl)
- Digest::MD4 - Digest::MD4 (Debian based: libdigest-md4-perl)
- Math::Expression - Math::Expression
* Requirements for webui * Requirements for webui
......
...@@ -37,7 +37,11 @@ WriteMakefile( ...@@ -37,7 +37,11 @@ WriteMakefile(
'DIR' => ["3rdparty"], 'DIR' => ["3rdparty"],
'EXE_FILES' => [qw( bin/smradiusd bin/smadmin bin/smradclient )], 'EXE_FILES' => [qw(
bin/smradiusd
bin/smadmin
bin/smradclient
)],
); );
......
[![build status](https://gitlab.devlabs.linuxassist.net/smradius/smradius/badges/master/build.svg)](https://gitlab.devlabs.linuxassist.net/smradius/smradius/commits/master)
[![coverage report](https://gitlab.devlabs.linuxassist.net/smradius/smradius/badges/master/coverage.svg)](https://gitlab.devlabs.linuxassist.net/smradius/smradius/commits/master)
\ No newline at end of file
...@@ -5,8 +5,7 @@ smradiusd: ...@@ -5,8 +5,7 @@ smradiusd:
* Create a raddbpath config option which is prepended to dict paths * Create a raddbpath config option which is prepended to dict paths
usage related queries: * Configurable 'use defaults for POD/CoA' we may not want to send these
* Use Math module to perform calculations
smadmin: smadmin:
* Ability to run smadmin before the end of current month and updating the records as necessary at a later stage * Ability to run smadmin before the end of current month and updating the records as necessary at a later stage
......
...@@ -23,8 +23,9 @@ use warnings; ...@@ -23,8 +23,9 @@ use warnings;
use Config;
use FindBin; use FindBin;
use lib "$FindBin::Bin/../share/perl5"; use lib ("$FindBin::Bin/../lib", "$FindBin::Bin/../share/perl5", "$FindBin::Bin/../share/perl/$Config{'version'}");
......
...@@ -21,16 +21,18 @@ use warnings; ...@@ -21,16 +21,18 @@ use warnings;
use Config;
use FindBin; use FindBin;
use lib "$FindBin::Bin/../share/perl5"; use lib ("$FindBin::Bin/../lib", "$FindBin::Bin/../share/perl5", "$FindBin::Bin/../share/perl/$Config{'version'}");
use smradius::client; use smradius::client;
smradius::client->run(); # Grab and exit with result received
my $res = smradius::client->run();
exit($res);
1;
# vim: ts=4 # vim: ts=4
...@@ -23,14 +23,12 @@ use warnings; ...@@ -23,14 +23,12 @@ use warnings;
use Config;
use FindBin; use FindBin;
use lib "$FindBin::Bin/../share/perl5"; use lib ("$FindBin::Bin/../lib", "$FindBin::Bin/../share/perl5", "$FindBin::Bin/../share/perl/$Config{'version'}");
use smradius::daemon; use smradius::daemon;
smradius::daemon->run(); smradius::daemon->run();
......
#!/bin/bash
# Database translation/creation script
# Copyright (C) 2009-2016, AllWorldIT
# Copyright (C) 2008, LinuxRulz
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
database="$1"
file="$2"
prefix="$3"
# Display usage info
display_usage() {
echo "Usage: $0 <database type> <file> [prefix]"
echo
echo "Valid database types:"
echo " mysql - For MySQL v5.5+"
echo " pgsql - For PostgreSQL"
echo " sqlite - For SQLite v3"
echo
exit
}
# Check we have our params
if [ -z "$database" -o -z "$file" ]
then
display_usage
fi
# Check file exists
if [ ! -f "$file" ]
then
echo "ERROR: Cannot open file '$file'"
exit 1
fi
# Check what we converting for
case "$database" in
"mysql")
sed \
-e "s/@PREFIX@/$prefix/g" \
-e 's/@PRELOAD@/SET FOREIGN_KEY_CHECKS=0;/' \
-e 's/@POSTLOAD@/SET FOREIGN_KEY_CHECKS=1;/' \
-e 's/@CREATE_TABLE_SUFFIX@/ENGINE=InnoDB CHARACTER SET latin1 COLLATE latin1_bin/' \
-e 's/@SERIAL_TYPE@/SERIAL/' \
-e 's/@BIGINT_UNSIGNED@/BIGINT UNSIGNED/' \
-e 's/@INT_UNSIGNED@/INT UNSIGNED/' \
-e 's/@TRACK_KEY_LEN@/512/' \
-e 's/@SERIAL_REF_TYPE@/BIGINT UNSIGNED/' < "$file"
;;
"pgsql")
sed \
-e "s/@PREFIX@/$prefix/g" \
-e 's/@PRELOAD@/SET CONSTRAINTS ALL DEFERRED;/' \
-e 's/@POSTLOAD@//' \
-e 's/@CREATE_TABLE_SUFFIX@//' \
-e 's/@SERIAL_TYPE@/SERIAL PRIMARY KEY/' \
-e 's/@BIGINT_UNSIGNED@/INT8/' \
-e 's/@INT_UNSIGNED@/INT8/' \
-e 's/@TRACK_KEY_LEN@/512/' \
-e 's/@SERIAL_REF_TYPE@/INT8/' < "$file"
;;
"sqlite")
sed \
-e "s/@PREFIX@/$prefix/g" \
-e 's/@PRELOAD@//' \
-e 's/@POSTLOAD@//' \
-e 's/@CREATE_TABLE_SUFFIX@//' \
-e 's/@SERIAL_TYPE@/INTEGER PRIMARY KEY AUTOINCREMENT/' \
-e 's/@BIGINT_UNSIGNED@/INT8/' \
-e 's/@INT_UNSIGNED@/INT8/' \
-e 's/@TRACK_KEY_LEN@/512/' \
-e 's/@SERIAL_REF_TYPE@/INT8/' < "$file"
;;
*)
echo "ERROR: Invalid database type '$database'"
exit 1
;;
esac
...@@ -179,7 +179,7 @@ CREATE TABLE @PREFIX@topups_summary ( ...@@ -179,7 +179,7 @@ CREATE TABLE @PREFIX@topups_summary (
TopupID @SERIAL_REF_TYPE@ NOT NULL, TopupID @SERIAL_REF_TYPE@ NOT NULL,
PeriodKey VARCHAR(255) NOT NULL, PeriodKey VARCHAR(255) NOT NULL,
Balance @INT_UNSIGNED@, Balance @INT_UNSIGNED@,
...@@ -199,13 +199,13 @@ CREATE TABLE @PREFIX@accounting ( ...@@ -199,13 +199,13 @@ CREATE TABLE @PREFIX@accounting (
ServiceType @INT_UNSIGNED@, ServiceType @INT_UNSIGNED@,
FramedProtocol @INT_UNSIGNED@, FramedProtocol @INT_UNSIGNED@,
NASPort VARCHAR(255), NASPort VARCHAR(255),
NASPortType @INT_UNSIGNED@, NASPortType @INT_UNSIGNED@,
CallingStationID VARCHAR(255), CallingStationID VARCHAR(255),
CalledStationID VARCHAR(255), CalledStationID VARCHAR(255),
...@@ -251,6 +251,9 @@ CREATE INDEX @PREFIX@accounting_idx2 ON @PREFIX@accounting (PeriodKey); ...@@ -251,6 +251,9 @@ CREATE INDEX @PREFIX@accounting_idx2 ON @PREFIX@accounting (PeriodKey);
CREATE INDEX @PREFIX@accounting_idx4 ON @PREFIX@accounting (Username,AcctSessionID,NASIPAddress,NASPort); CREATE INDEX @PREFIX@accounting_idx4 ON @PREFIX@accounting (Username,AcctSessionID,NASIPAddress,NASPort);
/* accounting_update_query */ /* accounting_update_query */
CREATE INDEX @PREFIX@accounting_idx5 ON @PREFIX@accounting (Username,AcctSessionID,NASIPAddress,NASPort,PeriodKey); CREATE INDEX @PREFIX@accounting_idx5 ON @PREFIX@accounting (Username,AcctSessionID,NASIPAddress,NASPort,PeriodKey);
/* Index for the EventTimestamp */
CREATE INDEX @PREFIX@accounting_idx7 ON @PREFIX@accounting (EventTimestamp);
CREATE INDEX @PREFIX@accounting_idx8 ON @PREFIX@accounting (Username,EventTimestamp);
...@@ -269,11 +272,14 @@ CREATE TABLE @PREFIX@accounting_summary ( ...@@ -269,11 +272,14 @@ CREATE TABLE @PREFIX@accounting_summary (
TotalOutput @INT_UNSIGNED@ TotalOutput @INT_UNSIGNED@
) @CREATE_TABLE_SUFFIX@; ) @CREATE_TABLE_SUFFIX@;
CREATE INDEX @PREFIX@accounting_summary_idx1 ON @PREFIX@accounting_summary (Username);
CREATE INDEX @PREFIX@accounting_summary_idx2 ON @PREFIX@accounting_summary (PeriodKey);
CREATE INDEX @PREFIX@accounting_summary_idx3 ON @PREFIX@accounting_summary (Username,PeriodKey);
/* Users data */ /* Users data */
CREATE TABLE @PREFIX@users_data ( CREATE TABLE @PREFIX@users_data (
ID @SERIAL_TYPE@, ID @SERIAL_TYPE@,
UserID @INT_UNSIGNED@, UserID @INT_UNSIGNED@,
...@@ -284,4 +290,4 @@ CREATE TABLE @PREFIX@users_data ( ...@@ -284,4 +290,4 @@ CREATE TABLE @PREFIX@users_data (
Value VARCHAR(255), Value VARCHAR(255),
UNIQUE (UserID,Name) UNIQUE (UserID,Name)
) @CREATE_TABLE_SUFFIX@; ) @CREATE_TABLE_SUFFIX@;
...@@ -2,3 +2,4 @@ ALTER TABLE @PREFIX@users ADD COLUMN PeriodKey VARCHAR(255); ...@@ -2,3 +2,4 @@ ALTER TABLE @PREFIX@users ADD COLUMN PeriodKey VARCHAR(255);
ALTER TABLE @PREFIX@users ADD COLUMN TotalTraffic @INT_UNSIGNED@; ALTER TABLE @PREFIX@users ADD COLUMN TotalTraffic @INT_UNSIGNED@;
ALTER TABLE @PREFIX@users ADD COLUMN TotalUptime @INT_UNSIGNED@; ALTER TABLE @PREFIX@users ADD COLUMN TotalUptime @INT_UNSIGNED@;
ALTER TABLE @PREFIX@users ADD COLUMN NASIdentifier VARCHAR(255); ALTER TABLE @PREFIX@users ADD COLUMN NASIdentifier VARCHAR(255);
ALTER TABLE @PREFIX@users ADD COLUMN LastAcctUpdate DATETIME;
...@@ -41,6 +41,8 @@ our (@EXPORT); ...@@ -41,6 +41,8 @@ our (@EXPORT);
); );
use AWITPT::Util;
# Check Math::Expression is installed # Check Math::Expression is installed
if (!eval {require Math::Expression; 1;}) { if (!eval {require Math::Expression; 1;}) {
print STDERR "You're missing Math::Expression, try 'apt-get install libmath-expression-perl'\n"; print STDERR "You're missing Math::Expression, try 'apt-get install libmath-expression-perl'\n";
...@@ -51,6 +53,7 @@ use smradius::logging; ...@@ -51,6 +53,7 @@ use smradius::logging;
use smradius::util; use smradius::util;
# Attributes we do not handle # Attributes we do not handle
my @attributeCheckIgnoreList = ( my @attributeCheckIgnoreList = (
'User-Password' 'User-Password'
...@@ -65,7 +68,23 @@ my @attributeReplyIgnoreList = ( ...@@ -65,7 +68,23 @@ my @attributeReplyIgnoreList = (
'SMRadius-Username-Transform', 'SMRadius-Username-Transform',
'SMRadius-Evaluate', 'SMRadius-Evaluate',
'SMRadius-Peer-Address', 'SMRadius-Peer-Address',
'SMRadius-Disable-WebUITopup' 'SMRadius-Disable-WebUITopup',
'SMRadius-AutoTopup-Traffic-Enabled',
'SMRadius-AutoTopup-Traffic-Amount',
'SMRadius-AutoTopup-Traffic-Limit',
'SMRadius-AutoTopup-Traffic-Notify',
'SMRadius-AutoTopup-Traffic-NotifyTemplate',
'SMRadius-AutoTopup-Traffic-Threshold',
'SMRadius-AutoTopup-Uptime-Enabled',
'SMRadius-AutoTopup-Uptime-Amount',
'SMRadius-AutoTopup-Uptime-Limit',
'SMRadius-AutoTopup-Uptime-Notify',
'SMRadius-AutoTopup-Uptime-NotifyTemplate',
'SMRadius-AutoTopup-Uptime-Threshold',
'SMRadius-Config-Filter-Reply-Attribute',
'SMRadius-Config-Filter-Reply-VAttribute',
'SMRadius-FUP-Period',
'SMRadius-FUP-Traffic-Threshold',
); );
my @attributeVReplyIgnoreList = ( my @attributeVReplyIgnoreList = (
); );
...@@ -85,8 +104,8 @@ sub addAttribute ...@@ -85,8 +104,8 @@ sub addAttribute
# Check we have the name, operator AND value # Check we have the name, operator AND value
if (!defined($attribute->{'Name'}) || !defined($attribute->{'Operator'}) || !defined($attribute->{'Value'})) { if (!defined($attribute->{'Name'}) || !defined($attribute->{'Operator'}) || !defined($attribute->{'Value'})) {
$server->log(LOG_DEBUG,"[ATTRIBUTES] Problem adding attribute with name = ".niceUndef($attribute->{'Name'}). $server->log(LOG_DEBUG,"[ATTRIBUTES] Problem adding attribute with name = ".prettyUndef($attribute->{'Name'}).
", operator = ".niceUndef($attribute->{'Operator'}).", value = ".niceUndef($attribute->{'Value'})); ", operator = ".prettyUndef($attribute->{'Operator'}).", value = ".prettyUndef($attribute->{'Value'}));
return; return;
} }
...@@ -170,7 +189,7 @@ sub checkAuthAttribute ...@@ -170,7 +189,7 @@ sub checkAuthAttribute
# Get packet attribute value # Get packet attribute value
my $attrVal = $packetAttributes->{$attribute->{'Name'}}; my $attrVal = $packetAttributes->{$attribute->{'Name'}};
$server->log(LOG_DEBUG,"[ATTRIBUTES] Processing CHECK attribute value ".niceUndef($attrVal)." against: '". $server->log(LOG_DEBUG,"[ATTRIBUTES] Processing CHECK attribute value ".prettyUndef($attrVal)." against: '".
$attribute->{'Name'}."' ".$attribute->{'Operator'}." '".join("','",@attrValues)."'"); $attribute->{'Name'}."' ".$attribute->{'Operator'}." '".join("','",@attrValues)."'");
# Loop with all the test attribute values # Loop with all the test attribute values
...@@ -327,7 +346,7 @@ sub checkAuthAttribute ...@@ -327,7 +346,7 @@ sub checkAuthAttribute
# Always matches as a check item, and adds the current # Always matches as a check item, and adds the current
# attribute with value to the list of configuration items. # attribute with value to the list of configuration items.
# #
# As a reply item, it has an itendtical meaning, but the # As a reply item, it has an idendtical meaning, but the
# attribute is added to the reply items. # attribute is added to the reply items.
} elsif ($operator eq '+=') { } elsif ($operator eq '+=') {
...@@ -410,7 +429,7 @@ sub checkAcctAttribute ...@@ -410,7 +429,7 @@ sub checkAcctAttribute
# Get packet attribute value # Get packet attribute value
my $attrVal = $packetAttributes->{$attribute->{'Name'}}; my $attrVal = $packetAttributes->{$attribute->{'Name'}};
$server->log(LOG_DEBUG,"[ATTRIBUTES] Processing CHECK attribute value ".niceUndef($attrVal)." against: '". $server->log(LOG_DEBUG,"[ATTRIBUTES] Processing CHECK attribute value ".prettyUndef($attrVal)." against: '".
$attribute->{'Name'}."' ".$attribute->{'Operator'}." '".join("','",@attrValues)."'"); $attribute->{'Name'}."' ".$attribute->{'Operator'}." '".join("','",@attrValues)."'");
# Loop with all the test attribute values # Loop with all the test attribute values
...@@ -424,7 +443,7 @@ sub checkAcctAttribute ...@@ -424,7 +443,7 @@ sub checkAcctAttribute
# Always matches as a check item, and adds the current # Always matches as a check item, and adds the current
# attribute with value to the list of configuration items. # attribute with value to the list of configuration items.
# #
# As a reply item, it has an itendtical meaning, but the # As a reply item, it has an idendtical meaning, but the
# attribute is added to the reply items. # attribute is added to the reply items.
if ($operator eq '+=') { if ($operator eq '+=') {
...@@ -531,7 +550,7 @@ sub setReplyAttribute ...@@ -531,7 +550,7 @@ sub setReplyAttribute
# Always matches as a check item, and replaces in the configuration items any attribute of the same name. # Always matches as a check item, and replaces in the configuration items any attribute of the same name.
# If no attribute of that name appears in the request, then this attribute is added. # If no attribute of that name appears in the request, then this attribute is added.
# #
# As a reply item, it has an itendtical meaning, but for the reply items, instead of the request items. # As a reply item, it has an idendtical meaning, but for the reply items, instead of the request items.
} elsif ($attribute->{'Operator'} eq ':=') { } elsif ($attribute->{'Operator'} eq ':=') {
# Overwrite # Overwrite
...@@ -546,7 +565,7 @@ sub setReplyAttribute ...@@ -546,7 +565,7 @@ sub setReplyAttribute
# Always matches as a check item, and adds the current # Always matches as a check item, and adds the current
# attribute with value to the list of configuration items. # attribute with value to the list of configuration items.
# #
# As a reply item, it has an itendtical meaning, but the # As a reply item, it has an idendtical meaning, but the
# attribute is added to the reply items. # attribute is added to the reply items.
} elsif ($attribute->{'Operator'} eq '+=') { } elsif ($attribute->{'Operator'} eq '+=') {
...@@ -595,7 +614,7 @@ sub setReplyVAttribute ...@@ -595,7 +614,7 @@ sub setReplyVAttribute
@attrValues = ( $attribute->{'Value'} ); @attrValues = ( $attribute->{'Value'} );
} }
$server->log(LOG_DEBUG,"[VATTRIBUTES] Processing REPLY attribute: '". $server->log(LOG_DEBUG,"[VATTRIBUTES] Processing REPLY vattribute: '".
$attribute->{'Name'}."' ".$attribute->{'Operator'}." '".join("','",@attrValues)."'"); $attribute->{'Name'}."' ".$attribute->{'Operator'}." '".join("','",@attrValues)."'");
...@@ -625,7 +644,7 @@ sub setReplyVAttribute ...@@ -625,7 +644,7 @@ sub setReplyVAttribute
# Always matches as a check item, and replaces in the configuration items any attribute of the same name. # Always matches as a check item, and replaces in the configuration items any attribute of the same name.
# If no attribute of that name appears in the request, then this attribute is added. # If no attribute of that name appears in the request, then this attribute is added.
# #
# As a reply item, it has an itendtical meaning, but for the reply items, instead of the request items. # As a reply item, it has an idendtical meaning, but for the reply items, instead of the request items.
} elsif ($attribute->{'Operator'} eq ':=') { } elsif ($attribute->{'Operator'} eq ':=') {
# Overwrite # Overwrite
...@@ -640,7 +659,7 @@ sub setReplyVAttribute ...@@ -640,7 +659,7 @@ sub setReplyVAttribute
# Always matches as a check item, and adds the current # Always matches as a check item, and adds the current
# attribute with value to the list of configuration items. # attribute with value to the list of configuration items.
# #
# As a reply item, it has an itendtical meaning, but the # As a reply item, it has an idendtical meaning, but the
# attribute is added to the reply items. # attribute is added to the reply items.
} elsif ($attribute->{'Operator'} eq '+=') { } elsif ($attribute->{'Operator'} eq '+=') {
...@@ -692,7 +711,7 @@ sub processConfigAttribute ...@@ -692,7 +711,7 @@ sub processConfigAttribute
# Always matches as a check item, and adds the current # Always matches as a check item, and adds the current
# attribute with value to the list of configuration items. # attribute with value to the list of configuration items.
# #
# As a reply item, it has an itendtical meaning, but the # As a reply item, it has an idendtical meaning, but the
# attribute is added to the reply items. # attribute is added to the reply items.
if ($attribute->{'Operator'} eq '+=') { if ($attribute->{'Operator'} eq '+=') {
...@@ -705,7 +724,7 @@ sub processConfigAttribute ...@@ -705,7 +724,7 @@ sub processConfigAttribute
# Always matches as a check item, and replaces in the configuration items any attribute of the same name. # Always matches as a check item, and replaces in the configuration items any attribute of the same name.
# If no attribute of that name appears in the request, then this attribute is added. # If no attribute of that name appears in the request, then this attribute is added.
# #
# As a reply item, it has an itendtical meaning, but for the reply items, instead of the request items. # As a reply item, it has an idendtical meaning, but for the reply items, instead of the request items.
} elsif ($attribute->{'Operator'} eq ':=') { } elsif ($attribute->{'Operator'} eq ':=') {
@{$configAttributes->{$attribute->{'Name'}}} = @attrValues; @{$configAttributes->{$attribute->{'Name'}}} = @attrValues;
...@@ -775,7 +794,8 @@ sub processConditional ...@@ -775,7 +794,8 @@ sub processConditional
# Split off expression # Split off expression
my ($condition,$onTrue,$onFalse) = ($attrVal =~ /^([^\?]*)(?:\?\s*((?:\S+)?[^:]*)(?:\s*\:\s*(.*))?)?$/); # NK: This probably needs a bit of work
my ($condition,$onTrue,$onFalse) = ($attrVal =~ /^([^\?]*)(?:\?\s*((?:\S+)?[^:]*)(?:\:\s*(.*))?)?$/);
# If there is no condition we cannot really continue? # If there is no condition we cannot really continue?
if (!defined($condition)) { if (!defined($condition)) {
...@@ -829,6 +849,10 @@ sub processConditional ...@@ -829,6 +849,10 @@ sub processConditional
# We only get here if $res is set to 1 above, if its only a conditional with no onTrue & onFalse # We only get here if $res is set to 1 above, if its only a conditional with no onTrue & onFalse
# Then attribStr will be unef # Then attribStr will be unef
if ($res && defined($attribStr)) { if ($res && defined($attribStr)) {
# Sanitize the output
$attribStr =~ s/^\s*//;
$attribStr =~ s/\s*$//;
foreach my $rawAttr (split(/;/,$attribStr)) { foreach my $rawAttr (split(/;/,$attribStr)) {
# Split off attribute string: name = value # Split off attribute string: name = value
my ($attrName,$attrVal) = ($rawAttr =~ /^\s*([^=]+)=\s*(.*)/); my ($attrName,$attrVal) = ($rawAttr =~ /^\s*([^=]+)=\s*(.*)/);
......
# Radius client # Radius client
# Copyright (C) 2007-2016, AllWorldIT # Copyright (C) 2007-2019, AllWorldIT
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
...@@ -23,12 +23,14 @@ package smradius::client; ...@@ -23,12 +23,14 @@ package smradius::client;
use strict; use strict;
use warnings; use warnings;
use Getopt::Long; use base qw(AWITPT::Object);
use Getopt::Long qw( GetOptionsFromArray );
use IO::Select; use IO::Select;
use IO::Socket; use IO::Socket;
use smradius::version; use smradius::version;
use Radius::Packet; use smradius::Radius::Packet;
# Check Config::IniFiles is instaslled # Check Config::IniFiles is instaslled
if (!eval {require Config::IniFiles; 1;}) { if (!eval {require Config::IniFiles; 1;}) {
...@@ -38,97 +40,99 @@ if (!eval {require Config::IniFiles; 1;}) { ...@@ -38,97 +40,99 @@ if (!eval {require Config::IniFiles; 1;}) {
# Run the client
sub run sub run
{ {
my ($self,@methodArgs) = @_;
# Instantiate if we're not already instantiated
$self = $self->new() if (!ref($self));
print(STDERR "SMRadClient v".VERSION." - Copyright (c) 2007-2016, AllWorldIT\n"); # The hash we're going to return
my $ret = { };
print(STDERR "SMRadClient v".VERSION." - Copyright (c) 2007-2019, AllWorldIT\n");
print(STDERR "\n");
# Set defaults # Set defaults
my $cfg; my $cfg;
$cfg->{'config_file'} = "/etc/smradiusd.conf"; $cfg->{'config_file'} = "/etc/smradiusd.conf";
# Grab runtime arguments
my @runArgs = @methodArgs ? @methodArgs : @ARGV;
# Parse command line params # Parse command line params
my $cmdline; my $cmdline;
%{$cmdline} = (); %{$cmdline} = ();
GetOptions( if (!GetOptionsFromArray(
\@runArgs,
\%{$cmdline}, \%{$cmdline},
"config:s", "config:s",
"raddb:s", "raddb:s",
"listen:s",
"help", "help",
) or die "Error parsing commandline arguments"; )) {
print(STDERR "ERROR: Error parsing commandline arguments");
return 1;
}
# Check for some args # Check for some args
if ($cmdline->{'help'}) { if ($cmdline->{'help'}) {
displayHelp(); displayHelp();
exit 0; return 0;
} }
# Make sure we only have 2 additional args # Make sure we only have 2 additional args
if (@ARGV > 3 || @ARGV < 3) { if (@runArgs < 3) {
print(STDERR "ERROR: Invalid number of arguments\n\n"); print(STDERR "ERROR: Invalid number of arguments\n");
displayHelp(); displayHelp();
exit 1; return 1;
} }
if (!defined($cmdline->{'raddb'}) || $cmdline->{'raddb'} eq "") { if (!defined($cmdline->{'raddb'}) || $cmdline->{'raddb'} eq "") {
print(STDERR "ERROR: No raddb directory specified!\n\n"); print(STDERR "ERROR: No raddb directory specified!\n");
displayHelp(); displayHelp();
exit 1; return 1;
} }
# Get variables we need # Get variables we need
my ($server,$type,$secret) = @ARGV; my $server = shift(@runArgs);
my $type = shift(@runArgs);
$self->{'secret'} = shift(@runArgs);
# Validate type # Validate type
if (!defined($type) || ( $type ne "acct" && $type ne "auth" && if (!defined($type) || ( $type ne "acct" && $type ne "auth" && $type ne "disconnect")) {
$type ne "disconnect" print(STDERR "ERROR: Invalid packet type specified!\n");
)){
print(STDERR "ERROR: Invalid packet type specified!\n\n");
displayHelp(); displayHelp();
exit 1; return 1;
} }
#if (defined($cmdline->{'config'}) && $cmdline->{'config'} ne "") {
# $cfg->{'config_file'} = $cmdline->{'config'};
#}
# Check config file exists
#if (! -f $cfg->{'config_file'}) {
# die("No configuration file '".$cfg->{'config_file'}."' found!\n");
#}
# Use config file, ignore case
#tie my %inifile, 'Config::IniFiles', (
# -file => $cfg->{'config_file'},
# -nocase => 1
#) or die "Failed to open config file '".$cfg->{'config_file'}."': $!";
# Copy config
#my %config = %inifile;
print(STDERR "\n"); print(STDERR "\n");
# Time to start loading the dictionary # Time to start loading the dictionary
print(STDERR "Loading dictionaries..."); print(STDERR "Loading dictionaries...");
my $raddb = Radius::Dictionary->new(); my $raddb = smradius::Radius::Dictionary->new();
# Look for files in the dir # Look for files in the dir
opendir(my $DIR, $cmdline->{'raddb'}) my $DIR;
or die "Cannot open '".$cmdline->{'raddb'}."': $!"; if (!opendir($DIR, $cmdline->{'raddb'})) {
print(STDERR "ERROR: Cannot open '".$cmdline->{'raddb'}."': $!");
return 1;
}
my @raddb_files = readdir($DIR); my @raddb_files = readdir($DIR);
# And load the dictionary # And load the dictionary
foreach my $df (@raddb_files) { foreach my $df (@raddb_files) {
my $df_fn = $cmdline->{'raddb'}."/$df"; my $df_fn = $cmdline->{'raddb'}."/$df";
# Load dictionary # Load dictionary
if (!$raddb->readfile($df_fn)) { if (!$raddb->readfile($df_fn)) {
print(STDERR "Failed to load dictionary '$df_fn': $!"); print(STDERR "Failed to load dictionary '$df_fn': $!");
} }
print(STDERR "."); print(STDERR ".");
} }
print(STDERR "\n"); print(STDERR "\n");
...@@ -136,52 +140,45 @@ sub run ...@@ -136,52 +140,45 @@ sub run
my $port; my $port;
my $pkt_code; my $pkt_code;
if ($type eq "acct") { if ($type eq "acct") {
$port = 1813; $port = 1813;
$pkt_code = "Accounting-Request"; $pkt_code = "Accounting-Request";
} elsif ($type eq "auth") { } elsif ($type eq "auth") {
$port = 1812; $port = 1812;
$pkt_code = "Access-Request"; $pkt_code = "Access-Request";
} elsif ($type eq "disconnect") { } elsif ($type eq "disconnect") {
$port = 1813; $port = 1813;
$pkt_code = "Disconnect-Request"; $pkt_code = "Disconnect-Request";
} }
print(STDERR "\nRequest:\n"); print(STDERR "\nRequest:\n");
print(STDERR " > Secret => '$secret'\n"); printf(STDERR " > Secret => '%s'\n",$self->{'secret'});
# Build packet # Build packet
my $pkt = Radius::Packet->new($raddb); $self->{'packet'} = smradius::Radius::Packet->new($raddb);
$pkt->set_code($pkt_code); $self->{'packet'}->set_code($pkt_code);
# Generate identifier # Generate identifier
my $ident = int(rand(32768)); my $ident = int(rand(32768));
$pkt->set_identifier($ident); $self->{'packet'}->set_identifier($ident);
print(STDERR " > Identifier: $ident\n"); print(STDERR " > Identifier: $ident\n");
# Generate authenticator number # Generate authenticator number
my $authen = int(rand(32768)); my $authen = int(rand(32768));
$pkt->set_authenticator($authen); $self->{'packet'}->set_authenticator($authen);
print(STDERR " > Authenticator: $ident\n"); print(STDERR " > Authenticator: $ident\n");
# Pull in attributes # Pull in attributes from STDIN if we're not being called as a function
while (my $line = <STDIN>) { if (!@runArgs) {
# Remove EOL while (my $line = <STDIN>) {
chomp($line); $self->addAttributesFromString($line);
# Split on , and newline
my @rawAttributes = split(/,\n/,$line);
foreach my $attr (@rawAttributes) {
# Pull off attribute name & value
my ($name,$value) = ($attr =~ /\s*(\S+)\s*=\s?(.+)/);
# Add to packet
print(STDERR " > Adding '$name' => '$value'\n");
if ($name eq "User-Password") {
$pkt->set_password($value,$secret);
} else {
$pkt->set_attr($name,$value);
} }
} }
# Pull in attributes from commandline
while (my $line = shift(@runArgs)) {
$self->addAttributesFromString($line);
} }
# Create UDP packet # Create UDP packet
my $udp_packet = $pkt->pack(); my $udp_packet = $self->{'packet'}->pack();
# Create socket to send packet out on # Create socket to send packet out on
my $sockTimeout = "10"; # 10 second timeout my $sockTimeout = "10"; # 10 second timeout
...@@ -190,48 +187,183 @@ sub run ...@@ -190,48 +187,183 @@ sub run
PeerPort => $port, PeerPort => $port,
Type => SOCK_DGRAM, Type => SOCK_DGRAM,
Proto => 'udp', Proto => 'udp',
TimeOut => $sockTimeout, Timeout => $sockTimeout,
); );
if (!$sock) { if (!$sock) {
print(STDERR "ERROR: Failed to create socket\n"); print(STDERR "ERROR: Failed to create socket\n");
return 1;
}
my $sock2;
# Check if we must listen on another IP/port
if (defined($cmdline->{'listen'}) && $cmdline->{'listen'} ne "") {
print(STDERR "Creating second socket\n");
# Check the details we were provided
my ($localAddr,$localPort) = split(/:/,$cmdline->{'listen'});
if (!defined($localPort)) {
print(STDERR "ERROR: The format for --listen is IP:Port\n");
return 1;
}
$sock2 = IO::Socket::INET->new(
LocalAddr => $localAddr,
LocalPort => $localPort,
Type => SOCK_DGRAM,
Proto => 'udp',
Timeout => $sockTimeout,
);
if (!$sock2) {
print(STDERR "ERROR: Failed to create second socket\n");
return 1;
}
} }
# Check if we sent the packet... # Check if we sent the packet...
if (!$sock->send($udp_packet)) { if (!$sock->send($udp_packet)) {
print(STDERR "ERROR: Failed to send data on socket\n"); print(STDERR "ERROR: Failed to send data on socket\n");
exit 1; return 1;
} }
# And time for the response # And time for the response
print(STDERR "\nResponse:\n"); print(STDERR "\nResponse:\n");
# Once sent, we need to get a response back # Once sent, we need to get a response back
my $rsock = IO::Select->new($sock); my $rsock = IO::Select->new($sock);
if (!$rsock) { if (!$rsock) {
print(STDERR "ERROR: Failed to select response data on socket\n"); print(STDERR "ERROR: Failed to select response data on socket\n");
exit 1; return 1;
} }
# Check if we can read a response after the select() # Check if we can read a response after the select()
if (!$rsock->can_read($sockTimeout)) { if (!$rsock->can_read($sockTimeout)) {
print(STDERR "ERROR: Failed to receive response data on socket\n"); print(STDERR "ERROR: Failed to receive response data on socket\n");
exit 1; return 1;
} }
# Read packet # Read packet
$sock->recv($udp_packet, 65536); $sock->recv($udp_packet, 65536);
if (!$udp_packet) { if (!$udp_packet) {
print(STDERR "ERROR: Receive response data failed: $!\n"); print(STDERR "ERROR: Receive response data failed on socket: $!\n");
exit 1; return 1;
} }
# Parse packet # Parse packet
$pkt = Radius::Packet->new($raddb,$udp_packet); my $pkt = smradius::Radius::Packet->new($raddb,$udp_packet);
print(STDERR " > Authenticated: ". (defined(auth_req_verify($udp_packet,$secret,$authen)) ? "yes" : "no") ."\n"); print(STDERR " > Authenticated: ". (defined(auth_req_verify($udp_packet,$self->{'secret'},$authen)) ? "yes" : "no") ."\n");
print(STDERR $pkt->str_dump()); print(STDERR $pkt->str_dump());
# Setup response
$ret->{'request'} = $self->hashedPacket($self->{'packet'});
$ret->{'response'} = $self->hashedPacket($pkt);
my $udp_packet2;
if (defined($sock2)) {
my $rsock2 = IO::Select->new($sock2);
if (!$rsock2) {
print(STDERR "ERROR: Failed to select response data on socket2\n");
return 1;
}
# Check if we can read a response after the select()
if (!$rsock2->can_read($sockTimeout)) {
print(STDERR "ERROR: Failed to receive response data on socket2\n");
return 1;
}
# Read packet
my $udp_packet2;
$sock2->recv($udp_packet2, 65536);
if (!$udp_packet2) {
print(STDERR "ERROR: Receive response data failed on socket2: $!\n");
return 1;
}
my $pkt2 = smradius::Radius::Packet->new($raddb,$udp_packet2);
print(STDERR $pkt2->str_dump());
# Save the packet we got
$ret->{'listen'}->{'response'} = $self->hashedPacket($pkt2);
}
# If we were called as a function, return hashed version of the response packet
if (@methodArgs) {
return $ret;
}
return 0;
}
# Return a hashed version of the packet
sub hashedPacket
{
my ($self,$pkt) = @_;
my $res = {};
$res->{'code'} = $pkt->code();
$res->{'identifier'} = $pkt->identifier();
foreach my $attrName (sort $pkt->attributes()) {
my $attrVal = $pkt->rawattr($attrName);
$res->{'attributes'}->{$attrName} = $attrVal;
}
foreach my $attrVendor ($pkt->vendors()) {
foreach my $attrName ($pkt->vsattributes($attrVendor)) {
$res->{'vattributes'}->{$attrVendor}->{$attrName} = $pkt->vsattr($attrVendor,$attrName);
}
}
return $res;
}
# Allow adding attribute from a string
sub addAttributesFromString
{
my ($self,$line) = @_;
# Remove EOL
chomp($line);
# Split on , and newline
my @rawAttributes = split(/[,\n]+/,$line);
foreach my $attr (@rawAttributes) {
# Pull off attribute name & value
my ($name,$value) = ($attr =~ /\s*(\S+)\s*=\s?(.+)/);
$self->addAttribute($name,$value);
}
return;
}
# Add attribute to packet
sub addAttribute
{
my ($self,$name,$value) = @_;
# Add to packet
print(STDERR " > Adding '$name' => '$value'\n");
if ($name eq "User-Password") {
$self->{'packet'}->set_password($value,$self->{'secret'});
} else {
$self->{'packet'}->set_attr($name,$value);
}
return; return;
} }
...@@ -241,8 +373,8 @@ sub run ...@@ -241,8 +373,8 @@ sub run
sub displayHelp { sub displayHelp {
print(STDERR<<EOF); print(STDERR<<EOF);
Usage: $0 [args] <server> <acct|auth|disconnect> <secret> Usage: $0 [args] <server> <acct|auth|disconnect> <secret> [ATTR=VALUE,...]
--raddb Directory where the radius dictionary files are --raddb=<DIR> Directory where the radius dictionary files are
EOF EOF
......
...@@ -25,11 +25,13 @@ use warnings; ...@@ -25,11 +25,13 @@ use warnings;
# Exporter stuff # Exporter stuff
use base qw(Exporter); use base qw(Exporter);
our (@EXPORT); our @EXPORT = qw(
@EXPORT = qw( );
our @EXPORT_OK = qw(
); );
use AWITPT::Util;
use smradius::logging; use smradius::logging;
...@@ -70,10 +72,8 @@ sub Init ...@@ -70,10 +72,8 @@ sub Init
# Should we use the packet timestamp? # Should we use the packet timestamp?
if (defined($config->{'radius'}{'use_packet_timestamp'})) { if (defined($config->{'radius'}{'use_packet_timestamp'})) {
if ($config->{'radius'}{'use_packet_timestamp'} =~ /^\s*(yes|true|1)\s*$/i) { if (defined(my $val = isBoolean($config->{'radius'}{'use_packet_timestamp'}))) {
$server->{'smradius'}{'use_packet_timestamp'} = 1; $server->{'smradius'}{'use_packet_timestamp'} = $val;
} elsif ($config->{'radius'}{'use_packet_timestamp'} =~ /^\s*(no|false|0)\s*$/i) {
$server->{'smradius'}{'use_packet_timestamp'} = 0;
} else { } else {
$server->log(LOG_NOTICE,"smradius/config.pm: Value for 'use_packet_timestamp' is invalid"); $server->log(LOG_NOTICE,"smradius/config.pm: Value for 'use_packet_timestamp' is invalid");
} }
...@@ -83,10 +83,8 @@ sub Init ...@@ -83,10 +83,8 @@ sub Init
# Should we use abuse prevention? # Should we use abuse prevention?
if (defined($config->{'radius'}{'use_abuse_prevention'})) { if (defined($config->{'radius'}{'use_abuse_prevention'})) {
if ($config->{'radius'}{'use_abuse_prevention'} =~ /^\s*(yes|true|1)\s*$/i) { if (defined(my $val = isBoolean($config->{'radius'}{'use_abuse_prevention'}))) {
$server->{'smradius'}{'use_abuse_prevention'} = 1; $server->{'smradius'}{'use_abuse_prevention'} = $val;
} elsif ($config->{'radius'}{'use_abuse_prevention'} =~ /^\s*(no|false|0)\s*$/i) {
$server->{'smradius'}{'use_abuse_prevention'} = 0;
} else { } else {
$server->log(LOG_NOTICE,"smradius/config.pm: Value for 'use_abuse_prevention' is invalid"); $server->log(LOG_NOTICE,"smradius/config.pm: Value for 'use_abuse_prevention' is invalid");
} }
......
...@@ -20,14 +20,13 @@ ...@@ -20,14 +20,13 @@
## @class smradius::constants ## @class smradius::constants
# SMRadius constants package # SMRadius constants package
package smradius::constants; package smradius::constants;
use base qw(Exporter);
use strict; use strict;
use warnings; use warnings;
# Exporter stuff
use base qw(Exporter);
our (@EXPORT,@EXPORT_OK); our (@EXPORT,@EXPORT_OK);
@EXPORT = qw( @EXPORT = qw(
RES_OK RES_OK
...@@ -37,7 +36,7 @@ our (@EXPORT,@EXPORT_OK); ...@@ -37,7 +36,7 @@ our (@EXPORT,@EXPORT_OK);
MOD_RES_NACK MOD_RES_NACK
MOD_RES_SKIP MOD_RES_SKIP
UINT_MAX GIGAWORD_VALUE
); );
@EXPORT_OK = (); @EXPORT_OK = ();
...@@ -50,7 +49,7 @@ use constant { ...@@ -50,7 +49,7 @@ use constant {
MOD_RES_ACK => 1, MOD_RES_ACK => 1,
MOD_RES_NACK => 2, MOD_RES_NACK => 2,
UINT_MAX => 2**32 GIGAWORD_VALUE => 2**32,
}; };
......
This diff is collapsed.
...@@ -25,6 +25,13 @@ use warnings; ...@@ -25,6 +25,13 @@ use warnings;
use base qw{AWITPT::Object}; use base qw{AWITPT::Object};
use DateTime;
use DateTime::TimeZone;
use Try::Tiny;
use smradius::Radius::Packet;
# Parse radius packet # Parse radius packet
sub parsePacket sub parsePacket
...@@ -33,7 +40,7 @@ sub parsePacket ...@@ -33,7 +40,7 @@ sub parsePacket
# Parse the radius packet # Parse the radius packet
$self->{'packet'} = Radius::Packet->new($dictionary,$rawPacket); $self->{'packet'} = smradius::Radius::Packet->new($dictionary,$rawPacket);
# Loop with packet attribute names and add to our log line # Loop with packet attribute names and add to our log line
$self->addLogLine("PACKET => "); $self->addLogLine("PACKET => ");
...@@ -80,7 +87,7 @@ sub setTimestamp ...@@ -80,7 +87,7 @@ sub setTimestamp
# Grab real event timestamp in local time uzing the time zone # Grab real event timestamp in local time uzing the time zone
my $eventTimestamp = DateTime->from_epoch( my $eventTimestamp = DateTime->from_epoch(
epoch => $self->{'user'}->{'_Internal'}->{'Timestamp-Unix'}, epoch => $self->{'user'}->{'_Internal'}->{'Timestamp-Unix'},
time_zone => $self->{'timeZone'}, time_zone => $self->{'timezone'},
); );
# Set the timestamp (not in unix) # Set the timestamp (not in unix)
$self->{'user'}->{'_Internal'}->{'Timestamp'} = $eventTimestamp->strftime('%Y-%m-%d %H:%M:%S'); $self->{'user'}->{'_Internal'}->{'Timestamp'} = $eventTimestamp->strftime('%Y-%m-%d %H:%M:%S');
...@@ -91,12 +98,20 @@ sub setTimestamp ...@@ -91,12 +98,20 @@ sub setTimestamp
# Set internal time zone # Set internal time zone
sub setTimeZone sub setTimezone
{ {
my ($self,$timeZone) = @_; my ($self,$timezone) = @_;
my $timezone_obj;
try {
$timezone_obj = DateTime::TimeZone->new('name' => $timezone);
};
# Retrun if we don't have a value, this means we failed
return if (!defined($timezone_obj));
$self->{'timeZone'} = $timeZone; $self->{'timezone'} = $timezone_obj;
return $self; return $self;
} }
...@@ -144,7 +159,7 @@ sub _init ...@@ -144,7 +159,7 @@ sub _init
$self->{'logLine'} = [ ]; $self->{'logLine'} = [ ];
$self->{'logLineParams'} = [ ]; $self->{'logLineParams'} = [ ];
$self->{'timeZone'} = "UTC"; $self->{'timezone'} = "UTC";
# Initialize user # Initialize user
$self->{'user'} = { $self->{'user'} = {
......