/*
// Copyright (c) 2018 Intel Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
*/

#include <fcntl.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <syslog.h>
#include <unistd.h>

#include <security/pam_ext.h>
#include <security/pam_modules.h>
#include <security/pam_modutil.h>

#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <openssl/rand.h>

/*
 * This module is intended to save password of  special group user
 *
 */

#define MAX_SPEC_GRP_PASS_LENGTH 20
#define MAX_SPEC_GRP_USER_LENGTH 16
#define MAX_KEY_SIZE		 8
#define DEFAULT_SPEC_PASS_FILE	 "/etc/ipmi_pass"
#define META_PASSWD_SIG		 "=OPENBMC="

/*
 * Meta data struct for storing the encrypted password file
 * Note: Followed by this structure, the real data of hash, iv, encrypted data
 * with pad and mac are stored.
 * Decrypted data will hold user name & password for every new line with format
 * like <user name>:<password>\n
 */
typedef struct metapassstruct {
	char signature[10];
	unsigned char reserved[2];
	size_t hashsize;
	size_t ivsize;
	size_t datasize;
	size_t padsize;
	size_t macsize;
} metapassstruct;

/**
 * @brief to acquire lock for atomic operation
 * Internally uses lckpwdf to acquire the lock. Tries to acquire the lock
 * using lckpwdf() in interval of 1ms, with maximum of 100 attempts.
 *
 * @return PAM_SUCCESS for success / PAM_AUTHTOK_LOCK_BUSY for failure
 */
int lock_pwdf(void)
{
	int i;
	int retval;

	i = 0;
	while ((retval = lckpwdf()) != 0 && i < 100) {
		usleep(1000);
		i++;
	}
	if (retval != 0) {
		return PAM_AUTHTOK_LOCK_BUSY;
	}
	return PAM_SUCCESS;
}

/**
 * @brief unlock the acquired lock
 * Internally uses ulckpwdf to release the lock
 */
void unlock_pwdf(void)
{
	ulckpwdf();
}

/**
 * @brief to get argument value of option
 * Function to get the value of argument options.
 *
 * @param[in] pamh - pam handle
 * @param[in] option - argument option to which value has to returned
 * @param[in] argc - argument count
 * @param[in] argv - array of arguments
 */
static const char *get_option(const pam_handle_t *pamh, const char *option,
			      int argc, const char **argv)
{
	if (!pamh) {
		return NULL;
	}

	int i;
	size_t len;

	len = strlen(option);

	for (i = 0; i < argc; ++i) {
		if (strncmp(option, argv[i], len) == 0) {
			if (argv[i][len] == '=') {
				return &argv[i][len + 1];
			}
		}
	}
	return NULL;
}

/**
 * @brief encrypt or decrypt function
 * Function which will do the encryption or decryption of the data.
 *
 * @param[in] pamh - pam handle.
 * @param[in] isencrypt - encrypt or decrypt option.
 * @param[in] cipher - EVP_CIPHER to be used
 * @param[in] key - key which has to be used in EVP_CIPHER api's.
 * @param[in] keylen - Length of the key.
 * @param[in] iv - Initialization vector data, used along with key
 * @param[in] ivlen - Length of IV.
 * @param[in] inbytes - buffer which has to be encrypted or decrypted.
 * @param[in] inbyteslen - length of input buffer.
 * @param[in] outbytes - buffer to store decrypted or encrypted data.
 * @param[in] outbyteslen - length of output buffer
 * @param[in/out] mac - checksum to cross verify. Will be verified for decrypt
 * and returns for encrypt.
 * @param[in/out] maclen - length of checksum
 * @return - 0 for success -1 for failures.
 */
