Why is the netmask in Net::IP set wrong? - perl

I'm trying to get a little script to recognize the SNMP data from a query to store it in a database. But I'm stuck when processing the data with the Net::IP CPAN module. If I define the network string there is no problem, but I have IP and mask in separate strings, and no matter how I join them, the module always set the netmask to /32.
I tried it like this:
my $net = "${$query_snmp->{$tablekey}}{'ipRouteMask'}/${$query_snmp->{$tablekey}}{'ipRouteDest'}";
my $IP = new Net::IP ($net) or die (Net::IP::Error());
But all the IP objects are always created with /32 no matter what I set the netmask to. If i define a string like 192.168.0.0/20 or anything on the same string I find no problem.
What am I missing?
Network -> 192.168.65.64/255.255.255.248
IP : 192.168.65.64
LASTIP : 192.168.65.64
Sho : 192.168.65.64
Bin : 11000000101010000100000101000000
Int : 3232252224
*** Mask: 255.255.255.255 *** wtf ??
Last: 192.168.65.64
Len : 32
Size: 1
Type: PRIVATE
Rev: 64.65.168.192.in-addr.arpa.

From the manual: A Net::IP object can be created from a single IP address, or from a Classless Prefix, ...
I think you've chosen to specify a classless network, provided that you insert a valid network specifier, it works for me.
#!/usr/bin/perl -w
use Net::IP;
my $ip = new Net::IP('112.198.64.0/18') or die (Net::IP::Error());
print ("IP : ".$ip->ip()."\n");
print ("Sho : ".$ip->short()."\n");
print ("Bin : ".$ip->binip()."\n");
print ("Int : ".$ip->intip()."\n");
print ("Mask: ".$ip->mask()."\n");
print ("Last: ".$ip->last_ip()."\n");
print ("Len : ".$ip->prefixlen()."\n");
print ("Size: ".$ip->size()."\n");
print ("Type: ".$ip->iptype()."\n");
print ("Rev: ".$ip->reverse_ip()."\n");
will output:
IP : 112.198.64.0
Sho : 112.198.64
Bin : 01110000110001100100000000000000
Int : 1892040704
Mask: 255.255.192.0
Last: 112.198.127.255
Len : 18
Size: 16384
Type: PUBLIC
Rev: 64.198.112.in-addr.arpa.
However, if you've entered "192.168.65.64/255.255.255.248", this is not a format accepted by Net::IP, you've to use instead "192.68.65.64/29", see this table. In this case it will work correctly:
IP : 192.168.65.64
Sho : 192.168.65.64
Bin : 11000000101010000100000101000000
Int : 3232252224
Mask: 255.255.255.248
Last: 192.168.65.71
Len : 29
Size: 8
Type: PRIVATE
Rev: 64.65.168.192.in-addr.arpa.
When you use the format with the full netmask, since it's not recognized, it gets just the IP and will give you the netmask of 255.255.255.255

thank you ! I finally used a simillar module, that doest requier to transform the ip mask to dec notation.
Net::Netmask -> https://metacpan.org/pod/Net::Netmask
CONSTRUCTING
Net::Netmask objects are created with an IP address and optionally a mask. There are many forms that are recognized:
'216.240.32.0/24' The preferred form.
'216.240.32.0:255.255.255.0'
'216.240.32.0-255.255.255.0'
'216.240.32.0', '255.255.255.0'
'216.240.32.0', '0xffffff00'
'216.240.32.0 - 216.240.32.255'
'216.240.32.4'
A /32 block.
'216.240.32'
Always a /24 block.
'216.240'
Always a /16 block.
'140'
Always a /8 block.
'216.240.32/24'
'216.240/16'
'default' or 'any'
0.0.0.0/0 (the default route)
'216.240.32.0#0.0.31.255'
Thank you.

Related

PowerShell - to check multiple Port Status

