Perl Module Net::DNS - calling "tsig" method on resolver object results in error - perl

recently the linux-distribution i use (recent gentoo)
upgraded the net-dns package to version 0.74 (from 0.66).
from this time using TSIG on queries and updates
does not work anymore.
former i used:
$resolver = Net::DNS::Resolver->new(...);
$resolver->tsig( $keyname, $key );
# ($key as base64 representation)
or
$resolver->tsig( Net::DNS::RR->new( "$keyname TSIG $key" ) );
calling tsig now results in an expeption:
"zone file representation not defined for TSIG at /usr/lib/perl5/vendor_perl/5.18.2/i686-linux/Net/DNS/RR.pm line 683."
according to http://search.cpan.org/~nlnetlabs/Net-DNS-0.74/lib/Net/DNS/Resolver.pm#tsig
tsig() - Get or set the TSIG record used to automatically sign outgoing queries and updates.
my usage of tsig() should be correct.
using another way of pre-creating the tsig RR-Object with:
my $tsig = Net::DNS::RR->new( type => "TSIG", name => "KEYNAME", key => "KEY" );
$resolver->tsig($tsig);
results in "tsig verify failure (BADSIG)" Errors in BIND at server side.
using $tsig for update packets only:
my $update = Net::DNS::Update->new( ... );
$update->sign_tsig($tsig);
also does not work (BADSIG); the 'simpler' way
$update->sign_tsig($keyname, $key);
does work.
What is the correct way to use TSIG for both query and update packets with the resolver object in Net::DNS >= V0.74 ?
Perl Version is 5.18.2 .
what am i doing wrong ? - thanks a lot for your hints.

The TSIG functionality in Net::DNS had a complete rewrite around 0.74, and most releases since then have had bugfixes for some aspect of TSIG. I'd suggest that you try to forget how it used to work, re-read all the relevant documentation and then change your own code as needed.
Also, 0.74 is (in this context) pretty old. It would probably be a good idea to upgrade to something closer to current (which is 0.82 when I write this).

Related

Autoload'd calls fail via Inline::Perl5 in Raku

