diff -urN smeserver-wireguard-1.0.old/createlink smeserver-wireguard-1.0/createlink --- smeserver-wireguard-1.0.old/createlink 2021-12-21 22:33:27.000000000 +0400 +++ smeserver-wireguard-1.0/createlink 2021-12-21 22:49:18.704000000 +0400 @@ -8,6 +8,12 @@ /etc/wireguard/server_public.key /etc/rc.d/init.d/masq )); +# for smeserver-manager +safe_symlink('restart', "root/etc/e-smith/events/$event/services2adjust/smanager"); +event_link('navigation2-conf', "$event", '80'); +event_link('routes2-conf', "$event", '80'); +event_link('locales2-conf', "$event", '80'); + # server_public.key will expand server_private.key to keep sync #TODO diff -urN smeserver-wireguard-1.0.old/createlinks-exe smeserver-wireguard-1.0/createlinks-exe --- smeserver-wireguard-1.0.old/createlinks-exe 1970-01-01 04:00:00.000000000 +0400 +++ smeserver-wireguard-1.0/createlinks-exe 2021-12-02 18:34:30.000000000 +0400 @@ -0,0 +1,23 @@ +#!/usr/bin/perl -w + +use esmith::Build::CreateLinks qw(:all); + +panel_link("webhosting", "manager"); + +for my $event (qw( + webhosting-modify smeserver-webhosting-update + )) +{ + #we can avoid those 2 as we are tricking ourself as ibay-modify and it will do those and php + #templates2events("/etc/httpd/conf/httpd.conf", $event); + #safe_symlink("sigusr1", "root/etc/e-smith/events/$event/services2adjust/httpd-e-smith"); + event_link("webhosting-php-expand", $event, "05"); + event_link("webhosting-php-adjust", $event, "90"); +} +$event="smeserver-webhosting-update"; +event_link("navigation-conf", $event, "70"); +# for smeserver-manager +safe_symlink('restart', "root/etc/e-smith/events/$event/services2adjust/smanager"); +event_link('navigation2-conf', "$event", '80'); +event_link('routes2-conf', "$event", '80'); +event_link('locales2-conf', "$event", '80'); diff -urN smeserver-wireguard-1.0.old/root/usr/share/perl5/vendor_perl/esmith/FormMagick/Panel/wireguard.pm smeserver-wireguard-1.0/root/usr/share/perl5/vendor_perl/esmith/FormMagick/Panel/wireguard.pm --- smeserver-wireguard-1.0.old/root/usr/share/perl5/vendor_perl/esmith/FormMagick/Panel/wireguard.pm 2021-12-21 22:33:27.000000000 +0400 +++ smeserver-wireguard-1.0/root/usr/share/perl5/vendor_perl/esmith/FormMagick/Panel/wireguard.pm 2022-04-15 19:43:48.000000000 +0400 @@ -190,9 +190,11 @@ my $q = $fm->{cgi}; my $username = $q->param('account'); my $info = $q->param('info'); - ($info) = $info =~ /([A-Za-z0-9_-]+)/; + ($info) = $info =~ /([A-Za-z0-9_\-. ]+)/; +# trim both ends + $info =~ s/^ +| +$//g; ($username) = $username =~ /([A-Za-z0-9_-]+)/; - return $fm->error("ERROR_FIELD_CONTENT", 'FIRST_PAGE') unless (defined $username and defined $info); + return $fm->error("ERROR_FIELD_CONTENT", 'FIRST_PAGE') unless ($username and $info); #get username my $user = $accounts->get($username) or return "$username does not exist"; return $fm->error("ERROR_WRONG_ACCT_TYPE", 'FIRST_PAGE') unless $user->prop("type") eq "user" or $user->key eq "admin"; @@ -345,6 +347,11 @@ my $allowedips = $q->param('allowedips') || ''; #todo validate fields + ($info) = $info =~ /([A-Za-z0-9_\-. ]+)/; +# trim both ends + $info =~ s/^ +| +$//g; + + return $fm->error("ERROR_FIELD_CONTENT", 'FIRST_PAGE') unless $info; my %props = ('user' => $account ,'private' => $private diff -urN smeserver-wireguard-1.0.old/root/usr/share/smanager/lib/SrvMngr/Controller/Wireguard.pm smeserver-wireguard-1.0/root/usr/share/smanager/lib/SrvMngr/Controller/Wireguard.pm --- smeserver-wireguard-1.0.old/root/usr/share/smanager/lib/SrvMngr/Controller/Wireguard.pm 1970-01-01 04:00:00.000000000 +0400 +++ smeserver-wireguard-1.0/root/usr/share/smanager/lib/SrvMngr/Controller/Wireguard.pm 2022-04-15 19:44:29.000000000 +0400 @@ -0,0 +1,572 @@ +package SrvMngr::Controller::Wireguard; + +#---------------------------------------------------------------------- +# heading : Configuration +# description : Wireguard +# navigation : 6000 6750 +# +# name : wireguard, method : get, url : /wireguard, ctlact : wireguard#main +# name : wireguardd, method : post, url : /wireguard, ctlact : wireguard#do_display +# name : wireguardu, method : post, url : /wireguard2, ctlact : wireguard#do_action +# name : wireguardr, method : get, url : /wireguard2, ctlact : wireguard#do_display +# +# routes : end +#---------------------------------------------------------------------- +use strict; +use warnings; +use Mojo::Base 'Mojolicious::Controller'; + +use Locale::gettext; +use SrvMngr::I18N; +use SrvMngr qw( theme_list init_session is_normal_password ); + +use esmith::ConfigDB; +use Net::IP; + +our $adb = esmith::AccountsDB->open() || die "Couldn't open accounts DB\ndb"; +our $cdb = esmith::ConfigDB->open() || die "Couldn't open config DB\n"; +our $wdb = esmith::ConfigDB->open('wireguard') || esmith::ConfigDB->create('wireguard'); +our $ndb = esmith::NetworksDB->open_ro || die "Error opening networks DB\n"; + + +sub main { + + my $c = shift; + $c->app->log->info($c->log_req); + + my %wrg_datas = (); + my $title = $c->l('wrg_FORM_TITLE'); + + $wrg_datas{'trt'} = 'LST'; + + $cdb = esmith::ConfigDB->open() || die "Couldn't open config DB\n"; + my $wg = $cdb->get('wg-quick@wg0'); + + $wrg_datas{'wgpub'} = $wg->prop('public'); + $wrg_datas{'wgip'} = $wg->prop('ip'); + $wrg_datas{'wgmask'} = $wg->prop('mask'); + $wrg_datas{'wgport'} = $wg->prop('UDPPort'); + $wrg_datas{'sstatus'} = $wg->prop('status'); + + my @wgstatus = `/usr/bin/wg show wg0 dump`; + + my $type = 'wg0'; + my @wgconf = $wdb->get_all_by_prop(type=>$type); + + $c->stash( title => $title, wrg_datas => \%wrg_datas, + wgstatus => \@wgstatus, wgconf => \@wgconf ); + + $c->render(template => 'wireguard'); + +}; + + +sub do_display { + + my $c = shift; + $c->app->log->info($c->log_req); + + my $rt = $c->current_route; + my $trt = ($c->param('trt') || ''); + my $wgconf = $c->param('Wgconf') || ''; + + my %wrg_datas = (); + my $title = $c->l('wrg_FORM_TITLE'); + my $modul = ''; + + $wrg_datas{'trt'} = $trt; + + if ( $trt eq 'QRC' ) { + $wrg_datas{'wgconf'} = $wgconf; + } + + if ( $trt eq 'MOD' ) { + $wrg_datas{'wgconf'} = $wgconf; + my $rec = $wdb->get($wgconf); + if ( $rec ) { + $wrg_datas{'info'} = $rec->prop('info') || ''; + $wrg_datas{'allowedips'} = $rec->prop('allowedips') || ''; + $wrg_datas{'private'} = $rec->prop('private') || ''; + $wrg_datas{'public'} = $rec->prop('public') || ''; + $wrg_datas{'account'} = $rec->prop('user') || ''; + $wrg_datas{'status'} = $rec->prop('status') || ''; + $wrg_datas{'dns'} = $rec->prop('dns') || ''; + } + } + + if ( $trt eq 'REM' ) { + $wrg_datas{'wgconf'} = $wgconf; + my $rec = $wdb->get($wgconf); + $wrg_datas{'wgcomment'} = $rec->prop('info') || ''; + } + + if ( $trt eq 'NEW' ) { + # nothing for a new client + } + + if ( $trt eq 'UPD' ) { + my $wg = $cdb->get('wg-quick@wg0'); + $wrg_datas{'ip'} = $wg->prop('ip'); + $wrg_datas{'mask'} = $wg->prop('mask'); + $wrg_datas{'private'} = $wg->prop('private'); + $wrg_datas{'public'} = $wg->prop('public'); + $wrg_datas{'status'} = $wg->prop('status'); + } + + if ( $trt eq 'LST' ) { + my @wgss = $adb->wgss(); + $c->stash( wgss => \@wgss ); + } + + $c->stash( title => $title, modul => $modul, wrg_datas => \%wrg_datas ); + $c->render( template => 'wireguard' ); + +}; + + +sub do_action { + + my $c = shift; + $c->app->log->info($c->log_req); + + my $rt = $c->current_route; + my $trt = ($c->param('trt') || ''); + + my %wrg_datas = (); + my $title = $c->l('wrg_FORM_TITLE'); + + $wrg_datas{'trt'} = $trt; + + my $result = ''; + my $res = ''; + + if ( $trt eq 'QRC' ) { + # NEVER + } + + if ( $trt eq 'LST' ) { + # NEVER + } + + if ( $trt eq 'MOD' ) { + $wrg_datas{'wgconf'} = $c->param('Wgconf'); + # controls + $res = 'OK'; # no controls here... + $result .= $res unless $res eq 'OK'; + if ( ! $result ) { + $res = performModifyClient( $c ); + $result .= $res unless $res eq 'OK'; + if ( ! $result ) { + $result = $c->l('wrg_SUCCESSFULLY_MODIFIED_CONF'); + } + } + } + + if ( $trt eq 'REM' ) { + if ($c->param("cancel")) { + $c->stash( error => $c->l('wrg_CANCELLED') ); + $c->redirect_to('/wireguard'); + } + # controls + $res = 'OK'; # no controls here... + $result .= $res unless $res eq 'OK'; + if ( ! $result ) { + $res = performRemoveClient( $c ); + $result .= $res unless $res eq 'OK'; + if ( ! $result ) { + $result = $c->l('wrg_SUCCESSFULLY_REMOVED_CONF'); + } + } + } + + if ( $trt eq 'NEW' ) { + + # controls + $res = 'OK'; # no controls here... + $result .= $res unless $res eq 'OK'; + if ( ! $result ) { + $res = performCreateClient( $c ); + $result .= $res unless $res eq 'OK'; + if ( ! $result ) { + $result = $c->l('wrg_SUCCESSFULLY_ADDED_CONF'); + } + } + } + + if ( $trt eq 'UPD' ) { + + # controls + $res = 'OK'; # no controls here... + $result .= $res unless $res eq 'OK'; + if ( ! $result ) { + $res = performUpdateConfig( $c ); + $result .= $res unless $res eq 'OK'; + if ( ! $result ) { + $result = $c->l('wrg_SUCCESSFULLY_UPDATED_CONF'); + } + } + } + + + # common parts + + if ($res ne 'OK') { + $c->stash( error => $result ); + $c->stash( title => $title, wrg_datas => \%wrg_datas ); + return $c->render('wireguard'); + } + + #force reload as successfull (for Main) + $wdb = esmith::ConfigDB->open('wireguard'); + + my $message = "'Wireguard' update ($trt) DONE"; + $c->app->log->info($message); + $c->flash( success => $result ); + + $c->redirect_to('/wireguard'); +} + + +# action for 'MOD' +sub performModifyClient{ + + my $c = shift; + my $msg = "OK"; + + my $wgacc = $c->param('Wgconf'); + my $account = $c->param('Account'); + my $private = $c->param('Private') || ''; + my $public = $c->param('Public') || ''; + my $info = $c->param('Info'); + my $status = $c->param('Status') || 'disabled'; + my $allowedips = $c->param('Allowedips') || ''; + + #todo validate fields + +# Untaint info and account before use in system() + ($info) = $info =~ /([A-Za-z0-9_\-. ]+)/; +# trim both ends + $info =~ s/^ +| +$//g; + ($account) = $account =~ /([A-Za-z0-9_-]+)/; + + return $c->l('wrg_ERROR_FIELD_CONTENT') unless ($account and $info); + + my %props = ('user' => $account + ,'private' => $private + ,'public' => $public + ,'info' => $info + ,'status' => $status + ,'allowedips' => $allowedips + ); + + $wdb->get($wgacc)->merge_props(%props) + or $msg = "Error occurred while modifying pseudonym in database."; + + # Untaint before use in system() + ($wgacc) = ($wgacc =~ /(\d+\.+\d+\.+\d+\.+\d+\.+\/\d+\.+)/); + system( "/sbin/e-smith/signal-event", "wireguard-user-modify", "$wgacc",) + == 0 or $msg = "Error occurred while modifying wirequard account."; + + return "$msg" + +} + + +# action for 'NEW' +sub performCreateClient { + + my $c = shift; + my $type = shift; + + my $username = $c->param('Account'); + my $info = $c->param('Info'); + +# Untaint info and account before use in system() + ($info) = $info =~ /([A-Za-z0-9_\-. ]+)/; +# trim both ends + $info =~ s/^ +| +$//g; + + ($username) = $username =~ /([A-Za-z0-9_-]+)/; + + return $c->l('wrg_ERROR_FIELD_CONTENT') unless ($username and $info); + + #get username + my $user = $adb->get($username) or return "$username does not exist"; + return $c->l('wrg_ERROR_WRONG_ACCT_TYPE') unless $user->prop("type") eq "user" or $user->key eq "admin"; + $username = $user->key; + + # execute the event wireguard-user-create username info + unless ( system ("/sbin/e-smith/signal-event", "wireguard-user-create", "$username" , "$info") == 0 ){ + return $c->error('wrg_ERROR_OCCURED'); + } + + return 'OK'; +} + + +# action for 'UPD' +sub performUpdateConfig { + + my $c = shift; + my $msg = "OK"; + + my $ip = $c->param('Ip'); + my $mask = $c->param('Mask'); + my $private = $c->param('Private'); + my $public = $c->param('Public'); + my $status = $c->param('Status'); + + unless (defined $private) { + $private =`/usr/bin/wg genkey`; + ($private) = ($private =~ /(\w+)/); + $public = `/usr/bin/echo $private | /usr/bin/wg pubkey`; + } + + # we get number of entries in wireguard db + my @num=$wdb->get_all_by_prop(type=>"wg0"); + if ( scalar @num >0 ) { + # we get current values + my $pprivate=$cdb->get('wg-quick@wg0')->prop('private'); + my $ppublic=$cdb->get('wg-quick@wg0')->prop('public'); + my $pip=$cdb->get('wg-quick@wg0')->prop('ip'); + my $pmask=$cdb->get('wg-quick@wg0')->prop('mask'); + # if # entries >0 and private |public | ip is chnaged then we push an error and stop + if ($pprivate ne $private || $ppublic ne $public || $pip ne $ip || $mask ne $pmask) { + return $c->l('wrg_CLIENTS_ALREADY_CONFIGURED'); + } + } + + #todo validate fields + + my %props = ('ip' => $ip + ,'mask' => $mask + ,'private' => $private + ,'public' => $public + ,'status' => $status + ); + + $cdb->get('wg-quick@wg0')->merge_props(%props) + or $msg = "Error occurred while modifying server details."; + + # Test Ip is inside CIDR + if ( ! test_for_private_ip( $ip,$mask ) ) { $msg = "IP must be in private range"; } + #else {$msg = "Ip is inside range $ip / $mask";} + + unless ($msg eq "OK"){ + # Untaint before use in system() + ($ip) = ($ip =~ /(\d+\.+\d+\.+\d+\.+\d+\.+\/\d+\.+)/); + system( "/sbin/e-smith/signal-event", "wireguard-conf-modify", "$ip",) + == 0 or $msg = "Error occurred while modifying wireguard conf."; + } + + return "$msg"; + +} + + +# action for 'REM' +sub performRemoveClient{ + + my ($c) = @_; + + my $conf = $c->param('Wgconf'); + if ($c->param("remove")){ + unless ($wdb->get($conf)->delete()){ + return $c->l('wrg_ERROR_OCCURED'); + } + unless (system ("/sbin/e-smith/signal-event", "wireguard-user-delete") == 0 ){ + return $c->l('wrg_ERROR_OCCURED'); + } + return 'OK'; + } + return $c->l('wrg_CANCELLED'); + +} + + +# called from templates +sub get_existing_accounts { + + my $c = shift; + my @existingAccounts = ('Administrator'); + + foreach my $account ($adb->get_all_by_prop(type=>'user')) { + push @existingAccounts, $account->key; + } + return \@existingAccounts; + +} + + +# called from templates +sub get_wgs_info { + + my ($c, $attr, $data) = @_; + + return undef if ( not defined $attr or not defined $data ); + + my $value; + $value = $wdb->get("$data")->prop('info') if ( $attr eq 'info' and $wdb->get("$data") ); + $value = $wdb->get("$data")->prop('user') if ( $attr eq 'user' and $wdb->get("$data") ); + + return $value; + +} + + +# called from templates +sub get_conf_info { + + my ( $c, $ipacc ) = @_; + ##my $ipacc = $c->param('Wgconf'); + + #untaint + ($ipacc) = $ipacc =~ /(\d+\.\d+\.\d+\.\d+\/\d+)/; + #get from db + + # return if does not exist + my $acc = $wdb->get($ipacc) or return undef; + + # return if current user is not admin or the user + return undef unless $c->is_admin; + + my $key = $acc->key; + my $info = $acc->prop('info'); + my $private = $acc->prop('private'); + my $wg0 = $cdb->get('wg-quick@wg0'); + my $ServPublic = $wg0->prop('public'); + my $Port = $wg0->prop('UDPPort'); + my $allowedips = $acc->prop('allowedips') || "0.0.0.0/0"; + + #here we guess wan IP + # are we server-gateway mode ? so external lan, should do + # else we should guess from an external service + my $ExternalIP = $cdb->get('ExternalInterface')->prop('IPAddress'); + $ExternalIP = get_internet_ip_address() unless defined $ExternalIP; + + #DNS + my $IPAddress = $cdb->get('InternalInterface')->prop('IPAddress'); + my $dns = ($allowedips =~ /0.0.0.0\/0/)? "DNS = $IPAddress" : "" ; + + my $fulltext ="#configuration for $key $info +[Interface] +PrivateKey = $private +Address = $key +$dns + +[Peer] +PublicKey = $ServPublic +AllowedIPs = $allowedips +Endpoint = $ExternalIP:$Port +"; + my @fulltext = split( "\n", $fulltext); + + return \@fulltext; + +} + + +# called from templates +sub get_conf_qr { + + my ( $c, $fulltext, $type) = @_; + + my $qr=`echo "$fulltext" |qrencode -t PNG -o - |base64`; + + return $qr; + +} + + +sub get_internet_ip_address { + + #we could use DNS to do this faster but some provider will block DNS + #dig +short myip.opendns.com @resolver1.opendns.com + #also resolver1.opendns.com resolver2.opendns.com resolver3.opendns.com + #here a list of available site with https + use Net::DNS; + use LWP::Simple; + my $timeout=1; + + my @httpslist=qw( +checkip.amazonaws.com +myexternalip.com/raw +ifconfig.me/ +icanhazip.com/ +ident.me/ +tnx.nl/ip +ipecho.net/plain +wgetip.com/ +ip.tyk.nu/ +bot.whatismyipaddress.com/ +ipof.in/txt +l2.io/ip +eth0.me/ ); + my @dns = ( + ['myip.opendns.com', 'resolver1.opendns.com', 'A'], + ['myip.opendns.com', 'resolver2.opendns.com', 'A'], + ['myip.opendns.com', 'resolver3.opendns.com', 'A'], + ['myip.opendns.com', 'resolver4.opendns.com', 'A'], + ['whoami.akamai.net', 'ns1-1.akamaitech.net', 'A'], + ['o-o.myaddr.l.google.com', 'ns1.google.com', 'TXT'] + + ); + + my $ip; + + #foreach my $i ( 0 .. $#dns) { + # dns calls; test only one random... + my $i = rand(@httpslist); + my $res = Net::DNS::Resolver->new( + nameservers => [ $dns[$i][1] ], + udp_timeout => $timeout, + tcp_timeout => $timeout + ); + + my $reply = $res->search($dns[$i][0], $dns[$i][2]); + if ($reply) { + foreach my $rr ($reply->answer) { + $ip= $rr->txtdata if $rr->can("txtdata"); + $ip= $rr->address if $rr->can("address"); + # untaint, dns output is tainted + ($ip) = $ip =~ /(\d+\.\d+\.\d+\.\d+)/; + return $ip if $ip =~ /(\d+\.\d+\.\d+\.\d+)/; + } + } else { + warn "query failed: ", $res->errorstring, "\n"; + } + #} + + # https calls + my $ii=0; + my $service; + while ( $ii <5 ) { + $service=$httpslist[rand(@httpslist)]; + $ip = (get "https://$service" ); + chomp $ip; + $ii++; + last if $ip =~ /(\d+\.\d+\.\d+\.\d+)/; + } + # not needed but in case, untaint + ($ip) = $ip =~ /(\d+\.\d+\.\d+\.\d+)/; + return $ip; + +} + + +sub test_for_private_ip { + + use NetAddr::IP; + $_ = shift; + my $mask = shift; + return unless /(\d+\.\d+\.\d+\.\d+)/; + my $iprange = NetAddr::IP->new($1,"$mask"); + return unless $iprange; + return ($iprange->first()->is_rfc1918() and $iprange->last()->is_rfc1918()); + +} + + +1 + +__END__ diff -urN smeserver-wireguard-1.0.old/root/usr/share/smanager/lib/SrvMngr/I18N/Modules/Wireguard/wireguard_en.lex smeserver-wireguard-1.0/root/usr/share/smanager/lib/SrvMngr/I18N/Modules/Wireguard/wireguard_en.lex --- smeserver-wireguard-1.0.old/root/usr/share/smanager/lib/SrvMngr/I18N/Modules/Wireguard/wireguard_en.lex 1970-01-01 04:00:00.000000000 +0400 +++ smeserver-wireguard-1.0/root/usr/share/smanager/lib/SrvMngr/I18N/Modules/Wireguard/wireguard_en.lex 2022-04-08 23:15:52.000000000 +0400 @@ -0,0 +1,55 @@ +'wrg_WIREGUARD_TITLE' => 'Wireguard panel', +'wrg_FORM_TITLE' => 'Wireguard', +'wrg_DESC_MAIN_PAGE' => 'Welcome to the wireguard panel. You can edit the configuration before creating any client, have a quick look on active connections, and manage clients.', +'wrg_LABEL_CONFIG' => 'Here is the main service configuration and status with active clients.', +'wrg_EDIT_CONFIG' => 'Edit Configuration', +'wrg_PUBLIC_KEY' => 'Public key', +'wrg_IP' => 'IP', +'wrg_PORT' => 'Port', +'wrg_INFO' => 'Information', +'wrg_ENDPOINT' => 'Remote IP', +'wrg_VPN_IP' => 'Internal IP', +'wrg_LATEST_HANDSHAKE' => 'Last handshake', +'wrg_RECEIVED' => 'Received', +'wrg_SENT' => 'Sent', +'wrg_KEEPALIVE' => 'Keep alive', +'wrg_LABEL_CLIENTS' => 'Here is the list of configured clients, You can access their configuration sample or easy configuration QR Code, alter their configuration, remove them or create new clients.', +'wrg_ADD_CLIENT' => 'Configure new client', +'wrg_CONF_NAME' => 'Dedicated IP', +'wrg_USER' => 'Associated User', +'wrg_DESC_MOD_CONFIG_PAGE' => 'Here you can alter the configuration. Be carefull, you can not alter the IP, subnet, private and public keys after you have created clients. The reason is that configured client will also need to be modified if yo do so.', +'wrg_DESC_IP_ACC_WIREGUARD' => 'Wireguard server internal IP.', +'wrg_INFO_IP_WIREGUARD' => 'IP', +'wrg_DESC_MASK_WIREGUARD' => 'Bitmask for the VPN internal network (e.g.: 22).', +'wrg_INFO_MASK_WIREGUARD' => 'Mask', +'wrg_DESC_PRIVATE_CONFIG' => 'Private key for the server, if empty one will be generated.', +'wrg_LABEL_PRIVATE' => 'Private key', +'wrg_DESC_PUBLIC_CONFIG' => 'Public key for the server generated from the private key.', +'wrg_LABEL_PUBLIC' => 'Public key', +'wrg_DESC_STATUS' => 'Status of the sevice.', +'wrg_LABEL_STATUS' => 'Status', +'wrg_DESC_ADD_CLIENT_PAGE' => 'To create a new client. please select user and add information to identify the purpose of this client. The first available IP will be associated and a private/public key pair will be generated for you.', +'wrg_DESC_SELECT_ACCOUNT' => 'Select the associated user account to the wireguard client', +'wrg_SELECT_ACCOUNT' => 'User account', +'wrg_DESC_INFO_ACC_WIREGUARD' => 'Fill a short description to remember what is the purpose of this client, as a user could have multiple clients.', +'wrg_INFO_ACC_WIREGUARD' => 'Information', +'wrg_DESC_DISPLAY_QR_PAGE' => 'You can copy paste this specific configuration to your client computer, or scan the QR code with your phone to configure your client.', +'wrg_DESC_MODIFY_CLIENT_PAGE' => 'You can alter the configuration of the client. Note that providing the private key is not required if you want to keep it secret from the admin, but you will not be able to use the QR code to configure your client and will have to add it manually.', +'wrg_QRCODE' => 'Display Configuration', +'wrg_DESC_CONF_NAME' => 'Dedicated IP associated with this client. It is also its primary identity.', +'wrg_DESC_PRIVATE' => 'Private key for this client, one is generated for easy access, but you can provide yours, or leave it blank, it is only needed to use the scan and configure QR code.', +'wrg_DESC_PUBLIC' => 'Public key is generated from private key, you can provide yours, it is mandatory to be able to connect the client.', +'wrg_DESC_ALLOWEDIPS' => 'You can manually provide the IP blocks that will be redirected through the VPN. This can be configured later on the client, but is provided to ease configuration with QR code. See wireguard man page for syntax. Leave it blank for all traffic to be redirected.', +'wrg_LABEL_ALLOWEDIPS' => 'Allowed IPs', +'wrg_DESC_REMOVE_CLIENT' => 'Do you want to remove this client?', +'wrg_ERROR_FIELD_CONTENT' => 'You must provide a user and information to create a new client.', +'wrg_ERROR_WRONG_ACCT_TYPE' => 'The associated account shoult be a user or admin account.', +'wrg_ERROR_OCCURED' => 'An error occured', +'wrg_CLIENTS_ALREADY_CONFIGURED' => 'You can not alter the server ip, mask, private and public key as there are already some clients configured.', +'wrg_NO_CONF' => 'No configured client', +'wrg_INTERFACE' => 'Interface', +'wrg_CANCELLED' => 'Operation cancelled', +'wrg_SUCCESSFULLY_MODIFIED_CONF' => 'Client configuration successfully modified', +'wrg_SUCCESSFULLY_REMOVED_CONF' => 'Client successfully removed', +'wrg_SUCCESSFULLY_ADDED_CONF' => 'New client successfully added', +'wrg_SUCCESSFULLY_UPDATED_CONF' => 'Server configuration successfully modified', diff -urN smeserver-wireguard-1.0.old/root/usr/share/smanager/themes/default/templates/partials/_wrg_list.html.ep smeserver-wireguard-1.0/root/usr/share/smanager/themes/default/templates/partials/_wrg_list.html.ep --- smeserver-wireguard-1.0.old/root/usr/share/smanager/themes/default/templates/partials/_wrg_list.html.ep 1970-01-01 04:00:00.000000000 +0400 +++ smeserver-wireguard-1.0/root/usr/share/smanager/themes/default/templates/partials/_wrg_list.html.ep 2022-04-15 19:26:26.000000000 +0400 @@ -0,0 +1,130 @@ +
+ +

