#!/usr/bin/env python

# This file is part of Window-Switch.
# Copyright (c) 2009-2013 Antoine Martin <antoine@nagafix.co.uk>
# Window-Switch is released under the terms of the GNU GPL v3

import os

from winswitch.util.simple_logger import Logger, msig
from winswitch.util.file_io import get_authorized_keys_file
from winswitch.util.crypt_util import key_to_string
from winswitch.util.common import visible_command, hash_text
from winswitch.globals import WIN32

logger=Logger("auth.", log_colour=Logger.HIGHLIGHTED_BLUE)

PAM_SERVICE = 'passwd'
PAM_PASSWORD = "password"


def	is_key_present(username, public_key):
	key_str = key_to_string(public_key)
	if len(key_str)<32:
		return	False
	return	is_key_str_present(username, key_str)

def	is_key_str_present(username, key_str):
	sig = msig(username, visible_command(key_str))
	logger.debug(sig)
	if not username or len(username)==0:
		return	False
	if not WIN32:
		try:
			import pwd
			try:
				pdb = pwd.getpwnam(username)
				if not pdb:
					logger.debug(sig+" user does not exist in password database")
					return	False
			except Exception, e:
				logger.log(sig+" error getting password entry: %s" % e)
				return	False
		except:
			logger.debug(sig+" pwd module not available")
	keys = load_keys(username)
	present = keys and key_str in keys
	if present:
		logger.log(sig+" key found")
	else:
		filename = get_authorized_keys_file(username)
		logger.log(sig+" key is missing, to allow access, paste this key into %s"  % (filename))
	return present

def	load_keys(username):
	try:
		filename = get_authorized_keys_file(username)
	except Exception ,e:
		logger.serr(None, e, username)
		return	None
	logger.sdebug("filename=%s"  % filename, username)
	if not os.path.exists(filename):
		return	None
	inp = open (filename, "r")
	keys = []
	for line in inp.readlines():
		if line.startswith("#"):
			continue
		parts = line.split(" ")
		key_part = parts[0]
		if len(key_part)<32:
			logger.serror("found invalid (ignored) key in %s: %s"  % (filename, key_part), username)
			continue
		logger.sdebug("key=%s"  % key_part, username)
		keys.append(key_part)
	return	keys


def	add_key(username, public_key, info_name):
	key_str = key_to_string(public_key)
	if len(key_str)<32:
		logger.serror("invalid key - not stored", username, public_key, info_name)
		return
	add_key_str(username, key_str, info_name)

def	add_key_str(username, key_str, info_name):
	sig = msig(username, visible_command(key_str), info_name)
	if not check_key_str(key_str):
		logger.serror("invalid key!", username, key_str, info_name)
		return
	logger.log(sig)
	filename = get_authorized_keys_file(username)
	key_file = open (filename, "a")
	key_file.write("%s %s\n" % (key_str, info_name))
	key_file.close()

def check_key_str(key_str):
	"""
	Our keys are numbers, just do a simple check for now.
	"""
	if not key_str:
		return	False
	return	key_str.isdigit() and len(key_str)>64

def is_password_correct(module, username, password):
	sig = msig(module, username, hash_text(password))
	logger.log(sig)
	if module=="PAM":
		allowed = False
		try:
			from winswitch.util.password_checker import PasswordChecker
			pc = PasswordChecker(username, password)
			allowed = pc.check()
		except Exception, e:
			logger.error(sig+" python PAM module is missing or failed to load! cannot authenticate with password!", e)
			allowed = False
		logger.debug(sig+" allowed=%s" % allowed)
		return	allowed
	elif module=="KRB5":
		try:
			from kpass import kpass			#@UnresolvedImport
			KRB5_SERVICE = "login"
			rc = kpass(username, password, KRB5_SERVICE, None, None)
			return	rc==1
		except Exception, e:
			logger.error(sig+" kpass error! cannot authenticate with password!", e)
			return	False
		return pc.check()
	else:
		raise Exception("Invalid authentication module: %s" % module)
