[powershell]Send access request to Tufin SecureChange using REST API

Previously I had a code in powershell, however this update supports ip address range format.

accepted source and destination addresses formats are:
1. hostname
2. host ip address
3. subnet in cidr notation
4. ip address range, from first ip to last ip.

#ignore certificate validation
add-type @"
    using System.Net;
    using System.Security.Cryptography.X509Certificates;
    public class TrustAllCertsPolicy : ICertificatePolicy {
        public bool CheckValidationResult(
            ServicePoint srvPoint, X509Certificate certificate,
            WebRequest request, int certificateProblem) {
            return true;
        }
    }
"@
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

$NS_URI = $null

$xpath = "ticket/steps/step/tasks/task/fields/field"
function Obfuscate_Password($username){
    if ((Test-Path .\tufin_s.do) -eq $true) {
    $password = Get-Content ".\tufin_s.do" | ConvertTo-SecureString
    $credential = New-Object System.Management.Automation.PSCredential($username,$password)
    } else {
        Read-Host $username -AsSecureString | ConvertFrom-SecureString | Out-File -NoClobber .\tufin_s.do
        #This is to allow time for the file to be written, otherwise there is a possibility that invoke-restmethod will throw an exception that is really weird.
        #Eg. Invoke-RestMethod : You must write ContentLength bytes to the request stream before calling [Begin]GetResponse.
        Start-Sleep -Seconds 2
        $password = Get-Content ".\tufin_s.do" | ConvertTo-SecureString
        $credential = New-Object System.Management.Automation.PSCredential($username,$password)
        }
    return $credential.GetNetworkCredential().Password
}


function is_ipv4_address($newhost){
$ipcheck = ($newhost -as [IPaddress]) -as [Bool]
if($ipcheck)
{
    return $true
}
elseif($newhost -like "*/*")
{
    $cidr = $newhost.split("/")
    if($cidr[1] -ge '0' -and $cidr[1] -le '32')
    {
        return $true
    }
    else{
        return $false
    }
}
elseif($newhost -like "*-*")
{
    $ip = $newhost.split("-")
    $ip1 = $ip[0] -as [IPaddress] -as [Bool]
    $ip[0] >> "fwr_add.log"
    $ip2 = $ip[1] -as [IPaddress] -as [Bool]
    $ip[1] >> "fwr_add.log"
    if($ip1 -and $ip2)
    {
       return $true
    }
    else
    {
       return $false
    }

}
else
{
    return $false
}
}

[xml]$body = New-Object System.Xml.XmlDocument
$body.Load(".\config.xml")



#1 is the title, for user to see
$a = 2 #source
$b = 2 #destination
$c = 2 #service
$d = 2 #action
$e = 2 #comment
$src = @() # source ip address collection
$dst = @()
$srcHosts = @() # source hostnames collection
$dstHosts = @()
$services = @() # collection of services
#$src_obj = @()
#$dst_obj = @()
$accessRequest = @()
$xl = New-Object -ComObject Excel.Application
$xl.Visible = $false # To prevent the excel from opening visibly.
$wb = $xl.Workbooks.Open("H:\Tufin\tests\Rulebook.xlsx")