<%=l 'wrg_DESC_MAIN_PAGE'%>

+ + %= form_for 'wireguard' => (method => 'POST') => begin + %= hidden_field 'trt' => 'UPD' +

<%=l 'wrg_LABEL_CONFIG'%>

+ %= submit_button l('wrg_EDIT_CONFIG'), class => 'action' + % end + +

+ %=l 'wrg_INTERFACE' + wg0

+ +

+ %=l 'wrg_LABEL_STATUS' + + %= $wrg_datas->{sstatus} +

+ +

+ %=l 'wrg_PUBLIC_KEY' + + %= $wrg_datas->{wgpub} +

+ +

+ %=l 'wrg_IP' + + %= $wrg_datas->{wgip}.'/'.$wrg_datas->{wgmask} +

+ +

+ %=l 'wrg_PORT' + + %= $wrg_datas->{wgport} +

+ + + + + + + % if (scalar @$wgstatus > 0) { + % foreach my $list (@$wgstatus) { + % #public-key | private-key | listen-port |persistent-keepalive + % my @line = split(' ',$list); + % next if $line[1] eq $wrg_datas->{wgpub}; + % my ($ginfo, $user); + % $ginfo = $c->get_wgs_info('info', "$line[3]"); + % $user = $c->get_wgs_info('user', "$line[3]"); + % use POSIX qw( strftime ); + % my $dateR= ($line[4] ) ? strftime("%Y-%m-%d %H:%M:%S", localtime($line[4])) : " "; + + %= t td => (class => 'sme-border') => $line[0] + %= t td => (class => 'sme-border') => "$user : $ginfo" + %= t td => (class => 'sme-border') => $line[2] + %= t td => (class => 'sme-border') => $line[3] + %= t td => (class => 'sme-border') => $dateR + %= t td => (class => 'sme-border') => $line[5] + %= t td => (class => 'sme-border') => $line[6] + %= t td => (class => 'sme-border') => $line[7] + + % } + % } +
+ %=l 'wrg_PUBLIC_KEY' + + %=l 'wrg_INFO' + + %=l 'wrg_ENDPOINT' + + %=l 'wrg_VPN_IP' + + %=l 'wrg_LATEST_HANDSHAKE' + + %=l 'wrg_RECEIVED' + + %=l 'wrg_LATEST_SEND' + + %=l 'wrg_KEEPALIVE' +
+ + %= form_for 'wireguard' => (method => 'POST') => begin +
+

<%=l 'wrg_LABEL_CLIENTS'%>

+ %= hidden_field 'trt' => 'NEW' + %= submit_button l('wrg_ADD_CLIENT'), class => 'action' + % end + + % if ( scalar @$wgconf == 0 ) { + %=l 'wrg_NO_CONF' + % } else { + + + + + % foreach my $conf (@$wgconf) { + % my $status = $c->l(uc($conf->prop('status') || 'enabled')); + + %= t td => (class => 'sme-border') => $conf->key + %= t td => (class => 'sme-border') => $conf->prop('user') || '' + %= t td => (class => 'sme-border') => $conf->prop('info') || '' + %= t td => (class => 'sme-border') => $status + % my $action = + % "" . l('wrg_QRCODE') . ""; + + % $action = + % "" . l('MODIFY') . ""; + + % $action = + % "" . l('REMOVE') . ""; + + + % } + +
+ %=l 'wrg_CONF_NAME' + + %=l 'wrg_USER' + + %=l 'wrg_INFO' + + %=l 'wrg_LABEL_STATUS' + + %=l 'ACTION' +
<%= $c->render_to_string(inline => $action) %><%= $c->render_to_string(inline => $action) %><%= $c->render_to_string(inline => $action) %>
+ %} +
+
diff -urN smeserver-wireguard-1.0.old/root/usr/share/smanager/themes/default/templates/partials/_wrg_mod.html.ep smeserver-wireguard-1.0/root/usr/share/smanager/themes/default/templates/partials/_wrg_mod.html.ep --- smeserver-wireguard-1.0.old/root/usr/share/smanager/themes/default/templates/partials/_wrg_mod.html.ep 1970-01-01 04:00:00.000000000 +0400 +++ smeserver-wireguard-1.0/root/usr/share/smanager/themes/default/templates/partials/_wrg_mod.html.ep 2022-04-15 19:28:16.000000000 +0400 @@ -0,0 +1,94 @@ +
+ + %= form_for '/wireguard2' => (method => 'POST') => begin +

+ %=l 'wrg_DESC_MODIFY_CLIENT_PAGE' +

+
+ +

+ %=l 'wrg_DESC_CONF_NAME' +

+ +

+ %=l 'wrg_CONF_NAME' + + %= $wrg_datas->{wgconf} +

+ +

+ %=l 'wrg_DESC_SELECT_ACCOUNT' +

+ +

+ %=l 'wrg_SELECT_ACCOUNT' + + % param 'Account' => $wrg_datas->{account} unless param 'Account'; + %= select_field 'Account' => $c->get_existing_accounts(), class => 'input' +

+ +

+ %=l 'wrg_DESC_INFO_ACC_WIREGUARD' +

+ +

+ %=l 'wrg_INFO_ACC_WIREGUARD' + + % param 'Info' => $wrg_datas->{info} unless param 'Info'; + %=text_field 'Info' => size => '45', class => 'input' +

+ +

+ %=l 'wrg_DESC_PRIVATE' +

+ +

+ %=l 'wrg_LABEL_PRIVATE' + + % param 'Private' => $wrg_datas->{private} unless param 'Private'; + %=text_field 'Private' => size => '45', class => 'input' +

+ +

+ %=l 'wrg_DESC_PUBLIC' +

+ +

+ %=l 'wrg_LABEL_PUBLIC' + + % param 'Public' => $wrg_datas->{public} unless param 'Public'; + %=text_field 'Public' => size => '45', class => 'input' +

+ +

+ %=l 'wrg_DESC_STATUS' +

+ +

+ %=l 'STATUS' + + % param 'Status' => $wrg_datas->{status} unless param 'Status'; + %= select_field 'Status' => [[ (l 'DISABLED') => 'disabled'], [ (l 'ENABLED') => 'enabled']], class => 'input' +

+ +

+ %=l 'wrg_DESC_ALLOWEDIPS' +

+ +

+ %=l 'wrg_LABEL_ALLOWEDIPS' + + % param 'Allowedips' => $wrg_datas->{allowedips} unless param 'Allowedips'; + %=text_field 'Allowedips' => size => '45', class => 'input' +

+ +
+ %= submit_button l('MODIFY'), name => 'modify', class => 'action' +
+ + %= hidden_field 'trt' => $wrg_datas->{trt} + %= hidden_field 'Wgconf' => $wrg_datas->{wgconf} + + % end + +
diff -urN smeserver-wireguard-1.0.old/root/usr/share/smanager/themes/default/templates/partials/_wrg_new.html.ep smeserver-wireguard-1.0/root/usr/share/smanager/themes/default/templates/partials/_wrg_new.html.ep --- smeserver-wireguard-1.0.old/root/usr/share/smanager/themes/default/templates/partials/_wrg_new.html.ep 1970-01-01 04:00:00.000000000 +0400 +++ smeserver-wireguard-1.0/root/usr/share/smanager/themes/default/templates/partials/_wrg_new.html.ep 2021-12-13 20:22:45.000000000 +0400 @@ -0,0 +1,38 @@ +
+ + %= form_for '/wireguard2' => (method => 'POST') => begin +

+ %=l 'wrg_DESC_ADD_CLIENT_PAGE' +

+ +

+ %=l 'wrg_DESC_SELECT_ACCOUNT' +

+ +

+ %=l 'wrg_SELECT_ACCOUNT' + + + %= select_field 'Account' => $c->get_existing_accounts(), class => 'input' +

+ +

+ %=l 'wrg_DESC_INFO_ACC_WIREGUARD' +

+ +

+ %=l 'wrg_INFO_ACC_WIREGUARD' + + + %=text_field 'Info' => size => '60', class => 'input' +

+ +
+ %= submit_button l('ADD'), class => 'action' +
+ + %= hidden_field 'trt' => $wrg_datas->{trt} + + % end + +
diff -urN smeserver-wireguard-1.0.old/root/usr/share/smanager/themes/default/templates/partials/_wrg_qrc.html.ep smeserver-wireguard-1.0/root/usr/share/smanager/themes/default/templates/partials/_wrg_qrc.html.ep --- smeserver-wireguard-1.0.old/root/usr/share/smanager/themes/default/templates/partials/_wrg_qrc.html.ep 1970-01-01 04:00:00.000000000 +0400 +++ smeserver-wireguard-1.0/root/usr/share/smanager/themes/default/templates/partials/_wrg_qrc.html.ep 2022-04-15 19:27:47.000000000 +0400 @@ -0,0 +1,17 @@ +
+ + % my $fulltext = join("\n", @{$c->get_conf_info( $wrg_datas->{wgconf} )}); +

+ %= text_area Info => "$fulltext", cols => 70, rows => 10 +
+ + % my $qr = $c->get_conf_qr("$fulltext"); + %= image "data:image/png;base64,$qr" + +
+ %=l 'wrg_DESC_DISPLAY_QR_PAGE' +
+ %= hidden_field 'trt' => $wrg_datas->{trt} + %= hidden_field 'Wgconf' => $wrg_datas->{wgconf} + +
diff -urN smeserver-wireguard-1.0.old/root/usr/share/smanager/themes/default/templates/partials/_wrg_rem.html.ep smeserver-wireguard-1.0/root/usr/share/smanager/themes/default/templates/partials/_wrg_rem.html.ep --- smeserver-wireguard-1.0.old/root/usr/share/smanager/themes/default/templates/partials/_wrg_rem.html.ep 1970-01-01 04:00:00.000000000 +0400 +++ smeserver-wireguard-1.0/root/usr/share/smanager/themes/default/templates/partials/_wrg_rem.html.ep 2022-04-15 19:27:07.000000000 +0400 @@ -0,0 +1,30 @@ +
+ + %= form_for '/wireguard2' => (method => 'POST') => begin +

+ %=l 'wrg_DESC_REMOVE_CLIENT' +

+ +


+ %=l 'wrg_CONF_NAME' + + %= $wrg_datas->{wgconf} +

+ +

+ %=l 'COMMENT' + + %= $wrg_datas->{wgcomment} +

+ +
+ %= submit_button l('CANCEL'), name => 'cancel', class => 'action' + %= submit_button l('REMOVE'), name => 'remove', class => 'action' +
+ + %= hidden_field 'trt' => $wrg_datas->{trt} + %= hidden_field 'Wgconf' => $wrg_datas->{wgconf} + + % end + +
diff -urN smeserver-wireguard-1.0.old/root/usr/share/smanager/themes/default/templates/partials/_wrg_upd.html.ep smeserver-wireguard-1.0/root/usr/share/smanager/themes/default/templates/partials/_wrg_upd.html.ep --- smeserver-wireguard-1.0.old/root/usr/share/smanager/themes/default/templates/partials/_wrg_upd.html.ep 1970-01-01 04:00:00.000000000 +0400 +++ smeserver-wireguard-1.0/root/usr/share/smanager/themes/default/templates/partials/_wrg_upd.html.ep 2022-04-15 19:27:19.000000000 +0400 @@ -0,0 +1,72 @@ +
+ + %= form_for '/wireguard2' => (method => 'POST') => begin +

+ %=l 'wrg_DESC_MOD_CONFIG_PAGE' +

+ +

+ %=l 'wrg_DESC_IP_ACC_WIREGUARD' +

+ +

+ %=l 'wrg_INFO_IP_WIREGUARD' + + % param 'Ip' => $wrg_datas->{ip} unless param 'Ip'; + %=text_field 'Ip' => class => 'input' +

+ +

+ %=l 'wrg_DESC_MASK_WIREGUARD' +

+ +

+ %=l 'wrg_INFO_MASK_WIREGUARD' + + % param 'Mask' => $wrg_datas->{mask} unless param 'Mask'; + %=text_field 'Mask' => class => 'input' +

+ +

+ %=l 'wrg_DESC_PRIVATE_CONFIG' +

+ +

+ %=l 'wrg_LABEL_PRIVATE' + + % param 'Private' => $wrg_datas->{private} unless param 'Private'; + %=text_field 'Private' => size => '45', class => 'input' +

+ +

+ %=l 'wrg_DESC_PUBLIC_CONFIG' +

+ +

+ %=l 'wrg_LABEL_PUBLIC' + + % param 'Public' => $wrg_datas->{public} unless param 'Public'; + %=text_field 'Public' => size => '45', class => 'input' +

+ +

+ %=l 'wrg_DESC_STATUS' +

+ +

+ %=l 'STATUS' + + % param 'Status' => $wrg_datas->{status} unless param 'Status'; + %= select_field 'Status' => [[ (l 'DISABLED') => 'disabled'], [ (l 'ENABLED') => 'enabled']], class => 'input' +

+ +
+ %= submit_button l('MODIFY'), name => 'modify', class => 'action' +
+ + %= hidden_field 'trt' => $wrg_datas->{trt} + %= hidden_field 'Wgconf' => $wrg_datas->{wgconf} + + % end + +
diff -urN smeserver-wireguard-1.0.old/root/usr/share/smanager/themes/default/templates/wireguard.html.ep smeserver-wireguard-1.0/root/usr/share/smanager/themes/default/templates/wireguard.html.ep --- smeserver-wireguard-1.0.old/root/usr/share/smanager/themes/default/templates/wireguard.html.ep 1970-01-01 04:00:00.000000000 +0400 +++ smeserver-wireguard-1.0/root/usr/share/smanager/themes/default/templates/wireguard.html.ep 2021-12-13 18:40:42.000000000 +0400 @@ -0,0 +1,35 @@ +% layout 'default', title => "Sme server 2 - wireguard"; + +% content_for 'module' => begin +
+ + % if ($config->{debug} == 1) { +

+ %= dumper $c->current_route + %= dumper $wrg_datas +

+ % } + % if ( stash 'error' ) { +
+ %= $c->render_to_string(inline => stash 'error') +
+ %} + +

<%= $title%>

+ + % if ($wrg_datas->{trt} eq 'UPD') { + %= include 'partials/_wrg_upd' + %} elsif ($wrg_datas->{trt} eq 'NEW') { + %= include 'partials/_wrg_new' + %} elsif ($wrg_datas->{trt} eq 'QRC') { + %= include 'partials/_wrg_qrc' + %} elsif ($wrg_datas->{trt} eq 'MOD') { + %= include 'partials/_wrg_mod' + %} elsif ($wrg_datas->{trt} eq 'REM') { + %= include 'partials/_wrg_rem' + %} else { + %= include 'partials/_wrg_list' + %} + +
+%end