I'm rewriting some perl/charting software in Raku but have run into an issue using the ChartDirector perl5 module (link below) via Inline::Perl5. The module is basically a perl interface to a DLL; using the module via Inline::Perl5 seems to work for method calls explicitly included in the code - but most of the method calls are executed via the autoload 'catch all' mechanism in perl5. These do not work in my raku code.
My question is can I expect this sort of application to work using Inline::Perl5? (perhaps there is no way to 'catch' these autoload'd method calls) and, if so, how to make it so.
Thanks for any pointers, suggestions.
wf
ChartDirector software (excellent graphics/charting software - have used it for nearly 2 decades with perl): https://www.advsofteng.com/index.html
Quoting verbiage (simplified), version info, and code from the start of a chartdir forum thread about this:
I'm using Inline::Perl5 which works with every other module I've tried.
I'm hitting problems reproducing the "first project" example on the chartdir site.
using chartdir 6, freebsd 12.2 (intel platform), raku 2022.04, perl 5.32.1.
#!/usr/bin/env raku
use lib:from<Perl5> '/usr/local/lib/perl5/site_perl';
use Inline::Perl5;
my $p5 = Inline::Perl5.new;
$p5.use('perlchartdir') ;
my $data = [85, 156, 179.5, 211, 123];
my $labels = ["Mon", "Tue", "Wed", "Thu", "Fri"];
my $c = $p5.invoke( 'XYChart', 'new', 250, 250);
$c.setPlotArea(30, 20, 200, 200);
$c.addBarLayer($data);
$c.xAxis().setLabels($labels);
$c.xAxis().setLabels($labels);
$c.makeChart("simplebar.png");
All seems fine (i.e., data-dumping $c after line 8 shows a large/reasonable looking structure) until line 9 where I receive "No such method setPlotArea for invocant of type XYChart". Line 10 does appear to work (no complaints) - remaining 3 lines don't (same type of error as for line 8).
And quoting some feedback that was given by Peter Kwan, the primary dev of chartdir:
I have never used Raku before. For your case, the methods that fail seem to be AUTOLOAD methods. ... I suspect may be Raku does not support Perl AUTOLOAD, so it reports undefined methods as not found instead of forwarding it to the "catch all" method. Or may be some additional things need to be imported for it to use the AUTOLOAD.
As dwarring notes in the comments below this SO question, Inline::Perl5 does support autoload (and has for 7 years), so perhaps that aspect is a red herring?
gratefully responding to p6steve's response, I am providing some additional information ..
The full output from various representations of $c (the XYChart object) is included here: https://pastebin.com/gY2ibDaM (hope it's ok to use pastebin for this (still finding my way through stackoverflow)) - the output was 600+ lines long and wasn't sure what I could usefully edit out).
to summarize though ..
dd $c returns nil (although prints out the equivalent of $c.perl (below) to stdout (not sure why))
say $c.perl returns:
XYChart.new(inline-perl5 => Inline::Perl5.new(thread-id => 1), wrapped-perl5-object => NativeCall::Types::Pointer.new(34651088744))
say $c.^methods returns:
(WHERE addHLOCLayer ACCEPTS WHY can new isa rakuseen defined getYCoor addHLOCLayer3 raku yZoneColor Numeric addLineLayer addAreaLayer DESTROY BUILDALL gist perl WHICH sink bless getYValue Str addBarLayer new_shadow_of_p5_object AT-KEY)
finally, say Dump $c (using Data::Dump module) yields about 600 lines of output (included in the pastebin output).
Hi wingfold and welcome to the raku SO tag!
I wonder what you get with dd $c; just before the line $c.setPlotArea(30, 20, 200, 200); - e.g. is $c truly an XYChart object?
If so then what does $c.^methods (the '^' indicates a meta method ... in this case you should get a list of the available methods).
Please do post the results here and hopefully that will help the diagnosis...
Thanks for the info!
Having seen the output of the $c.^methods call, it is clear that $c has no method $c.setPlotArea (reading the error message says the same - perhaps I should have given that due weight!)
I do not know the Inline::Perl5 module well, but I have seen similar issues with Inline::Python.
My experience in Python is that the target language objects only expose their "direct" methods and do not automatically pull in all the composed methods that they can perform.
My workaround has been on the lines of an "eval" style approach, something like:
$p5.run( qq[$c.setPlotArea(30, 20, 200, 200);] );
Hope this helps!

Connectivity issue to Sybase DB from Perl script

I have to connect my Perl script to a newly constructed Sybase server version - 16.0.03.08.1019
Error - login Failed (due to encrypt password issue)
Previously the script was written in Perl:
$conn = Sybase::DBlib->new($user,$pass,$server,"$dbase Handle");
$conn->sql("use $dbase");
I searched online every where it is written put EncryptPassword=1.
I tried two ways shown below, but couldn't succeed.
$conn = Sybase::DBlib->new($user,$pass,$server,"$dbase Handle","EncryptPassword=1");
$conn = Sybase::DBlib->new("EncryptPassword=1",$user,$pass,$server,"$dbase Handle");
My question is, where to use EncryptPassword=1 in Perl script. Am I using it in correct place.
Wow! DBlib - that takes me back. When I last worked with DBlib (in about 1995), one of the tasks on my list was to replace all use of DBlib with CTlib - which was Sybase's new technology that was intended to replace DBlib. Soon after that, the system was rewritten again to use DBI and DBD::Sybase - which has been the recommended way to talk to Sybase databases from Perl programs for over twenty years. You'll note that the most recent release of sybperl (which is the CPAN distribution containing Sybase::DBlib and Sybase::CTlib) was over ten years ago. I'm pretty sure that Sybase themselves haven't supported DBlib since about the start of this millennium.
So, bearing in mind that you're using ancient technology that is largely dead and shouldn't be used, is there anything that can be done to help you without rewriting the whole system?
Perhaps.
Looking at the documentation for Sybase::DBlib, I see this example of how to write calls to new():
$dbh = new Sybase::DBlib [$user [, $pwd [, $server [, $appname [, {additional attributes}]]]]]
Ignore the fact that it's using the new Class syntax that any rational programmer would avoid - the Class->new() version is this:
$dbh = Sybase::DBlib->new([$user [, $pwd [, $server [, $appname [, {additional attributes}]]]]])
Note the "additional attributes" field at the end. I bet that's where your stuff needs to go. Note also, that it's { additional attributes } - so it looks like it expects a hash reference.
So it seems likely that the syntax you want is this:
$conn = Sybase::DBlib->new($user, $pass, $server, "$dbase Handle", {
EncryptPassword => 1,
});
Note that there are huge caveats in this. Not least, given that Sybase::DBlib has been unsupported for ten years, I wouldn't be at all surprised if it didn't support encrypted passwords at all.
But it might work. It's probably your best hope.
And please do whatever you can to update your codebase to use tools and libraries that haven't been unsupported for such a long time.

"Insecure dependency error while running with -T switch" using cicindela2

I am applying the cicindela2 recommendation engine
It uses Apache mod_perl and the Perl DBI module.
Here is the rough flow of how it works
Data input by Record Handler
Data is passed through the filter chain for batch processing
Temporary tables are output from batch processing
Recommendation result is requested by accessing the Recommend Handler which trigger the action of Recommender
I configured an aggregation and ran the project batch script. I know that the batch processing succeeded because I saw the output of processing from DB. But when I tried to access the recommendation result with URL that triggers the Recommend Handler, I saw a blank white page and the log said
FATAL: Insecure dependency in parameter 1 of DBIx::ContextualFetch::db=HASH(0x7f2a76169e78)->prepare_cached method call while running with -T switch at /usr/local/share/perl5/Ima/DBI.pm line 398.
This is where the error was thrown from the
Ima::DBI
base module
/usr/local/share/perl5/Ima/DBI.pm.
sub _mk_sql_closure {
my ($class, $sql_name, $statement, $db_meth, $cache) = #_;
return sub {
my $class = shift;
my $dbh = $class->$db_meth();
# Everything must pass through sprintf, even if #_ is empty.
# This is to do proper '%%' translation.
my $sql = $class->transform_sql($statement => #_);
return $cache # Line 398
? $dbh->prepare_cached($sql)
: $dbh->prepare($sql);
};
}
It seems that the SQL query prepared by the program is insecure, right?
What is reason for this error?
Is it related to the function of cache management of DBI?
Would it be solved if I clear the cache regularly?
Also, I tried to log the SQL statement generated, but the output failed even when I placed something like $LOGGER->warn("123") in the handle subroutine of the Recommend Handler.
How come the log failed and how to log it correctly?
Insecure dependency... while running with -T switch is Perl's way of telling you that you're running with taint mode active and attempting to do something with tainted data which could be potentially unsafe. In this particular case, $sql is tainted, because some or all of its content came from sources external to the program - probably user input, although it could also have been read from a file.
To fix this, you need to think about where $sql came from, so that you can work out the appropriate way to clean it up.
In the most likely scenario, you've asked a user to supply search terms and then inserted those terms directly into your SQL string. This is a bad idea in general, as it opens you up to the possibility of SQL injection attacks. (Obligatory Bobby Tables link.) Revise your SQL handling to make use of SQL placeholders instead of inserting user input into the WHERE clause and this vulnerability should go away.
If tainted data is making its way into $sql in some other way, you need to clean up the tainted data by using a regular expression to validate it and capture the validated data, then assign the captured data to your variable. e.g.,
my $tainted = <STDIN>;
$tainted =~ /([A-Z]*)/; # Only allow uppercase characters
my $clean = $1; # No longer tainted because it came from $1
If you need to take this route, DO NOT use .* as your regex to untaint the data without serious, serious consideration, because, if you just blindly accept any and all data, you will be discarding any and all benefit provided by taint mode.

perl6 Changes in IO::Socket::INET from last year and broken promises

When I asked a question last year about promises, my echo server was working (see this link: perl6 how to get specific identity of promises? ). However, with the new versions of perl6, my echo server is no longer working.
I guess I can try the example from the perl6 documentation site ( https://docs.perl6.org/type/IO::Socket::INET ), but I want to find out what mistake I have made in my code. My current level has precluded me from seeing the difference between my codes and the codes on the perl6 documentation site. Please give me a hint; thanks !
my #result;
for 0 .. 2 -> $index {
#result[$index] = start {
my $myPromiseID = $index;
say "======> $myPromiseID\n";
my $rsSocket = IO::Socket::INET.new:
localhost => 'localhost',
localport => 1234 + $index,
listen => 1;
while $rsSocket.accept -> $rsConnection {
say "Promise $myPromiseID accepted connection";
while $rsConnection.recv -> $stuff {
say "Promise $myPromiseID Echoing $stuff";
$rsConnection.print($stuff);
}
$rsConnection.close;
}
}
}
await #result;
And the error messages are:
Tried to get the result of a broken Promise
in block <unit> at p6EchoMulti.pl line 24
Original exception:
Nothing given for new socket to connect or bind to
in block at p6EchoMulti.pl line 8
Actually thrown at:
in block at p6EchoMulti.pl line 13
This commit, which was announced in the Jan 2017 section of Rakudo's changelog as "Fixed bug where IPv6 URIs were not parsed correctly" did a lot more that just fix a URI parsing bug. It also completely redid the parameter binding/validation of an IO::Socket::INET.new call, and one consequence is it broke your code because the updated code requires that listen be an actual Bool, not merely coerce to one.
The old code (the code on the left of the commit link above) had a simple method new (*%args is copy). This matched your call. The error (fail "Nothing given for new socket to connect or bind to") did not trigger because 1 evaluates to True in a boolean context so %args<host> || %args<listen> was also True. So the rest of the code ran with listen set to 1 and it all worked out fine.
Rakudos from 2017.01 have the code on the right at the commit link above. Note how there are now multiple new methods (i.e. multiple multi method new ... declarations).
The multi(s) intended to handle a call that specifies a listen argument is/are of the form multi method new (..., Bool:D :$listen!, ...). Note the Bool:D.
A call to new, with the listen parameter set to True, matches this multi and works as expected.
But a call with :listen(1) will just match the generic multi method new (*%args) signature instead. This latter does an unconditional fail "Nothing given for new socket to connect or bind to";.
Okay, after some struggling, it seems to have improved if I changed listen=>1 to listen=>True.
Can anyone care to explain why 1 was not evaluated to True, and why it worked before?
Thanks.

What is the best way to ensure the correctness of data returned by a SNMP query?

I am working on code which uses the snmp->get_bulk_request() method to make SNMP queries to get interface table details from a network device.
The problem I am facing is that sometimes, the data I receive from the query is missing some detail. This is a transient issue.
I believe that placing a set number of retries will reduce the probability of error. But, as I go through the documentation for snmp->get_bulk_request(), I find a parameter called
maxrepetitions. It is not clear to me from the documentation what this parameter does.
I am trying to figure out what effect the maxrepetitions parameter has when used with the get_bulk_request call method. I have gone through the documentation in "get_bulk_request() - send a SNMP get-bulk-request to the remote agent" and found this:
$result = $session->get_bulk_request(
[-callback => sub {},] # non-blocking
[-delay => $seconds,] # non-blocking
[-contextengineid => $engine_id,] # v3
[-contextname => $name,] # v3
[-nonrepeaters => $non_reps,]
[-maxrepetitions => $max_reps,]
-varbindlist => \#oids,
);
The default value for get-bulk-request -maxrepetitions is 0. The maxrepetitions value specifies the number of successors to be returned for the remaining variables in the variable-bindings list.
Specifically, my questions are:
Is adding maxrepetitions equivalent to adding retries for the query?.
Is retrying the right way to ensure the data is most probably correct?
If not, what is the best method to ensure the probability error is low in data returned by SNMP query?
From the man page:
Set the max-repetitions field in the GETBULK PDU. This specifies the maximum number of iterations over the repeating
variables.
Example
snmpbulkget -v2c -Cn1 -Cr5 -Os -c public zeus system ifTable
will retrieve the variable system.sysDescr.0 (which is the lexicographically next object to system) and the first 5 objects in
the ifTable:
sysDescr.0 = STRING: "SunOS zeus.net.cmu.edu 4.1.3_U1 1 sun4m"
ifIndex.1 = INTEGER: 1
ifIndex.2 = INTEGER: 2
ifDescr.1 = STRING: "lo0"
et cetera.