/* 
   SQL Auditing Tools
   Copyright (C) Patrik Karlsson 2001
   
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.
   
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include "tds.h"
#include "sqldict.h"
#include "constants.h"
#include "util.h"
#include <getopt.h>

/*
  Set a few default values
*/
TDSLOGIN *set_target_defaults(TDSLOGIN *login) {

  login = tds_alloc_login();
  tds_set_passwd(login, "");
  tds_set_user(login, "sa");
  tds_set_app(login, "Microsoft Access");
  tds_set_host(login, "xxx");
  tds_set_library(login,"TDS-Library");
  tds_set_charset(login,"iso_1");
  tds_set_language(login, "us_english");
  tds_set_server(login, "");
  tds_set_packet(login, 512);
  tds_set_port(login, 1433);

  return login;

}

void usage(char **argv) {

  printf("\tSQLDict %s by patrik.karlsson@ixsecurity.com\n", 
	 SQLTOOLS_VERSION);
  printf("\t------------------------------------------------\n");
  printf("\tusage: %s [options]\n\n", argv[0]);
  printf("\t\t-i* <ipfile> to probe\n");
  printf("\t\t-u* <userfile>\n");
  printf("\t\t-p* <dicfile>\n");
  printf("\t\t-r <reportfile>\n");
  printf("\t\t-v verbose\n\n");
  
}

void initArguments(ARGS *pArgs) {

  pArgs->pIPFile = NULL;
  pArgs->pUserFile = NULL;
  pArgs->pPassFile = NULL;
  pArgs->nLogLevel = 0;
  pArgs->pRepFile = NULL;
  
  memset(pArgs->sIP, 0, sizeof(pArgs->sIP));

}

int doHack(const ARGS *pArgs) {
  
  TDSLOGIN *login;
  TDSSOCKET *tds;  
  char user[64];
  char pass[64];
  char ip[16];

  /* Create report header */
  if ( pArgs->pRepFile != NULL ) {
    fprintf(pArgs->pRepFile, "SQLDict by Patrik Karlsson "
	    "<patrik.karlsson@ixsecurity.com>\n");
    fprintf(pArgs->pRepFile, "---------------------------"
	    "--------------------------------\n\n");
  }

  while ( getNextItem(pArgs->pIPFile, (char *)&ip, sizeof(ip) ) ) {

    while ( getNextItem(pArgs->pUserFile, (char *)&user, sizeof(user)) ) {

      while ( getNextItem(pArgs->pPassFile, (char *)&pass, sizeof(pass)) ) {

	if ( pArgs->nLogLevel > 0 )
	  fprintf(stdout, "Logging in with %s pw %s\n", user, pass);

	login = set_target_defaults(login);

	tds_set_server(login, ip);
	tds_set_passwd(login, pass);
        tds_set_user(login, user);
      
	if( (tds = tds_connect(login)) !=NULL ) {
	  fprintf(stdout, "IP: %-15s User: %-14s Pass: %-14s\n", 
		  ip, user, pass);
	  
	  if ( pArgs->pRepFile != NULL )
	    fprintf(pArgs->pRepFile, "IP: %-15s User: %-14s Pass: %-14s\n", 
		  ip, user, pass);

	  break;
	}

      free(login);

      } /* end pass loop */
      
      fseek(pArgs->pPassFile, 0L, SEEK_SET);

    } /* end user loop */
    
    fseek(pArgs->pUserFile, 0L, SEEK_SET);

  } /* end ip loop */

  return TRUE;

}

int main(int argc, char **argv) {

  ARGS args;
  int c = -1;

  initArguments(&args);

  while (1) {

    c = getopt (argc, argv, "i:u:p:vr:h");

    if ( c == -1 ) 
      break;

    switch (c) {

    case 'v':
      args.nLogLevel = 1;
      break;

    case 'h':
      usage(argv);
      exit(1);
      break;
      
    case 'i':

      if ( ( args.pIPFile = fopen(optarg, "r") ) == NULL ) {
	
	if ( strlen(optarg) <= sizeof(args.sIP) ) {
	  strncpy(args.sIP, optarg, strlen(optarg));
	}
	else {
	  usage(argv);
	  exit(1);
	}

      }

      break;

    case 'u':
      if ( ( args.pUserFile = fopen(optarg, "r") ) == NULL ) {
	fprintf(stderr, "ERROR: Opening user file\n");
	exit(1);
      }

      break;

    case 'p':
      if ( ( args.pPassFile = fopen(optarg, "r") ) == NULL ) {
	fprintf(stderr, "ERROR: Opening password file\n");
	exit(1);
      }

      break;

    case 'r':
      if ( ( args.pRepFile = fopen(optarg, "w") ) == NULL ) {
	fprintf(stderr, "ERROR: Creating report file\n");
	exit(1);
      }

      break;

    default:
      usage(argv);
      exit(1);
      break;
    }

  }

  
  if ( args.pIPFile == NULL || args.pUserFile == NULL || 
       args.pPassFile == NULL ) {
    usage(argv);
    exit(1);
  }

  return doHack(&args);

  fclose(args.pIPFile);
  fclose(args.pUserFile);
  fclose(args.pPassFile);

  if ( args.pRepFile != NULL )
    fclose(args.pRepFile);

  return TRUE;

}