$rule_name = $wb.Worksheets | Select-Object "Name"
foreach($rule in $rule_name)
{
    
    
    $ws = $wb.Sheets.item($rule.Name)
    #$ws = $wb.sheets.item("Rule1")
    if($ws.Range("A" + $a).Text -eq "" -or $ws.Range("B" + $b).Text -eq "" -or $ws.Range("C" + $c).Text -eq "")
    {
        break
    }
        # can use as a function for this part
    
    $access_request_node = $body.CreateNode("element","access_request",$NS_URI)
    $use_topology_node = $body.CreateNode("element","use_topology",$NS_URI)
    $users_node = $body.CreateNode("element","users",$NS_URI)
    $user_element = $body.CreateElement("user")
    $sources_node = $body.createNode("element","sources",$NS_URI)
    $destinations_node = $body.CreateNode("element","destinations",$NS_URI)
    $services_node = $body.CreateNode("element","services",$NS_URI)
    $action_node = $body.CreateNode("element","action",$NS_URI)
    $labels_node = $body.CreateNode("element","labels",$NS_URI)
    $body.ticket.steps.step.tasks.task.fields.field.AppendChild($access_request_node)
    
    $access_request_node.AppendChild($use_topology_node)
    $access_request_node.AppendChild($users_node)
    $users_node.AppendChild($user_element)
    $user_element.InnerText = "Any"
    $access_request_node.appendchild($sources_node)
    $access_request_node.appendchild($destinations_node)
    $access_request_node.AppendChild($services_node)
    $access_request_node.AppendChild($action_node)
    $action_node.InnerText = "Accept"
    $access_request_node.AppendChild($labels_node)
    $use_topology_node.InnerText = "true"

    while($true)
    {
        if($ws.Range("A" + $a).Text -ne "") # collect until an empty cell.
            {
                $srcHosts += $ws.Range("A" + $a).Text
        }
        else
        {
            break
        }
        $a += 1
    }
    foreach($srcHost in $srcHosts) 
    {
        if(is_ipv4_address($srcHost)){
                $srcHost >> "fwr_add.log"
                $src += $srcHost            
        }
              
        
        else {
            $srcHost + " resolving" >> "fwr_add.log"
            try{
                $src += [System.Net.DNS]::GetHostEntry($srcHost).AddressList.IPAddressToString
            }
            catch {
                $err=$_.Exception
                $err.Message
            }
        }
        
    }
    foreach($src_ip in $src) {
        if($src_ip -like "*/*"){
            $src_obj =  $src_ip.split("/")
            $source_node = $body.createNode("element","source",$NS_URI)
            $source_node.SetAttribute("type","IP")
            $source_address_element = $body.CreateElement("ip_address")
            $source_address_cidr_element = $body.CreateElement("cidr")
            $sources_node.AppendChild($source_node)
            $source_node.AppendChild($source_address_element)
            $source_node.AppendChild($source_address_cidr_element)
            $source_address_element.InnerText = $src_obj[0]
            $source_address_cidr_element.InnerText = $src_obj[1]
            }

        elseif($src_ip -like "*-*"){
            $src_obj = $src_ip.split("-")
            $source_node = $body.CreateNode("element","source",$NS_URI)
            $source_node.SetAttribute("type","RANGE")
            $source_address_range_first_ip = $body.CreateElement("range_first_ip")
            $source_address_range_last_ip = $body.CreateElement("range_last_ip")
            $sources_node.AppendChild($source_node)
            $source_node.AppendChild($source_address_range_first_ip)
            $source_node.AppendChild($source_address_range_last_ip)
            $source_address_range_first_ip.InnerText = $src_obj[0]
            $src_obj[0] + " at foreach step" >> "fwr_add.log"
            $source_address_range_last_ip.InnerText = $src_obj[1]
            $src_obj[1] + " at foreach step" >> "fwr_add.log"

        }

        else{

            $source_node = $body.createNode("element","source",$NS_URI)
            $source_node.SetAttribute("type","IP")
            $source_address_element = $body.CreateElement("ip_address")
            $source_address_mask_element = $body.CreateElement("netmask")
            $sources_node.AppendChild($source_node)
            $source_node.AppendChild($source_address_element)
            $source_node.AppendChild($source_address_mask_element)
            $source_address_element.InnerText = $src_ip
            $source_address_mask_element.InnerText = "255.255.255.255"
            }
    }

    while($true)
    {
        if($ws.Range("B" + $b).Text -ne "")
        {
            $dstHosts += $ws.Range("B" + $b).Text
        }
        else
        {
            break
        }
        $b += 1
    }
    foreach($dstHost in $dstHosts)
    {
        if(is_ipv4_address($dstHost)){
            $dstHost >> "fwr_add.log"
            $dst += $dstHost
        }
        else{    
           $dst += [System.Net.DNS]::GetHostEntry($dstHost).AddressList.IPAddressToString
        }
    }
    foreach($dst_ip in $dst) {
        if($dst_ip -like "*/*"){
           $dst_obj =  $dst_ip.split("/")
           $destination_node = $body.CreateNode("element","destination",$NS_URI)
           $destination_node.SetAttribute("type","IP")
           $destination_address_element = $body.CreateElement("ip_address")
           $destination_address_mask_element = $body.CreateElement("netmask")
           $destination_address_cidr_element = $body.CreateElement("cidr")
           $destinations_node.AppendChild($destination_node)
           $destination_node.AppendChild($destination_address_element)
           $destination_node.AppendChild($destination_address_cidr_element)
           $destination_address_element.InnerText = $dst_obj[0]
           $destination_address_cidr_element.InnerText = $dst_obj[1]
           }
        elseif($dst_ip -like "*-*"){
           $dst_obj = $dst_ip.Split("-")
           $destination_node = $body.CreateNode("element","destination",$NS_URI)
           $destination_node.SetAttribute("type","RANGE")
           $destination_address_range_first_ip = $body.CreateElement("range_first_ip")
           $destination_address_range_last_ip = $body.CreateElement("range_last_ip")
           $destinations_node.AppendChild($destination_node)
           $destination_node.AppendChild($destination_address_range_first_ip)
           $destination_node.AppendChild($destination_address_range_last_ip)
           $destination_address_range_first_ip.InnerText = $dst_obj[0]
           $dst_obj[0] + " at foreach step" >> "fwr_add.log"
           $destination_address_range_last_ip.InnerText = $dst_obj[1]
           $dst_obj[1] + " at foreach step" >> "fwr_add.log"

        }

        else {
           $destination_node = $body.createNode("element","destination",$NS_URI)
           $destination_node.SetAttribute("type","IP")
           $destination_address_element = $body.CreateElement("ip_address")
           $destination_address_mask_element = $body.CreateElement("netmask")
           $destinations_node.AppendChild($destination_node)
           $destination_node.AppendChild($destination_address_element)
           $destination_node.AppendChild($destination_address_mask_element)
           $destination_address_element.InnerText = $dst_ip
           $destination_address_mask_element.InnerText = "255.255.255.255"

        }
    }
    while($true)
    {
        if($ws.Range("C" + $c).Text -ne "")
        {
            $services_s += @($ws.Range("C" + $c).Text)
        }
        else
        {
            break
        }
        $c += 1
    }
    foreach($service in $services_s)
    {
        
        
        if($service.ToString().ToLower() -like "*tcp*")
        {
            $proto = "TCP"
            $port_num = $service.Replace("tcp","")
        }
        elseif($service.ToString().ToLower() -like "*udp*") {
            $proto = "UDP"
            $port_num = $service.Replace("udp","")
        }
        else {
            $proto = "TCP"
            $port_num = $service.Replace("tcp","")
        }

        $service_node = $body.CreateNode("element","service",$NS_URI)
        $service_node.SetAttribute("type","PROTOCOL")
        $protocol_element = $body.CreateElement("protocol")
        $port_element = $body.CreateElement("port")
        $services_node.AppendChild($service_node)
        $service_node.AppendChild($protocol_element)
        $service_node.AppendChild($port_element)
        $protocol_element.InnerText = $proto
        $port_element.InnerText = $port_num
    }
        
    $body.save("example_2.xml")

    $a = 2 #source
    $b = 2 #destination
    $c = 2 #service
    $d = 2 #action
    $e = 2 #comment
    $src = @() # source ip address collection
    $dst = @()
    $srcHosts = @() # source hostnames collection
    $dstHosts = @()
    $services_s = @()
    $services = @()
}    



$xl.Workbooks.Close()
$xl.Quit()
[void][System.Runtime.Interopservices.Marshal]::FinalReleaseComObject($ws)
[void][System.Runtime.Interopservices.Marshal]::FinalReleaseComObject($wb)
[void][System.Runtime.Interopservices.Marshal]::FinalReleaseComObject($xl)
[GC]::Collect()

$usr = "admin"
$pwd = Obfuscate_Password($usr)
$cred = "${usr}:${pwd}"
$bytes = [System.Text.Encoding]::ASCII.GetBytes($cred)
$base64 = [System.Convert]::ToBase64String($bytes)
$basicAuthValue = "Basic $base64"
$headers = @{ Authorization = $basicAuthValue }
               
       
#sleep to defeat the z monster = "You must write ContentLength bytes to the request stream before calling [Begin]GetResponse."
Start-Sleep -Seconds 5 
try
{
  Invoke-RestMethod -Uri "https://tufin_address/securechangeworkflow/api/securechange/tickets/"  -Method Post -ContentType "application/xml" -Headers $headers -Body $body 
}
catch {
    $err=$_.Exception
    $err.Message
}
Advertisement

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s