#!/usr/bin/perl use 5.024; use strict; use warnings; use autodie; use Config::Tiny; use Time::HiRes qw(gettimeofday); use POSIX qw(strftime); use HTTP::Tiny; use HTTP::CookieJar; use JSON::PP; use Text::CSV; my $verbose = 1; my $CONFIG_FILE = "/home/mischa/netskope/netskope.cnf"; my $config = Config::Tiny->read($CONFIG_FILE, 'utf8'); my $NTSKP_TENANT = $config->{netskope}{NTSKP_TENANT}; my $NTSKP_TOKEN = $config->{netskope}{NTSKP_TOKEN}; my $NTSKP_REPORTID = $config->{netskope}{NTSKP_REPORTID}; my $ZS_MAX_DOMAINS = $config->{zscaler}{ZS_MAX_DOMAINS}; my $ZS_BASE_URI = $config->{zscaler}{ZS_BASE_URI}; my $ZS_API_KEY = $config->{zscaler}{ZS_API_KEY}; my $ZS_API_USERNAME = $config->{zscaler}{ZS_API_USERNAME}; my $ZS_API_PASSWORD = $config->{zscaler}{ZS_API_PASSWORD}; my $ZS_CATEGORY_NAME = $config->{zscaler}{ZS_CATEGORY_NAME}; my $ZS_CATEGORY_DESC = $config->{zscaler}{ZS_CATEGORY_DESC}; say "Running..."; # Authenticate my $now = int(gettimeofday * 1000); my $n = substr($now, -6); my $r = sprintf "%06d", $n >> 1; my $key; for my $i (0..length($n)-1) { $key .= substr($ZS_API_KEY, substr($n, $i, 1), 1); } for my $i (0..length($r)-1) { $key .= substr($ZS_API_KEY, substr($r, $i, 1) + 2, 1); } my $uri = "$ZS_BASE_URI/authenticatedSession"; my $body = JSON::PP->new->space_after->encode({apiKey => $key, username => $ZS_API_USERNAME, password => $ZS_API_PASSWORD, timestamp => $now}); my $jar = HTTP::CookieJar->new; my $request = HTTP::Tiny->new('default_headers' => {"Content-Type" => "application/json", "Cache-Control" => "no-cache"}, 'cookie_jar' => $jar); my $response = $request->post($uri, {'content' => $body}); if ($verbose) { say "POST $uri"; say "BODY $body"; say "HTTP " . $response->{'status'}; say "COOKIE " . $jar->cookie_header($ZS_BASE_URI); } # Get filter list id $uri = "$ZS_BASE_URI/urlCategories/lite"; $response = $request->get($uri); my $json = JSON::PP->new->utf8->decode($response->{'content'}); my $id; for my $item (@{$json}) { if (exists($item->{'configuredName'})) { if ($item->{'configuredName'} eq $ZS_CATEGORY_NAME) { $id = $item->{'id'}; } } } # Push Domains my @domains = ('secomtrust.net', 'baidupcs.com', 'cloud.baidu.com'); $uri = defined($id) ? "$ZS_BASE_URI/urlCategories/$id" : "$ZS_BASE_URI/urlCategories"; my $method = defined($id) ? "put" : "post"; my $description = "$ZS_CATEGORY_DESC\n\nLast Updated: " . strftime("%Y-%m-%d %H:%M:%S", localtime); $#domains = $#domains >= $ZS_MAX_DOMAINS ? $ZS_MAX_DOMAINS : $#domains; $body = JSON::PP->new->space_after->encode({configuredName => $ZS_CATEGORY_NAME, customCategory => 'true', superCategory => 'SECURITY', urls => \@domains, description => $description}); $response = $request->$method($uri, {'content' => $body}); if ($verbose) { say uc($method) . " $uri"; say "BODY $body"; say "HTTP " . $response->{'status'}; say "RESPONSE " . $response->{'content'} if ($response->{'status'} =~ /^4/); } # Delete authenticadSession $uri = "$ZS_BASE_URI/authenticatedSession"; $response = $request->delete($uri); if ($verbose) { say "DELETE $uri"; say "HTTP " . $response->{'status'}; }