int encrypt_decrypt_data(const pam_handle_t *pamh, int isencrypt,
			 const EVP_CIPHER *cipher, const unsigned char *key,
			 int keylen, const unsigned char *iv, int ivlen,
			 const unsigned char *inbytes, size_t inbyteslen,
			 unsigned char *outbytes, size_t *outbyteslen,
			 unsigned char *mac, unsigned int *maclen)
{
	EVP_CIPHER_CTX *ctx;
	const EVP_MD *digest;
	int outEVPlen = 0;
	int retval = 0;
	size_t outlen = 0;

	if (cipher == NULL || key == NULL || iv == NULL || inbytes == NULL ||
	    outbytes == NULL || mac == NULL || inbyteslen == 0 ||
	    EVP_CIPHER_key_length(cipher) > keylen ||
	    EVP_CIPHER_iv_length(cipher) > ivlen) {
		pam_syslog(pamh, LOG_DEBUG, "Invalid inputs");
		return -1;
	}

	digest = EVP_sha256();
	if (!isencrypt) {
		unsigned char calmac[EVP_MAX_MD_SIZE];
		unsigned int calmaclen = 0;
		// calculate MAC for the encrypted message.
		if (NULL == HMAC(digest, key, keylen, inbytes, inbyteslen,
				 calmac, &calmaclen)) {
			pam_syslog(pamh, LOG_DEBUG,
				   "Failed to verify authentication %d",
				   retval);
			return -1;
		}
		if (!((calmaclen == *maclen) &&
		      (memcmp(calmac, mac, calmaclen) == 0))) {
			pam_syslog(pamh, LOG_DEBUG,
				   "Authenticated message doesn't match %d, %d",
				   calmaclen, *maclen);
			return -1;
		}
	}

	ctx = EVP_CIPHER_CTX_new();
	EVP_CIPHER_CTX_set_padding(ctx, 1);

	// Set key & IV
	retval = EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, isencrypt);
	if (!retval) {
		pam_syslog(pamh, LOG_DEBUG, "EVP_CipherInit_ex failed with %d",
			   retval);
		EVP_CIPHER_CTX_free(ctx);
		return -1;
	}
	if ((retval = EVP_CipherUpdate(ctx, outbytes + outlen, &outEVPlen,
				       inbytes, inbyteslen))) {
		outlen += outEVPlen;
		if ((retval = EVP_CipherFinal(ctx, outbytes + outlen,
					      &outEVPlen))) {
			outlen += outEVPlen;
			*outbyteslen = outlen;
		} else {
			pam_syslog(pamh, LOG_DEBUG,
				   "EVP_CipherFinal returns with %d", retval);
			EVP_CIPHER_CTX_free(ctx);
			return -1;
		}
	} else {
		pam_syslog(pamh, LOG_DEBUG, "EVP_CipherUpdate returns with %d",
			   retval);
		EVP_CIPHER_CTX_free(ctx);
		return -1;
	}
	EVP_CIPHER_CTX_free(ctx);

	if (isencrypt) {
		// Create MAC for the encrypted message.
		if (NULL == HMAC(digest, key, keylen, outbytes, *outbyteslen,
				 mac, maclen)) {
			pam_syslog(pamh, LOG_DEBUG,
				   "Failed to create authentication %d",
				   retval);
			return -1;
		}
	}
	return 0;
}

/**
 * @brief get temporary file handle
 * Function to get the temporary file handle, created using mkstemp
 *
 * @param[in] pamh - pam handle.
 * @param[in/out] tempfilename - tempfilename, which will be used in mkstemp.
 * @return - FILE handle for success. NULL for failure
 */
FILE *get_temp_file_handle(const pam_handle_t *pamh, char *const tempfilename)
{
	FILE *tempfile = NULL;
	int fd;
	int oldmask = umask(077);
	fd = mkstemp(tempfilename);
	if (fd == -1) {
		pam_syslog(pamh, LOG_DEBUG, "Error in creating temp file");
		umask(oldmask);
		return NULL;
	}
	pam_syslog(pamh, LOG_DEBUG, "Temporary file name is %s", tempfilename);

	tempfile = fdopen(fd, "w");
	umask(oldmask);
	return tempfile;
}

