/*
// 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 <syslog.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>

#include <security/pam_modules.h>
#include <security/pam_ext.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 reseved[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)
{
	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 char *key,
			 size_t keylen, const char *iv, size_t ivlen,
			 const char *inbytes, size_t inbyteslen, char *outbytes,
			 size_t *outbyteslen, char *mac, size_t *maclen)
{
	EVP_CIPHER_CTX *ctx;
	const EVP_MD *digest;
	size_t 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) {
		char calmac[EVP_MAX_MD_SIZE];
		size_t 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, *opwfilebuff = NULL, *opwptext = NULL;
	size_t opwptextlen = 0, opwfilesize = 0;
	metapassstruct *opwmp = NULL;

	char *pwptext = NULL, *pwctext = NULL;
	size_t pwctextlen = 0, pwptextlen = 0, maclen = 0;
	size_t writtensize = 0, keylen = 0;
	metapassstruct pwmp = {META_PASSWD_SIG, {0, 0}, .0, 0, 0, 0, 0};
	char mac[EVP_MAX_MD_SIZE] = {0};
	unsigned char key[EVP_MAX_KEY_LENGTH];
	char iv[EVP_CIPHER_iv_length(cipher)];
	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 succeded 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);

			// 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,
					    &opwmp->macsize)
				    != 0) {
					pam_syslog(pamh, LOG_DEBUG,
						   "Decryption failed");
					free(pwptext);
					free(opwptext);
					free(opwfilebuff);
					fclose(opwfile);
					fclose(pwfile);
					err = 1;
					goto done;
				}
			}

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

			linebuff = strtok(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(
						pwptext + writtensize,
						pwptextlen - writtensize,
						"%s:%s\n", forwho, towhat);
					wroteentry = 1;
				} else {
					writtensize += snprintf(
						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(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 genertion 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 */
