check_openvpn.cpp 3.85 KB
#include "check_openvpn.h"

using namespace std;

char *servicename = (char*)"OpenVPN";

void printVersion()
{
	cout << "check_openvpn v" << VERSION << endl << endl;
}

void printHelp(bool longVersion)
{
	if(longVersion)
	{
		printVersion();
		cout << "Check OpenVPN server" << endl << endl;
		printHelp(false);
		cout << "Options:" << endl;
		cout << " -h" << endl;
		cout << "    Print detailed help screen" << endl;
		cout << " -V" << endl;
		cout << "    Print version information" << endl;
		cout << " -H HOSTADDRESS" << endl;
		cout << "    Host where the UPnP server is running" << endl;
                cout << " -p PORT" << endl;
                cout << "    OpenVPN Administration port" << endl;
                cout << " -P PASSWORD" << endl;
                cout << "    OpenVPN Administration password" << endl;
		return;
	}
	cout << "Usage: " << endl << "check_openvpn [-hV] -H HOSTADDRESS -p PORT -P PASSWORD" << endl << endl;
}

int check_openvpn(uint16_t port, char *hostname, char *password, string *serverinfo)
{
    size_t numClients = 0;
    string ipList = "";
    char buffer[MAX_TCP+1];
    int s;
    int timeout = 10;
    int bytes = 0;
    string output = "";

    s = createSocket();
    connect(s,port,hostname,timeout);
    while(output != "ENTER PASSWORD:")
    {
        recvMsg(s,buffer,MAX_TCP);
	output += buffer;
        memset(buffer,0x00,MAX_TCP+1);
    }
    sendMsg(s,strcat(password,"\n"),strlen(password)+1);
    output = "";
    do
    {
        bytes = recvMsg(s,buffer,MAX_TCP);
        output += buffer;
        memset(buffer,0x00,MAX_TCP+1);
    }while(bytes);
    if(output == "ENTER PASSWORD:")
    {
        *serverinfo = "Incorrect password";
        close(s);
        return 3;
    }
    output = "";
    sendMsg(s,(char*)"status 2\n",9);
    do
    {
        bytes = recvMsg(s,buffer,MAX_TCP);
        output += buffer;
        memset(buffer,0x00,MAX_TCP+1);
    }while(output.rfind("END") != output.size()-5);
    vector<string> splitstr;
    vector<string> fields;
    split(output,"\n",splitstr);
    for(vector<string>::iterator it = splitstr.begin() ; it != splitstr.end(); ++it)
    {
        if(it->substr(0,11) == "CLIENT_LIST")
        {
            split(*it,",",fields);
            ipList += fields[3] + ",";
            numClients++;
        }
    }
    if(numClients)
    {
        ipList.pop_back();
    }
    *serverinfo = int2str(numClients) + " clients connected (" + ipList + ")" ;
    close(s);
    return 0;
}

int main(int argc, char **argv)
{
	struct itimerval timer;
	timer.it_value.tv_sec = 10;
	timer.it_value.tv_usec = 0;
	timer.it_interval.tv_sec = 0;
	timer.it_interval.tv_usec = 0;
	setitimer (ITIMER_VIRTUAL, &timer, 0);

	struct sigaction sa;
	memset (&sa, 0, sizeof (sa));
	sa.sa_handler = &timer_handler;
	sigaction (SIGVTALRM, &sa, 0);

	uint16_t port = 1195;
	char *hostname = NULL;
        char *password = NULL;
	int c;

	while ((c = getopt (argc, argv, "H:p:P:Vh")) != -1)
	{
		switch(c)
		{
			case 'H':
        			hostname = optarg;
        			break;
			case 'p':
       		 		port = (uint16_t) str2int(optarg);
       		 		break;
			case 'P':
       		 		password = optarg;
       		 		break;
			case 'V':
				printVersion();
				return 0;
			case 'h':
				printHelp(true);
				return 0;
			case '?':
				printHelp(false);
				return 3;
		}
	}

	if(hostname == NULL)
	{
		cout << "No HOSTADDRESS specified. Exiting." << endl;
		return 3;
	}

        if(password == NULL)
        {
            cout << "No PASSWORD specified. Exiting." << endl;
            return 3;
        }

	string serverinfo = "";
	int returnCode = check_openvpn(port,hostname,password,&serverinfo);

	cout << servicename;
	switch(returnCode)
	{
		case 0:
			cout << " OK - " << serverinfo << endl ;
			break;

		case 2:
			cout << " CRITICAL - No response" << endl;
			break;

        case 3:
            cout << " UNKNOWN - " << serverinfo << endl;
	}

	return returnCode;
}