/**
 * @brief updates special password file
 * Function to update the special password file. Stores the password against
 * username in encrypted form along with meta data
 *
 * @param[in] pamh - pam handle.
 * @param[in] keyfilename - file name where key seed is stored.
 * @param[in] filename - special password file name
 * @param[in] forwho - name of the user
 * @param[in] towhat - password that has to stored in encrypted form
 * @return - PAM_SUCCESS for success or PAM_AUTHTOK_ERR for failure
 */
int update_pass_special_file(const pam_handle_t *pamh, const char *keyfilename,
			     const char *filename, const char *forwho,
			     const char *towhat)
{
	struct stat st;
	FILE *pwfile = NULL, *opwfile = NULL, *keyfile = NULL;
	int err = 0, wroteentry = 0;
	char tempfilename[1024];
	size_t forwholen = strlen(forwho);
	size_t towhatlen = strlen(towhat);
	char keybuff[MAX_KEY_SIZE] = { 0 };
	size_t keybuffsize = sizeof(keybuff);

	const EVP_CIPHER *cipher = EVP_aes_128_cbc();
	const EVP_MD *digest = EVP_sha256();

	char *linebuff = NULL;
	unsigned char *opwfilebuff = NULL;
	unsigned char *opwptext = NULL;
	size_t opwptextlen = 0, opwfilesize = 0;
	metapassstruct *opwmp = NULL;

	unsigned char *pwptext = NULL;
	unsigned char *pwctext = NULL;
	size_t pwctextlen = 0, pwptextlen = 0;
	unsigned int maclen = 0;
	size_t writtensize = 0;
	unsigned int keylen = 0;
	metapassstruct pwmp = { META_PASSWD_SIG, { 0, 0 }, .0, 0, 0, 0, 0 };
	unsigned char mac[EVP_MAX_MD_SIZE] = { 0 };
	unsigned char key[EVP_MAX_KEY_LENGTH];
	unsigned char iv[EVP_CIPHER_iv_length(cipher)];
	unsigned char hash[EVP_MD_block_size(digest)];

	// Following steps are performed in this function.
	// Step 1: Create a temporary file - always update temporary file, and
	// then swap it with original one, only if everything succeeded at the
	// end. Step 2: If file already exists, read the old file and decrypt it
	// in buffer Step 3: Copy user/password pair from old buffer to new
	// buffer, and update, if the user already exists with the new password
	// Step 4: Encrypt the new buffer and write it to the temp file created
	// at Step 1.
	// Step 5. rename the temporary file name as special password file.

	// verify the tempfilename buffer is enough to hold
	// filename_XXXXXX (+1 for null).
	if (strlen(filename) >
	    (sizeof(tempfilename) - strlen("__XXXXXX") - 1)) {
		pam_syslog(pamh, LOG_DEBUG, "Not enough buffer, bailing out");
		return PAM_AUTHTOK_ERR;
	}
	// Fetch the key from key file name.
	keyfile = fopen(keyfilename, "r");
	if (keyfile == NULL) {
		pam_syslog(pamh, LOG_DEBUG, "Unable to open key file %s",
			   keyfilename);
		return PAM_AUTHTOK_ERR;
	}
	if (fread(keybuff, 1, keybuffsize, keyfile) != keybuffsize) {
		pam_syslog(pamh, LOG_DEBUG, "Key file read failed");
		fclose(keyfile);
		return PAM_AUTHTOK_ERR;
	}
	fclose(keyfile);

	// Step 1: Try to create a temporary file, in which all the update will
	// happen then it will be renamed to the original file. This is done to
	// have atomic operation.
	snprintf(tempfilename, sizeof(tempfilename), "%s__XXXXXX", filename);
	pwfile = get_temp_file_handle(pamh, tempfilename);
	if (pwfile == NULL) {
		err = 1;
		goto done;
	}

	// Update temporary file stat by reading the special password file
	opwfile = fopen(filename, "r");
	if (opwfile != NULL) {
		if (fstat(fileno(opwfile), &st) == -1) {
			fclose(opwfile);
			fclose(pwfile);
			err = 1;
			goto done;
		}
	} else { // Create with this settings if file is not present.
		memset(&st, 0, sizeof(st));
	}
	// Override the file permission with S_IWUSR | S_IRUSR
	st.st_mode = S_IWUSR | S_IRUSR;
	if ((fchown(fileno(pwfile), st.st_uid, st.st_gid) == -1) ||
	    (fchmod(fileno(pwfile), st.st_mode) == -1)) {
		if (opwfile != NULL) {
			fclose(opwfile);
		}
		fclose(pwfile);
		err = 1;
		goto done;
	}
	opwfilesize = st.st_size;

	// Step 2: Read existing special password file and decrypt the data.
	if (opwfilesize) {
		opwfilebuff = malloc(opwfilesize);
		if (opwfilebuff == NULL) {
			fclose(opwfile);
			fclose(pwfile);
			err = 1;
			goto done;
		}

		if (fread(opwfilebuff, 1, opwfilesize, opwfile)) {
			opwmp = (metapassstruct *)opwfilebuff;
			opwptext = malloc(opwmp->datasize + opwmp->padsize);
			if (opwptext == NULL) {
				free(opwfilebuff);
				fclose(opwfile);
				fclose(pwfile);
				err = 1;
				goto done;
			}
			// User & password pairs are mapped as <user
			// name>:<password>\n. Add +3 for special chars ':',
			// '\n' and '\0'.
			pwptextlen = opwmp->datasize + forwholen + towhatlen +
				     3 + EVP_CIPHER_block_size(cipher);
			pwptext = malloc(pwptextlen);
			if (pwptext == NULL) {
				free(opwptext);
				free(opwfilebuff);
				fclose(opwfile);
				fclose(pwfile);
				err = 1;
				goto done;
			}

			// First get the hashed key to decrypt
			HMAC(digest, keybuff, keybuffsize,
			     opwfilebuff + sizeof(*opwmp), opwmp->hashsize, key,
			     &keylen);

			unsigned int tmpmacsize = opwmp->macsize;
			// Skip decryption if there is no data
			if (opwmp->datasize != 0) {
				// Do the decryption
				if (encrypt_decrypt_data(
					    pamh, 0, cipher, key, keylen,
					    opwfilebuff + sizeof(*opwmp) +
						    opwmp->hashsize,
					    opwmp->ivsize,
					    opwfilebuff + sizeof(*opwmp) +
						    opwmp->hashsize +
						    opwmp->ivsize,
					    opwmp->datasize + opwmp->padsize,
					    opwptext, &opwptextlen,
					    opwfilebuff + sizeof(*opwmp) +
						    opwmp->hashsize +
						    opwmp->ivsize +
						    opwmp->datasize +
						    opwmp->padsize,
					    &tmpmacsize) != 0) {
					pam_syslog(pamh, LOG_DEBUG,
						   "Decryption failed");
					free(pwptext);
					free(opwptext);
					free(opwfilebuff);
					fclose(opwfile);
					fclose(pwfile);
					err = 1;
					goto done;
				}
				opwmp->macsize = tmpmacsize;
			}

			// NULL terminate it, before using it in strtok().
			opwptext[opwmp->datasize] = '\0';

			linebuff = strtok((char *)opwptext, "\n");
			// Step 3: Copy the existing user/password pair
			// to the new buffer, and update the password if user
			// already exists.
			while (linebuff != NULL) {
				if ((!strncmp(linebuff, forwho, forwholen)) &&
				    (linebuff[forwholen] == ':')) {
					writtensize += snprintf(
						(char *)pwptext + writtensize,
						pwptextlen - writtensize,
						"%s:%s\n", forwho, towhat);
					wroteentry = 1;
				} else {
					writtensize += snprintf(
						(char *)pwptext + writtensize,
						pwptextlen - writtensize,
						"%s\n", linebuff);
				}
				linebuff = strtok(NULL, "\n");
			}
		}
		// Clear the old password related buffers here, as we are done
		// with it.
		free(opwfilebuff);
		free(opwptext);
	} else {
		pwptextlen = forwholen + towhatlen + 3 +
			     EVP_CIPHER_block_size(cipher);
		pwptext = malloc(pwptextlen);
		if (pwptext == NULL) {
			if (opwfile != NULL) {
				fclose(opwfile);
			}
			fclose(pwfile);
			err = 1;
			goto done;
		}
	}

	if (opwfile != NULL) {
		fclose(opwfile);
	}

	if (!wroteentry) {
		// Write the new user:password pair at the end.
		writtensize += snprintf((char *)pwptext + writtensize,
					pwptextlen - writtensize, "%s:%s\n",
					forwho, towhat);
	}
	pwptextlen = writtensize;

	// Step 4: Encrypt the data and write to the temporary file
	if (RAND_bytes(hash, EVP_MD_block_size(digest)) != 1) {
		pam_syslog(pamh, LOG_DEBUG,
			   "Hash generation failed, bailing out");
		free(pwptext);
		fclose(pwfile);
		err = 1;
		goto done;
	}

	// Generate hash key, which will be used for encryption.
	HMAC(digest, keybuff, keybuffsize, hash, EVP_MD_block_size(digest), key,
	     &keylen);
	// Generate IV values
	if (RAND_bytes(iv, EVP_CIPHER_iv_length(cipher)) != 1) {
		pam_syslog(pamh, LOG_DEBUG,
			   "IV generation failed, bailing out");
		free(pwptext);
		fclose(pwfile);
		err = 1;
		goto done;
	}

	// Buffer to store encrypted message.
	pwctext = malloc(pwptextlen + EVP_CIPHER_block_size(cipher));
	if (pwctext == NULL) {
		pam_syslog(pamh, LOG_DEBUG, "Ctext buffer failed, bailing out");
		free(pwptext);
		fclose(pwfile);
		err = 1;
		goto done;
	}

	// Do the encryption
	if (encrypt_decrypt_data(pamh, 1, cipher, key, keylen, iv,
				 EVP_CIPHER_iv_length(cipher), pwptext,
				 pwptextlen, pwctext, &pwctextlen, mac,
				 &maclen) != 0) {
		pam_syslog(pamh, LOG_DEBUG, "Encryption failed");
		free(pwctext);
		free(pwptext);
		fclose(pwfile);
		err = 1;
		goto done;
	}

	// Update the meta password structure.
	pwmp.hashsize = EVP_MD_block_size(digest);
	pwmp.ivsize = EVP_CIPHER_iv_length(cipher);
	pwmp.datasize = writtensize;
	pwmp.padsize = pwctextlen - writtensize;
	pwmp.macsize = maclen;

	// Write the meta password structure, followed by hash, iv, encrypted
	// data & mac.
	if (fwrite(&pwmp, 1, sizeof(pwmp), pwfile) != sizeof(pwmp)) {
		pam_syslog(pamh, LOG_DEBUG, "Error in writing meta data");
		err = 1;
	}
	if (fwrite(hash, 1, pwmp.hashsize, pwfile) != pwmp.hashsize) {
		pam_syslog(pamh, LOG_DEBUG, "Error in writing hash data");
		err = 1;
	}
	if (fwrite(iv, 1, pwmp.ivsize, pwfile) != pwmp.ivsize) {
		pam_syslog(pamh, LOG_DEBUG, "Error in writing IV data");
		err = 1;
	}
	if (fwrite(pwctext, 1, pwctextlen, pwfile) != pwctextlen) {
		pam_syslog(pamh, LOG_DEBUG, "Error in encrypted data");
		err = 1;
	}
	if (fwrite(mac, 1, maclen, pwfile) != maclen) {
		pam_syslog(pamh, LOG_DEBUG, "Error in writing MAC");
		err = 1;
	}

	free(pwctext);
	free(pwptext);

	if (fflush(pwfile) || fsync(fileno(pwfile))) {
		pam_syslog(
			pamh, LOG_DEBUG,
			"fflush or fsync error writing entries to special file: %s",
			tempfilename);
		err = 1;
	}

	if (fclose(pwfile)) {
		pam_syslog(pamh, LOG_DEBUG,
			   "fclose error writing entries to special file: %s",
			   tempfilename);
		err = 1;
	}

done:
	if (!err) {
		// Step 5: Rename the temporary file as special password file.
		if (!rename(tempfilename, filename)) {
			pam_syslog(pamh, LOG_DEBUG,
				   "password changed for %s in special file",
				   forwho);
		} else {
			err = 1;
		}
	}

	// Clear out the key buff.
	memset(keybuff, 0, keybuffsize);

	if (!err) {
		return PAM_SUCCESS;
	} else {
		unlink(tempfilename);
		return PAM_AUTHTOK_ERR;
	}
}

