#!/usr/bin/env expect

# Agentless monitoring
#
# Copyright (C) 2015-2020, Wazuh Inc.
# Copyright (C) 2009 Trend Micro Inc.
# All rights reserved.
#
# This program is free software; you can redistribute it
# and/or modify it under the terms of the GNU General Public
# License (version 2) as published by the FSF - Free Software
# Foundation.

if {$argc < 1} {
    send_user "ERROR: ssh_pixconfig_diff <hostname> <commands>\n";
    exit 1;
}

# NOTE: this script must be called from within /var/ossec for it to work
set passlist "agentless/.passlist"
set hostname [lindex $argv 0]
set commands [lrange $argv 1 end]
set pass "x"
set addpass "x"
set timeout 20

if {[string compare $hostname "test"] == 0} {
    if {[string compare $commands "test"] == 0} {
        exit 0;
    }
}

# Read the password list
if {! [file isfile $passlist]} {
    send_user "ERROR: Password list not present (use \"register_host\" first).\n"
    exit 1;
}

set in [open "|base64 -d $passlist"]

while {[gets $in line] != -1} {
        set me [string first "|" $line]
        set me2 [string last "|" $line]
        set length [string length $line]

        if {$me == -1} {
            continue;
        }
        if {$me2 == -1} {
            continue;
        }
        if {$me == $me2} {
            continue;
        }

        set me [expr $me-1]
        set me2 [expr $me2-1]

        set host_list [string range $line 0 $me]
        set me [expr $me+2]
        set pass_list [string range $line $me $me2]
        set me2 [expr $me2+2]
        set addpass_list [string range $line $me2 $length]

        if {[string compare $host_list $hostname] == 0} {
            set pass "$pass_list"
            set addpass "$addpass_list"
            break
        }
}
close $in

if {[string compare $pass "x"] == 0} {
    send_user "ERROR: Password for '$hostname' not found.\n"
    exit 1;
}

# SSH to the box and pass the directories to check
if [catch {
    spawn ssh $hostname
} loc_error] {
    send_user "ERROR: Opening connection: $loc_error.\n"
    exit 1;
}

expect {
    "WARNING: REMOTE HOST" {
        send_user "ERROR: RSA host key for '$hostname' has changed. Unable to access.\n"
        exit 1;
    }
    "*sure you want to continue connecting*" {
        send "yes\r"
        expect "* password:*" {
            send "$pass\r"

            expect {
                "Permission denied" {
                    send_user "ERROR: Incorrect password to remote host: $hostname .\n"
                    exit 1;
                }
                timeout {
                    send_user "ERROR: Timeout while running on host (too long to finish): $hostname .\n"
                    exit 1;
                }
                "*>" {
                    send_user "\nINFO: Starting.\n"
                }
            }
        }
    }
    "ssh: connect to host*" {
        send_user "ERROR: Unable to connect to remote host: $hostname .\n"
        exit 1;
    }
    "no address associated with name" {
        send_user "ERROR: Unable to connect to remote host: $hostname .\n"
        exit 1;
    }
    "*Connection refused*" {
        send_user "ERROR: Unable to connect to remote host: $hostname .\n"
        exit 1;
    }
    "*Connection closed by remote host*" {
        send_user "ERROR: Unable to connect to remote host: $hostname .\n"
        exit 1;
    }
    "* password:*" {
        send "$pass\r"

        expect {
            "Permission denied" {
                send_user "ERROR: Incorrect password to remote host: $hostname .\n"
                exit 1;
            }
            timeout {
                send_user "ERROR: Timeout while running on host (too long to finish): $hostname .\n"
                exit 1;
            }
            "*>" {
                send_user "INFO: Starting.\n"
            }
        }
    }
    timeout {
        send_user "ERROR: Timeout while connecting to host: $hostname . \n"
        exit 1;
    }
}

if {[string compare $addpass ""] != 0} {
    # Go into enable mode
    send "enable\r"
    expect {
        "Password:" {
            send "$addpass\r"

                expect {
                    "*asswor*" {
                        send_user "ERROR: Incorrect enable password to remote host: $hostname .\n"
                            exit 1;
                    }
                    "*rror - incorrect password*" {
                        send_user "ERROR: Incorrect enable password to remote host: $hostname .\n"
                            exit 1;
                    }
                    timeout {
                        send_user "ERROR: Timeout while going to enable mode on host: $hostname .\n"
                            exit 1;
                    }
                    "*#" {
                        send_user "ok on enable pass\n"
                    }
                }
        }
        timeout {
            send_user "ERROR: Timeout while running enable on host: $hostname .\n"
                exit 1;
        }
    }
}

# Send commands
set timeout 60
send_user "\nSTORE: now\n"

send "skip-page-display\r"

# Exclude uptime from the output
send "sh run\r"
send "$commands\r"
send "exit\rexit\r"

expect {
    timeout {
        send_user "ERROR: Timeout while running commands on host: $hostname .\n"
        exit 1;
    }
    eof {
        send_user "\nINFO: Finished.\n"
        exit 0;
    }
}

send_user "ERROR: Unable to finish properly.\n"
exit 1;