I was trying to check whether the port is opened or not using powershell like follows.
My question is : I want to check multiple ports such as 389,53,135. how can we do that?
Here is my script :
$Ipaddress= "xx.xx.xx.xx"
$Port= "389"
$t = New-Object Net.Sockets.TcpClient
$t.Connect($Ipaddress,$Port)
if($t.Connected)
{
"Port $Port is operational"
}
else
{
"Port $Port is closed, You may need to contact your IT team to open it. "
}
My desired output :
Port 389 is operational;Port 53 is operational;Port 135 is operational
Use PowerShells Test-NetConnection and just put that inside a loop that iterates over an array of ports.
For syntax and usage see https://learn.microsoft.com/en-us/powershell/module/nettcpip/test-netconnection?view=windowsserver2022-ps

How to parse JSON from https website using Ada

I am trying to make a simple parser for an https website push, so trying to follow from the example from http://rosettacode.org/wiki/HTTP#Ada, just changing the address from a website.
So I tried
with Ada.Text_IO; use Ada.Text_IO;
with AWS.Client;
with AWS.Response;
procedure Main_Other is
begin
Put_Line (AWS.Response.Message_Body
(AWS.Client.Get
(URL => "https://google.com")));
end Main_Other;
But I got an exception
raised PROGRAM_ERROR : aws-client.adb:398 finalize/adjust raised exception
[2020-04-02 10:41:20] process exited with status 1, elapsed time: 00.80s
So, any thoughts on how to fix that?
I'd like to parse the current status of some tables in a website, similar of making something like that in Python
import pandas as pd
def retrieve_json(json_url):
return pd.read_json(json_url)
I'd like to code this solution the simplest way possible, even better not relying on AWS.
Please, and thanks.
It seems that you're using a build of AWS with SSL support disabled (SSL support is optional). Replacing https with http should do the trick. If an unsecured connection is not an option, either recompile AWS with SSL support enabled (see here and here) or, if you're in a hurry and happen to develop on Linux, fall back on GNAT.Expect and wget (tested with GNAT CE 2019):
main.adb
with Ada.Text_IO; use Ada.Text_IO;
with GNAT.Expect; use GNAT.Expect;
with GNATCOLL.JSON; use GNATCOLL.JSON;
procedure Main is
-------------------
-- Download_JSON --
-------------------
function Download_JSON (URL : String) return JSON_Value is
Cmd : constant String := "wget";
Arg_1 : aliased String := "-q"; -- Turn off Wget's own messages.
Arg_2 : aliased String := "-O"; -- Output response to ...
Arg_3 : aliased String := "-"; -- ... standard output.
Arg_4 : aliased String := URL;
Status : aliased Integer;
Response : String :=
Get_Command_Output
(Command => Cmd,
Arguments => (1 => Arg_1'Unchecked_Access,
2 => Arg_2'Unchecked_Access,
3 => Arg_3'Unchecked_Access,
4 => Arg_4'Unchecked_Access),
Input => "",
Status => Status'Unchecked_Access);
begin
-- Omitting check of 'Status' for brevity.
return Read (Response);
end;
Root : JSON_Value;
begin
Root := Download_JSON
("https://raw.githubusercontent.com/AdaCore/gnatcoll-core/" &
"master/testsuite/tests/json/validation/basic_object.json");
Put_Line (Write (Root));
end Main;
default.gpr
with "gnatcoll.gpr";
project Default is
for Source_Dirs use ("src");
for Object_Dir use "obj";
for Main use ("main.adb");
end Default;
output
$ ./main
{"a":1,"b":"a tringg","c":[1,2,3],"d":{"a":"a"},"e":null}

Private only dovecot, local docker configuration for one user fails login for Apple Mail

I'm trying to make a local docker-dovecot machine to archive my e-mails. I would like to query them with Apple Mail. I have a simple ubuntu docker machine (on an VM with parallels, because I'm on a Mac).
I have this local.conf:
# A comma separated list of IPs or hosts where to listen in for connections.
# "*" listens in all IPv4 interfaces, "::" listens in all IPv6 interfaces.
# If you want to specify non-default ports or anything more complex,
# edit conf.d/master.conf.
listen = *,::
# Protocols we want to be serving.
protocols = imap
# Static passdb.
# This can be used for situations where Dovecot doesn't need to verify the
# username or the password, or if there is a single password for all users:
passdb {
driver = static
args = password=dovecot
}
# Location for users' mailboxes. The default is empty, which means that Dovecot
# tries to find the mailboxes automatically. This won't work if the user
# doesn't yet have any mail, so you should explicitly tell Dovecot the full
# location.
#
# If you're using mbox, giving a path to the INBOX file (eg. /var/mail/%u)
# isn't enough. You'll also need to tell Dovecot where the other mailboxes are
# kept. This is called the "root mail directory", and it must be the first
# path given in the mail_location setting.
#
# There are a few special variables you can use, eg.:
#
# %u - username
# %n - user part in user#domain, same as %u if there's no domain
# %d - domain part in user#domain, empty if there's no domain
# %h - home directory
#
# See doc/wiki/Variables.txt for full list. Some examples:
#
# mail_location = maildir:~/Maildir
# mail_location = mbox:~/mail:INBOX=/var/mail/%u
# mail_location = mbox:/var/mail/%d/%1n/%n:INDEX=/var/indexes/%d/%1n/%n
#
# <doc/wiki/MailLocation.txt>
#
mail_location = maildir:/var/mail/%n
# System user and group used to access mails. If you use multiple, userdb
# can override these by returning uid or gid fields. You can use either numbers
# or names. <doc/wiki/UserIds.txt>
# mail_uid = CHANGE_THIS_to_your_short_user_name_or_uid
# mail_gid = admin
# SSL/TLS support: yes, no, required. <doc/wiki/SSL.txt>
ssl = no
# Login user is internally used by login processes. This is the most untrusted
# user in Dovecot system. It shouldn't have access to anything at all.
# default_login_user = _dovenull
# Internal user is used by unprivileged processes. It should be separate from
# login user, so that login processes can't disturb other processes.
# default_internal_user = _dovecot
# Setting limits.
default_process_limit = 10
default_client_limit = 50
and I'm getting this from Apple Mail
May 23 07:15:58 Mail[87524] <Debug>: <0x7fe16f021cd0:[Non-authenticated]> Wrote: 1.11 ID ("name" "Mac OS X Mail" "version" "9.3 (3124)" "os" "Mac OS X" "os-version" "10.11.5 (15F34)" "vendor" "Apple Inc.")
May 23 07:15:58 Mail[87524] <Debug>: <0x7fe16f021cd0:[Non-authenticated]> Read: * ID {
name = Dovecot;
}
May 23 07:15:58 Mail[87524] <Debug>: <0x7fe16f021cd0:[Non-authenticated]> Read: 1.11 OK
May 23 07:15:58 Mail[87524] <Debug>: <0x7fe16f021cd0:[Non-authenticated]> Wrote: 3.11 LOGOUT
May 23 07:16:00 Mail[87524] <Debug>: <0x7fe16aa14590:[Disconnected]> Read: * OK [CAPABILITY (
IMAP4REV1,
"LITERAL+",
"SASL-IR",
"LOGIN-REFERRALS",
ID,
ENABLE,
IDLE,
"AUTH=PLAIN",
"AUTH=LOGIN"
)]
May 23 07:16:00 Mail[87524] <Debug>: <0x7fe16aa14590:[Non-authenticated]> Wrote: 1.23 ID ("name" "Mac OS X Mail" "version" "9.3 (3124)" "os" "Mac OS X" "os-version" "10.11.5 (15F34)" "vendor" "Apple Inc.")
May 23 07:16:00 Mail[87524] <Debug>: <0x7fe16aa14590:[Non-authenticated]> Read: * ID {
name = Dovecot;
}
May 23 07:16:00 Mail[87524] <Debug>: <0x7fe16aa14590:[Non-authenticated]> Read: 1.23 OK
May 23 07:16:00 Mail[87524] <Debug>: <0x7fe16aa14590:[Non-authenticated]> Wrote: 3.23 LOGOUT
and this from dovecot (mail.log):
May 23 05:07:22 f8ab3e20742f dovecot: master: Dovecot v2.2.9 starting up (core dumps disabled)
May 23 05:07:22 f8ab3e20742f dovecot: ssl-params: Generating SSL parameters
May 23 05:07:29 f8ab3e20742f dovecot: ssl-params: SSL parameters regeneration completed
May 23 05:07:52 f8ab3e20742f dovecot: imap-login: Aborted login (no auth attempts in 0 secs): user=<>, rip=10.211.55.2, lip=172.17.0.2, session=<IJwtbHszbgAK0zcC>
May 23 05:07:54 f8ab3e20742f dovecot: imap-login: Aborted login (no auth attempts in 0 secs): user=<>, rip=10.211.55.2, lip=172.17.0.2, session=<qsRNbHszdgAK0zcC>
The output of doveconf -n is (so "disable_plaintext_auth = no" is active):
# 2.2.9: /etc/dovecot/dovecot.conf
# OS: Linux 4.4.8-boot2docker x86_64 Ubuntu 14.04.4 LTS aufs
auth_mechanisms = plain login
default_client_limit = 50
default_process_limit = 10
disable_plaintext_auth = no
listen = *,::
mail_location = maildir:/var/mail/%n
namespace inbox {
inbox = yes
location =
mailbox Drafts {
special_use = \Drafts
}
mailbox Junk {
special_use = \Junk
}
mailbox Sent {
special_use = \Sent
}
mailbox "Sent Messages" {
special_use = \Sent
}
mailbox Trash {
special_use = \Trash
}
prefix =
}
passdb {
args = password=dovecot
driver = static
}
protocols = imap
ssl = no
Any suggestions why this login isn't working?
Thanks!
The solution is to fix and configure the following line correctly (from local.conf):
# mail_uid = CHANGE_THIS_to_your_short_user_name_or_uid
How did I find out? Thanks to #Kondybas for the pointer to try another client. I used Thunderbird and it produced dovecot log entries (why didn't Apple Mail produce these lines? No clue), saying that it couldn't switch to mail_uid user context. I extended dovecot Dockerfile and switched the user appropriately. Afterwards it worked with Thunderbird and then with Apple Mail.

Docker + Exim + Dovecot. Relay not permitted

Trying to configure Exim mail server using this article. I can use this server inside my local network but when I try to use it from internet I taking some errors. Ports 10000-20000 translate to server machine. Everything I doing inside the docker image of CentOS 7. Host machine with CentOS 7 too.
Abbreviations:
test_domain.tk - my test domain
test1, test2 - test users
test#external.com - test external email
123.456.789.876 - my external ip (I have router with NAT)
10.0.7.30 - docker's tunnel
Starting docker with command: docker run -d --name mail -h test_domain.tk -p 10025:25 -p 10587:587 -p 10465:465 -p 10143:143 -p 10993:993 mail/server:localwork start_server
start_server:
#!/bin/bash -e
/usr/sbin/dovecot && /usr/sbin/exim -v -bdf -q30m
/etc/exim/exim.conf:
primary_hostname = test_domain.tk
domainlist local_domains = # : localhost : test_domain.tk
domainlist relay_to_domains =
hostlist relay_from_hosts =
acl_smtp_mail = acl_check_mail
acl_smtp_rcpt = acl_check_rcpt
acl_smtp_data = acl_check_data
acl_smtp_mime = acl_check_mime
av_scanner = clamd:/var/run/clamd.exim/clamd.sock
tls_advertise_hosts = *
tls_certificate = /etc/ssl/default.crt
tls_privatekey = /etc/ssl/default.key
daemon_smtp_ports = 25 : 465 : 587
tls_on_connect_ports = 465
allow_domain_literals
never_users = root
auth_advertise_hosts = *
rfc1413_hosts = *
rfc1413_query_timeout = 5s
ignore_bounce_errors_after = 2d
timeout_frozen_after = 7d
begin acl
acl_check_mail:
deny condition = ${if eq{$sender_helo_name}{} {1}}
message = Nice boys say HELO first
warn condition = ${if eq{$sender_host_name}{} {1}}
set acl_m_greylistreasons = Host $sender_host_address lacks reverse DNS\n$acl_m_greylistreasons
accept
acl_check_rcpt:
accept hosts = :
control = dkim_disable_verify
deny message = Restricted characters in address
domains = +local_domains
local_parts = ^[.] : ^.*[#%!/|]
deny message = Restricted characters in address
domains = !+local_domains
local_parts = ^[./|] : ^.*[#%!] : ^.*/\\.\\./
accept local_parts = postmaster
domains = +local_domains
require verify = sender
accept hosts = +relay_from_hosts
control = submission
control = dkim_disable_verify
accept authenticated = *
control = submission
control = dkim_disable_verify
require message = relay not permitted
domains = +local_domains : +relay_to_domains
require verify = recipient
accept
acl_check_data:
warn condition = ${if !def:h_Message-ID: {1}}
set acl_m_greylistreasons = Message lacks Message-Id: header. Consult RFC2822.\n$acl_m_greylistreasons
accept
acl_check_mime:
deny message = Blacklisted file extension detected
condition = ${if match \
{${lc:$mime_filename}} \
{\N(\.exe|\.pif|\.bat|\.scr|\.lnk|\.com)$\N} \
{1}{0}}
accept
begin routers
dnslookup:
driver = dnslookup
domains = ! +local_domains
transport = remote_smtp
ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8
# if ipv6-enabled then instead use:
# ignore_target_hosts = <; 0.0.0.0 ; 127.0.0.0/8 ; ::1
no_more
system_aliases:
driver = redirect
allow_fail
allow_defer
data = ${lookup{$local_part}lsearch{/etc/aliases}}
# user = exim
file_transport = address_file
pipe_transport = address_pipe
userforward:
driver = redirect
check_local_user
# local_part_suffix = +* : -*
# local_part_suffix_optional
file = $home/.forward
allow_filter
no_verify
no_expn
check_ancestor
file_transport = address_file
pipe_transport = address_pipe
reply_transport = address_reply
procmail:
driver = accept
check_local_user
require_files = ${local_part}:+${home}/.procmailrc:/usr/bin/procmail
transport = procmail
no_verify
localuser:
driver = accept
check_local_user
# local_part_suffix = +* : -*
# local_part_suffix_optional
transport = local_delivery
cannot_route_message = Unknown user
begin transports
remote_smtp:
driver = smtp
remote_msa:
driver = smtp
port = 587
hosts_require_auth = *
procmail:
driver = pipe
command = "/usr/bin/procmail -d $local_part"
return_path_add
delivery_date_add
envelope_to_add
user = $local_part
initgroups
return_output
local_delivery:
driver = appendfile
directory = $home/Maildir
maildir_format
maildir_use_size_file
delivery_date_add
envelope_to_add
return_path_add
address_pipe:
driver = pipe
return_output
address_file:
driver = appendfile
delivery_date_add
envelope_to_add
return_path_add
address_reply:
driver = autoreply
begin retry
* * F,2h,15m; G,16h,1h,1.5; F,4d,6h
begin rewrite
begin authenticators
dovecot_login:
driver = dovecot
public_name = LOGIN
server_socket = /var/run/dovecot/auth-client
server_set_id = $auth1
dovecot_plain:
driver = dovecot
public_name = PLAIN
server_socket = /var/run/dovecot/auth-client
server_set_id = $auth1
exim log:
8 LOG: MAIN
8 exim 4.84 daemon started: pid=8, -q30m, listening for SMTP on port 25 (IPv6 and IPv4) port 587 (IPv6 and IPv4) and for SMTPS on port 465 (IPv6 and IPv4)
16 LOG: host_lookup_failed MAIN
16 no host name found for IP address 123.456.789.876
16 LOG: MAIN REJECT
16 H=([10.0.7.30]) [123.456.789.876] X=SSLv3:DHE-RSA-AES128-SHA:128 F=<test1#test_domain.tk> rejected RCPT <test#external.com>: relay not permitted
16 LOG: lost_incoming_connection MAIN
16 unexpected disconnection while reading SMTP command from ([10.0.7.30]) [123.456.789.876]
When I try to connect from internet I got timeout error in mail client and empty logs in Exim. It's probably problem of work with router. How to make it works?
Ask me if you need more data. Thanks in advance.
You have your docker internal ports (for example 10025) mapped to standard smtp ports (for example 25), but you have exim listening on the standard ports instead of the mapped internal ports. Configure exim to listen on 10025, 10465, 10587 and see if the behavior changes.
It seems there's an issue with reverse DNS lookup according to this ancient post. Try disabling host_lookup and see if that works:
host_lookup = 0.0.0.0/0
If it does you'll have to fix your DNS settings to map the right domain to your host.

DNS Client that is written Using C Sockets

I just want to write DNS client program using C sockets that
takes three arguments: a query name (e.g., host name or domain name) and a query type (A, or NS, or MX), and DNS server name. Print out the responses in the answer section of the DNS record received.
I know there is a command getaddrinfo..
but I just want to connect to lookup table and then
get the DNS server name...
so when i give the input ./a.out www.google.com A 144.20.190.70
it will show something similar to this:
Server: 144.20.190.70
Address: 144.20.190.70#53
Non-authoritative answer:
Name : www.google.com
Canonical name : www.l.google.com
Name : www.l.google.com
Address : 74.125.19.104
Name : www.l.google.com
Address : 74.125.19.105
Name : www.l.google.com
Address : 74.125.19.106
Name : www.l.google.com
Address : 74.125.19.147
Name : www.l.google.com
Address : 74.125.19.99
Name : www.l.google.com
Address : 74.125.19.103
Yes you need to see Bev.net.dns class that Rob-philpott made for .net
Click Here
building requests to send to DNS servers is not easy but once you can get the answer back from the server then you need to send it back to the browser and this is the bit i've got stuck on.
i listen on port 53/UDP and get the request and send it to the DNS server and get a valid responce but then i send that back to the browser using the remote client port as a UDP but the browser will not except the reply.
Robs code is real easy to use as shown below "Resolver.Lookup" and i just neded to add a bit so that the original byte array sent from the DNS server as saved in Resolver.Message ready to send back to the browser.
public void Listen()
{
receiveSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp );
receiveEndPoint = new IPEndPoint(IPAddress.Any, receivePort); receiveSocket.Bind(receiveEndPoint);
receivePort = (receiveSocket.LocalEndPoint as IPEndPoint).Port;
receiveBuffer = new byte[BufferSize];
receiveAsyncResult = receiveSocket.BeginReceiveFrom(receiveBuffer, 0, receiveBuffer.Length, SocketFlags.None, ref receiveEndPoint, new AsyncCallback(NetworkMessageReceivedCallback), receiveSocket);
}
public void NetworkMessageReceivedCallback(IAsyncResult asyncResult)
{
EndPoint remoteEndPoint = null;
byte[] bytes = null;
remoteEndPoint = new IPEndPoint(IPAddress.Any, 0); //Will contain the clients port
int bytesRead = receiveSocket.EndReceiveFrom(asyncResult, ref remoteEndPoint);
bytes = new Byte[bytesRead];
Buffer.BlockCopy(receiveBuffer, 0, bytes, 0, bytesRead);
//string ip = "208.67.222.222";
string ip = "192.168.1.254";
IPAddress dnsServer = IPAddress.Parse(ip);
Response R = Resolver.Lookup(bytes, dnsServer);
receiveSocket.SendTo(R.Message , remoteEndPoint);//127.0.0.1
receiveSocket.Close();
Listen();
}