/* Password Management API's */

/**
 * @brief pam_sm_chauthtok API
 * Function which will be called for pam_chauthtok() calls.
 *
 * @param[in] pamh - pam handle
 * @param[in] flags - pam calls related flags
 * @param[in] argc - argument counts / options
 * @param[in] argv - array of arguments / options
 * @return - PAM_SUCCESS for success, others for failure
 */
int pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv)
{
	int retval = -1;
	const void *item = NULL;
	const char *user = NULL;
	const char *pass_new = NULL, *pass_old = NULL;
	const char *spec_grp_name =
		get_option(pamh, "spec_grp_name", argc, argv);
	const char *spec_pass_file =
		get_option(pamh, "spec_pass_file", argc, argv);
	const char *key_file = get_option(pamh, "key_file", argc, argv);

	if (spec_grp_name == NULL || key_file == NULL) {
		return PAM_IGNORE;
	}
	if (flags & PAM_PRELIM_CHECK) {
		// send success to verify other stacked modules prelim check.
		return PAM_SUCCESS;
	}

	retval = pam_get_user(pamh, &user, NULL);
	if (retval != PAM_SUCCESS) {
		return retval;
	}

	// get  already read password by the stacked pam module
	// Note: If there are no previous stacked pam module which read
	// the new password, then return with AUTHTOK_ERR

	retval = pam_get_item(pamh, PAM_AUTHTOK, &item);
	if (retval != PAM_SUCCESS || item == NULL) {
		return PAM_AUTHTOK_ERR;
	}
	pass_new = item;

	struct group *grp;
	int spec_grp_usr = 0;
	// Verify whether the user belongs to special group.
	grp = pam_modutil_getgrnam(pamh, spec_grp_name);
	if (grp != NULL) {
		while (*(grp->gr_mem) != NULL) {
			if (strcmp(user, *grp->gr_mem) == 0) {
				spec_grp_usr = 1;
				break;
			}
			(grp->gr_mem)++;
		}
	}

	pam_syslog(pamh, LOG_DEBUG, "User belongs to special grp: %x",
		   spec_grp_usr);

	if (spec_grp_usr) {
		// verify the new password is acceptable.
		size_t pass_len = strlen(pass_new);
		size_t user_len = strlen(user);
		if (pass_len > MAX_SPEC_GRP_PASS_LENGTH ||
		    user_len > MAX_SPEC_GRP_USER_LENGTH) {
			pam_syslog(pamh, LOG_ERR,
				   "Password length (%zu) / User name length "
				   "(%zu) is not acceptable for IPMI",
				   pass_len, user_len);
			pass_new = pass_old = NULL;
			return PAM_AUTHTOK_ERR;
		}
		if (spec_pass_file == NULL) {
			spec_pass_file = DEFAULT_SPEC_PASS_FILE;
			pam_syslog(
				pamh, LOG_ERR,
				"Using default special password file name :%s",
				spec_pass_file);
		}
		if ((retval = lock_pwdf())) {
			pam_syslog(pamh, LOG_ERR,
				   "Failed to lock the passwd file");
			return retval;
		}
		retval = update_pass_special_file(
			pamh, key_file, spec_pass_file, user, pass_new);
		unlock_pwdf();
		return retval;
	}

	return PAM_SUCCESS;
}

/* end of module definition */
