#!/usr/bin/expect -f

#(c) 2006 Nuno Rodrigues <nunorodrigues84@gmail.com>

#Por defeito o timeout  10 segundos
#Mexer no timeout: set timeout ***

#Variaveis em que nao vamos mexer
#Strings
set service_status "SERVICE STATUS:"
set fail "CRITICAL"
set ok "OK"

#set imap "IMAP/SSL"
#set smtp "SMTP"

set working "is working on host: " 
set nworking "not working on host: "

#set nagios_fail "SERVICE STATUS: CRITICAL, IMAP/SSL not working :"
#set ka_fail "Failed connection to host :"
#set nagios_success "SERVICE STATUS: OK, IMAP/SSL is working :"
#set ka_success "OK, IMAP/SSL is working :"
#Erros
set t_error 0 
set g_error 1 
set u_error 2 

#Dar uma ajuda ao utilizador
proc usage {} {
	global argv0
	send_user "$argv0 <protocol> <application> <host to connect> \[timeout\] \nprotocol: imaps|SMTP\napplication: nagios|ka|local\n"
	exit 2
}

#verificao de argumentos
proc check_arguments {protocol prog} {

	if { ![string equal $protocol "imaps"] && ![string equal $protocol "SMTP"] } { usage }
	if { ![string equal $prog "nagios"] && ![string equal $prog "ka"] && ![string equal $prog "local"]} { usage }
}

#Funcao de retorno de erro
#Recebe o nome do programa que o est a executar (nagios/ka/local), o nome do host e o tipo de erro(timeout/connection refused) e o protocolo
proc devolve_erro {prog_name host tipo_erro protocolo} {
	global service_status fail nworking
	global t_error g_error u_error
	#Descobrir qual  o tipo de erro
	if { $tipo_erro == $t_error } {
		set erro "TIMEOUT ERROR"
	}
	if { $tipo_erro == $g_error } {
		set erro "CONNECTION REFUSED"
	}
	if { $tipo_erro == $u_error } {
		set erro "UNKNOWN ERROR"
	}
	send_user "$service_status $fail $protocolo $nworking $host\n"	
	if { [string equal $prog_name "nagios"] } {
		#send_user "$nagios_fail $nome $erro\n"
		exit 2
	}
	if { [string equal $prog_name "ka"] } { 
		#send_user "$ka_fail $nome $erro\n"
		exit 1
	} else {
	 	#send_user "Not successful $erro\n"
		exit 1
	}
}

#Funcao de retorno de sucesso
#Recebe como argumentos o nome do programa que o est a correr (nagios/ka/localhost), o nome do host a contactar e o protocolo que est a usar
proc devolve_sucesso {prog_name host protocolo} {
	global service_status ok working
	
	send_user "$service_status $ok $protocolo $working $host\n"
	
	if { [string equal $prog_name "nagios"] } {
		#send_user "$nagios_success $nome\n"
		exit 0
	}
	if { [string equal $prog_name "ka"] } {
		#send_user "$ka_success $nome\n"
		exit 0
	} else { exit 1 }
}

############################################################
###############INICIO DO PROGRAMA!!!!!######################
############################################################
#Vamos verificar se t tudo certo
#Vamos precisar de 3 ou 4 argumentos : 
if {$argc < 3} {
	usage
} 
if {$argc > 4} {
	usage
} else {
	#Temos trs argumentos, ento vamos ver se eles to todos bem definidos
	set protocol [lindex $argv 0]
	set prog [lindex $argv 1]
	set host [lindex $argv 2]

	if {$argc == 4} {
		set timeout [lindex $argv 3]
	}
	
	check_arguments $protocol $prog
}

#Agora tomar a deciso de criar uma ligao SMTP ou IMAP/SSL

if { [string equal $protocol "SMTP"] } {
	#Executar o cdigo do SMTP
	#Fazer telnet para o porto 25
	spawn -noecho /usr/bin/telnet $host 25

	#Suprimir o output
	log_user 0
	
	#Esperar "220 HOST"
	
	expect {
		"220" {
			#Correu bem. O servidor aceitou a ligacao
			#Enviar ehlo
			send "ehlo nuno-adm\r"
			expect {
				"250" {
					#Correu bem. Ele aceitou o ehlo
					#Vamos fazer quit ento
					send "quit\r"
					expect {
						"221" {
							#Correu bem. Desligamos a sesso tranquilamente
							# preciso devolver sucesso
							devolve_sucesso $prog $host $protocol
						}
						timeout {
							#Devolver erro de timeout
							devolve_erro $prog $host $t_error $protocol
						}
						eof {
							#Devolver erro desconhecido
							devolve_erro $prog $host $u_error $protocol
						}
					}
				}
				timeout {
					#Devolver erro de timeout
					devolve_erro $prog $host $t_error $protocol
				}
				eof {
					#Devolver erro desconhecido
					devolve_erro $prog $host $u_error $protocol
				}
			}
		}
		"could not resolve" {
			#Devolver erro de connection refused
			devolve_erro $prog $host $g_error $protocol
		}
		"Connection refused" {
			#Devolver erro de connection refused
			devolve_erro $prog $host $g_error $protocol
		}
		timeout {
			#Devolver erro de timeout
			send_user "deu timeout"
			devolve_erro $prog $host $t_error $protocol
		}
		eof {
			#Devolver erro desconhecido
			devolve_erro $prog $host $u_error $protocol
		}
	}
	
} else {
	#Executar o cdigo do IMAP/SSL

	#Executar o comando
	#Usar ssl v3 para ligar  porta 993 (IMAP/SSL)
	spawn -noecho /usr/bin/openssl s_client -host $host -ssl3 -port 993 -quiet 

	#Primeiro, limpar o output do expect 
	log_user 0

	#Depois de ligar, vamos esperar 2 coisas diferentes: OK / Connection Refused
	expect {
		"errno" {
			#Problemas aqui.  preciso devolver erro
			devolve_erro $prog $host $g_error $protocol
		}
		"OK" {
			send "a001 logout\r"
			expect {
				"OK LOGOUT completed" {
				#T tudo OK. Vamos l enviar o output, consoante a aplicao que teja a correr isto (ka/nagios)
				devolve_sucesso $prog $host $protocol
				}
				timeout {
					#Erro por timeout
					devolve_erro $prog $host $t_error $protocol
				}
				eof {
					#Erro desconhecido
					devolve_erro $prog $host $u_error $protocol
				}
			}	
		}
		timeout {
			#Timeout logo a ligar ao servidor de IMAP
			devolve_erro $prog $host $t_error $protocol
		}
		eof {
			#Erro desconhecido a ligar
			devolve_erro $prog $host $u_error $protocol
		}
	} 
}

