Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * @mainpage Yep Utility.
- *
- * Software for encryption/decryption of private text data.\n
- * System requirements:
- * - Compiler: cc/gcc
- * - Compile options: -ansi -std=c99
- *
- * Copyright (c) 2012 valsorym <[email protected]>. All rights reserved.
- */
- #include <err.h>
- #include <math.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <stdarg.h>
- #include <termios.h>
- #include <sys/time.h>
- #include <unistd.h>
- /* DEFINES */
- /*---------------------------------------------------------------------------*/
- /**
- * @def DEFAULT_HOOKWORD
- * @brief Protection word by default. Use if not specified arguments
- * are \a ARGV_HOOKWORD.
- *
- * @def DEFAULT_TEMPDIR
- * @brief Directory for storing temporary files by default. Use if not
- * specified arguments are \a ARGV_TEMPDIR.
- */
- #define DEFAULT_HOOKWORD "howdy"
- #define DEFAULT_TEMPDIR "/tmp/yep"
- /**
- * @def MAXLEN_BUF
- * @brief The maximum length of text buffer. The buffer used to read lines
- * from a file, encode/decode strings.
- *
- * @def MAXLEN_PATH
- * @brief The maximum permissible length of the path to the file including
- * the file name.
- *
- * @def MAXLEN_SYSKEY
- * @brief Maximum length of keywords: passwords, hookword.
- *
- * @def MAXLEN_TEMPNAME
- * @brief The maximum permissible length of the temporary file name.
- */
- #define MAXLEN_BUF 4096
- #define MAXLEN_PATH 255
- #define MAXLEN_SYSKEY 15
- /* NEWTYPES */
- /*---------------------------------------------------------------------------*/
- /**
- * @enum bool
- * @brief Boolean data type. etc. \e c99 _Bool.
- */
- typedef enum {
- false=0, /**< True value. */
- true /**< False value. */
- } bool;
- /**
- * @enum cmethod
- * @brief Direction of encryption: encrypt, decrypt.
- */
- typedef enum {
- encode=1, /**< Encrypt a file. */
- decode=-1 /**< Decrypt a file. */
- } cmethod;
- /**
- * @enum cstatus
- * @brief The status of the encrypting/decrypting the file.
- */
- typedef enum {
- no_err=0, /**< Encryption/decryption is successful. */
- err_hookword=33, /**< Decrypted file can not be obtained because of
- * not correct password/hookword. */
- o_err_read, /**< Can not open for reading the original file. */
- t_err_read, /**< Can not open for reading the temp file. */
- o_err_write, /**< Can not open for writing the original file. */
- t_err_write, /**< Can not open for writing the temp file. */
- o_err_save, /**< Can not save the original file.
- * Error function fclose(). */
- t_err_save, /**< Can not save the temp file.
- * Error function fclose(). */
- o_err_create, /**< Can not create the original file.
- * Error function createyep(). */
- t_err_create, /**< Can not create the temp file.
- * Error function createyep(). */
- decode_problem, /**< Unable to decode the file. */
- encode_problem /**< Unable to encode the file. */
- } cstatus;
- /**
- * @enum maintype
- * @brief The way to open the file.
- */
- typedef enum {
- editfile, /**< The file is open to change/read. */
- changepass /**< The file is opened to change the password. */
- } maintype;
- /* SYSTEM FUNCTIONS */
- /*---------------------------------------------------------------------------*/
- extern char *geths(char [], int );
- extern char csymbol(const char , int );
- extern bool cstr(char [], int , const char *, const char *, cmethod );
- extern bool createyep(const char *, const char *, const char *);
- extern cstatus decodingfile(const char *, const char *,
- const char *, const char *);
- extern cstatus encodingfile(const char *, const char *,
- const char *, const char *);
- extern int terminal(const char *, ...);
- /* SCREEN FUNCTIONS */
- /*---------------------------------------------------------------------------*/
- extern void s_help(void);
- extern void s_main(const char *, const char *, const char *,
- const char *, maintype );
- /* VIRTUAL SCREEN FUNCTIONS */
- /*---------------------------------------------------------------------------*/
- extern void vs_newpass(char [], char [], const char *);
- /* MAIN */
- /*---------------------------------------------------------------------------*/
- /**
- * @brief Yep main function.
- *
- * @param argc Count of arguments passed.
- * @param argv The list of arguments.
- *
- * @return Returns zero on success of the program.
- */ //*
- int
- main(int argc, char **argv)
- {
- // `curopt` - found the argument.
- // `editor` - text editor software.
- // `tempdir` - store temporary files.
- // `hookword` - indicator for file recovery.
- // `optstr` - options:
- // -w: the argument to specify the protection word.
- // -d: the argument to specify a directory for storing temporary files.
- // -p: the argument to change the password on the specified file.
- // -h, -i: the list of arguments to display help information.
- int curopt = 0;
- char *editor = NULL,
- *tempdir = NULL,
- *hookword = NULL,
- *optstr = "w:d:p:h?";
- // Global variables `getopt` function (unistd.h):
- // `optarg` - pointer to the current argument, if any.
- // `optopt` - the last of the known parameters.
- // `optind` - The index of the next pointer argv, which will be processed
- // the next call to getopt().
- extern char *optarg;
- extern int optind;
- // The program requires access to the UNIX shell.
- if (!system(NULL))
- errx(1, "The UNIX shell is not available.\n");
- // Must be at least one external argument.
- if (argc < 2)
- errx(2, "See the help page on the program.\n");
- // Read the arguments list.
- while ((curopt = getopt(argc, argv, optstr)) != -1)
- switch (curopt) {
- case 'i':
- case 'h': // Show help screen.
- s_help();
- break;
- case 'w': // Read hookword.
- if (*optarg != '-')
- hookword = optarg;
- else
- errx(3, "Hookword parameter is not specified.\n");
- break;
- case 'd': // Read tempdir.
- if (*optarg != '-')
- tempdir = optarg;
- else
- errx(4, "Tempdir parameter is not specified.\n");
- break;
- case 'p': // Set new password on file.
- if (*optarg != '-')
- s_main(hookword, editor, optarg, tempdir, changepass);
- else
- errx(5, "Don't specify a file for change the password.\n");
- break;
- default: break;
- } // end switch ().
- // Recent arguments <EDITOR> <FILE>.
- if (argc - optind == 2) {
- // ... hookword, editor, file, tempdir, editfile);
- s_main(hookword, argv[argc - 2], argv[argc - 1], tempdir, editfile);
- } else
- errx(6, "Wrong number of arguments.\n");
- return 0;
- } // end main(). */
- /* SYSTEM FUNCTIONS */
- /*---------------------------------------------------------------------------*/
- /**
- * @brief Read from standard input hidden line.
- *
- * @param buf The buffer where written to a string from stdin.
- * @param bufsize The size of the buffer.
- *
- * @return Returns a pointer to the line of input that is placed in the
- * buffer \a buf.
- */ //*
- char
- *geths(char buf[], int bufsize)
- {
- int ch,
- i = 0,
- max = bufsize - 1;
- struct
- termios term,
- oldterm;
- // Do not display the characters as you type.
- tcgetattr(0, &term);
- oldterm = term;
- term.c_lflag &= ~ECHO; // Does not display the characters.
- term.c_lflag &= ~ICANON; // Do not expect the press enter.
- tcsetattr(0, TCSANOW, &term);
- // Read the hidden characters.
- while ((ch = getchar()) != EOF && ch != '\n')
- if (ch == 127 || ch == 8 || ch == '\b') {
- if (i > 0) i--;
- } else if (i < max)
- buf[i++] = ch;
- buf[i++] = '\0';
- // Restore the old display options.
- term = oldterm;
- tcsetattr(0, TCSANOW, &term);
- return buf;
- } // end geths(). */
- /**
- * @brief Encode a character offset.
- *
- * @param ch The symbol to encode.
- * @param seek The shift to encode.
- *
- * @return Returns the encoded (If \a seek variable > = 0)/decoded (If
- * \a seek variable <0) symbol. If symbol failed to encode/decode, returns the
- * character \a ch variable .
- *
- * @see cstr().
- */ //*
- char
- csymbol(const char ch, int seek)
- {
- char result = ch;
- char *alphabet = "QWERTYUIOPASDFGHJKLZXCVBNM"
- "qwertyuiopasdfghjklzxcvbnm"
- "1234567890 !@#$%^&*()_-+{}:";
- int alphsize = strlen(alphabet);
- // Determine the symbol.
- for (int i=0; i < alphsize; ++i)
- if (ch == *(alphabet + i)) {
- seek += i;
- while (seek >= alphsize)
- seek -= alphsize;
- while (seek < 0)
- seek += alphsize;
- if (seek >= 0 && seek < alphsize)
- result = *(alphabet + seek);
- break;
- } // end if ().
- return result;
- } // end csymbol(). */
- /**
- * @brief Cryptography string.
- *
- * @param buf Encoded string is placed in the buffer.
- * @param bufsize The size of the buffer.
- * @param str The string to encode.
- * @param pass Password to encrypt the string.
- * @param method Method: encode/decode.
- *
- * @return
- * - true - If the string \a str has been successfully encoded/decoded
- * and placed in buffer \a buf.
- * - false - If you encode/decode the string is impossible.
- *
- * @see csymbol().
- */ //*
- bool
- cstr(char buf[], int bufsize, const char *str, const char *pass,
- cmethod method)
- {
- int len = strlen(pass),
- seek = 0;
- // Determine the offset.
- for (int i = 0; i < len; ++i)
- seek = seek + ((int)*(pass + i)) * i;
- buf[0] = '\0';
- // Can I put the original in the buffer?
- // Determine the count of processed symbols.
- len = strlen(str);
- if (len > bufsize - 1)
- return false;
- // encode || decode str.
- for (int i = 0; i < len; ++i)
- buf[i] = csymbol(*(str+i), (seek + i) * method);
- buf[len] = '\0';
- return true;
- } // end cstr(). */
- /**
- * @brief Creates an empty yep-file recording it encoded a keyword (hookword).
- *
- * @param hookword Word of the key.
- * @param pass Password.
- * @param file The file to be created.
- *
- * @return
- * - true - If the file is successfully created.
- * - false - An error occurred while creating the file.
- */ //*
- bool
- createyep(const char *hookword, const char *pass,
- const char *file)
- {
- FILE *f_file;
- char buf[MAXLEN_BUF];
- bool result = false;
- if (!(f_file = fopen(file, "w")))
- return false;
- // Write a hookword in new yepfile.
- if (cstr(buf, MAXLEN_BUF - 1, hookword, pass, encode)) {
- strncat(buf, "\n", MAXLEN_BUF);
- fputs(buf, f_file);
- result = true;
- } // end if ().
- if(fclose(f_file))
- return false;
- return result;
- } // end createyep(). */
- /**
- * @brief Вуcode file.
- *
- * @param hookword Word of the key.
- * @param pass Password.
- * @param file File for decoding.
- * @param tempfile The temporary file.
- *
- * @return
- * - no_err - If the operation is executed without error.
- * - o_err_read - Can not open file \a file for reading.
- * - t_err_write - Can not open file \a tempfile for writing.
- * - err_hookword - Wrong password or secret word.
- * - o_err_save - Unable to save file \a file.
- * - t_err_save - Unable to save file \a tempfile.
- * - decode_problem - Unable to decode the file \a file.
- *
- * @see encodingfile().
- */ //*
- cstatus
- decodingfile(const char *hookword, const char *pass, const char *file,
- const char *tempfile)
- {
- FILE *f_file, *f_tempfile;
- char buf[MAXLEN_BUF],
- str[MAXLEN_BUF];
- bool hw_tested = false,
- result = no_err;
- if (!(f_file = fopen(file, "r")))
- return o_err_read;
- if (!(f_tempfile = fopen(tempfile, "w"))) {
- fclose(f_file);
- return t_err_write;
- } // end if ().
- // Encoding file.
- while(!feof(f_file)) {
- if (!hw_tested) {
- // Read hookword.
- hw_tested = true;
- if(fgets(buf, MAXLEN_BUF, f_file)) {
- buf[strlen(buf) - 1] = '\0'; // Remove "\n" symbol.
- if (!cstr(str, MAXLEN_BUF, buf, pass, decode))
- return decode_problem;
- if (strcmp(str, hookword)) {
- result = err_hookword;
- break;
- } // end if ().
- } else {
- result = err_hookword;
- break;
- }
- } else {
- // Read body.
- if(fgets(buf, MAXLEN_BUF, f_file)) {
- if (cstr(str, MAXLEN_BUF, buf, pass, decode))
- fputs(str, f_tempfile);
- else
- return decode_problem;
- } // end if ().
- } // end if ().
- } // end while ().
- if(fclose(f_file)) {
- fclose(f_tempfile);
- return o_err_save;
- } // end if ().
- if(fclose(f_tempfile))
- return t_err_save;
- return result;
- } // end decodingfile(). */
- /**
- * @brief Encode file.
- *
- * @param hookword Word of the key.
- * @param pass Password.
- * @param file File for decoding.
- * @param tempfile The temporary file.
- *
- * @return
- * - no_err - If the operation is executed without error.
- * - o_err_create - If the function createyep() caused the error,
- * etc. can not create file \a file.
- * - o_err_write - Can not open file for writing \a file.
- * - t_err_read - Can not open file for reading \a tempfile.
- * - o_err_save - Unable to close file \a file.
- * - t_err_save - Unable to close file \a tempfile.
- * - encode_problem - Unable to encode the file \a tempfile.
- *
- * @see decodingfile().
- */ //*
- cstatus
- encodingfile(const char *hookword, const char *pass, const char *file,
- const char *tempfile)
- {
- FILE *f_file,
- *f_tempfile;
- char buf[MAXLEN_BUF],
- str[MAXLEN_BUF];
- bool result = no_err;
- if (!createyep(hookword, pass, file))
- return o_err_create;
- if (!(f_file = fopen(file, "a")))
- return o_err_write;
- if (!(f_tempfile = fopen(tempfile, "r"))) {
- fclose(f_file);
- return t_err_read;
- } // end if ().
- // Decoding file.
- while(!feof(f_tempfile)) {
- // Write body.
- if(fgets(buf, MAXLEN_BUF, f_tempfile)) {
- if (cstr(str, MAXLEN_BUF, buf, pass, encode))
- fputs(str, f_file);
- else
- return encode_problem;
- } // end if ().
- } // end while ().
- if(fclose(f_file)) {
- fclose(f_tempfile);
- return o_err_save;
- } // end if ();
- if(fclose(f_tempfile))
- return t_err_save;
- return result;
- } // end encodingfile(). */
- /**
- * @brief Executing shell commands.
- *
- * @detailed This function takes cover those arguments as printf() function
- * from the C standard library.
- *
- * @param format Command for the terminal.
- * @param ... Formatting options.
- *
- * @return Returns integer - the result of a shell command.
- */ //*
- int
- terminal(const char *format, ...)
- {
- va_list ptr;
- char buf[MAXLEN_BUF];
- va_start(ptr, format);
- vsnprintf(buf, MAXLEN_BUF, format, ptr);
- va_end(ptr);
- return system(buf);
- } // end terminal(). */
- /* SCREEN FUNCTIONS */
- /*---------------------------------------------------------------------------*/
- /**
- * @brief Show help page.
- *
- * @return No data is returned.
- */ //*
- void
- s_help(void)
- {
- puts("\nNAME\n"
- "\tyep - encrypted text files.\n\n"
- "SYNOPSIS\n"
- "\tyep [-w hookword] [-d tempdir] editor file\n"
- "\tyep [-h | -i]\n"
- "\tyep [-w hookword] [-d tempdir] -p file\n\n"
- "DESCRIPTION\n"
- "\tyep program allows you to encrypt text files using the "
- "public key.\n\n"
- "OPTIONS\n"
- "\t-w hookword\n"
- "\t\tEstablishes additional protection for the word file. This \n"
- "\t\tword should be that you could safely recover an encrypted \n"
- "\t\tfile. If the word is not specified - the word will be used \n"
- "\t\tby default.\n"
- "\t-p file\n"
- "\t\tThe flag allows you to change the previously set password,\n"
- "\t\tand the protection word (hookword).\n"
- "\t-d tempdir\n"
- "\t\tSets the directory for storing temporary files.\n"
- "\t-h, -i\n"
- "\t\tDisplay help information about the program.\n"
- "\teditor\n"
- "\t\tSpecify a text editor synchronous: vi, vim, ee ... Use \n"
- "\t\tasynchronous editors (geany &, emacs & ...) - is impossible.\n"
- "\tfile\n"
- "\t\tThe file to be encrypted / decrypted. If the file does not \n"
- "\t\texist - it is created.\n\n"
- "BUGS\n"
- "\tEmail bug reports to [email protected]. Be sure to include \n"
- "\tthe word \"yep bugs\" somewhere in the \"Subject:\" field.\n");
- exit(0);
- } // end help(). */
- /**
- * @brief The main function of encoding, decoding, and change the
- * password on file.
- *
- * @param hookword Secret word.
- * @param editor Synchronous text editor.
- * @param file File manipulation.
- * @param tempdir The directory for storing temporary files.
- * @param type The method of handling file: encoding/decoding or change
- * your password.
- *
- * @return No data is returned.
- */ //*
- void
- s_main(const char *hookword, const char *editor, const char *file,
- const char *tempdir, maintype type)
- {
- char newhookword[MAXLEN_SYSKEY],
- passagain[MAXLEN_SYSKEY],
- pass[MAXLEN_SYSKEY];
- bool existfile = false,
- existeditor = false;
- char tempname[] = "XXXXXXX",
- tempfile[MAXLEN_PATH];
- // int len = 0;
- // Standard data.
- if (!hookword)
- hookword = DEFAULT_HOOKWORD;
- if (!tempdir)
- tempdir = DEFAULT_TEMPDIR;
- // Create a YEP temporary directory.
- if (terminal("ls -l -d %s | grep ^d", tempdir))
- if (terminal("mkdir -p %s", tempdir))
- errx(7, "Can not create a directory for storing "
- "temporary files.\n");
- // Create a random filename for a temporary file.
- if (strlen(tempdir) + strlen(tempname) >= MAXLEN_PATH)
- errx(8, "A very long name for a temporary file.\n");
- snprintf(tempfile, MAXLEN_PATH, "%s/%s", tempdir, tempname);
- if (mkstemp(tempfile) == -1)
- errx(9, "There exists a directory with that name: %s.\n", file);
- // Check for the file.
- if (!(existfile = !terminal("ls -l -d %s | grep ^-", file)))
- if (!terminal("ls -l -d %s | grep ^d", file)) {
- // There exists a directory with that name: filename.
- terminal("clear");
- errx(10, "There exists a directory with that name: %s.\n", file);
- } // end if ().
- // Checking the editor.
- existeditor = !terminal("which %s", editor);
- terminal("clear");
- // Create interface.
- printf("This will open the file with the following parameters:\n");
- printf(" Filename%s:\t%s\n",
- (existfile ? "" : " (file not exist)"), file);
- if (type == editfile)
- printf(" Editor%s:\t%s\n",
- (existeditor ? "" : " (editor is not installed)"), editor);
- printf(" Hookword%s:\t%s\n\n", (!strcmp(DEFAULT_HOOKWORD, hookword) ?
- " (default word protection)" : ""), hookword);
- if (type == editfile) {
- // Just open file.
- if (!existeditor)
- errx(11, "Editor is not installed: %s.\n", editor);
- } else if (type == changepass) {
- // Change password.
- if (!existfile)
- errx(12, "Сan not change the password on this file: %s.\n", file);
- } else
- // Bad type parameter.
- errx(13, "Is not valid action.\n");
- // end if ().
- // Read the password.
- printf("\nTo exit, press Ctrl+C.\n");
- while (true) {
- printf("\nPassword: ");
- geths(pass, MAXLEN_SYSKEY);
- if (!existfile) {
- printf("\nEnter password again: ");
- geths(passagain, MAXLEN_SYSKEY);
- if (strcmp(pass, passagain))
- printf("\nPasswords do not match. Please, enter again.\n");
- else {
- // Need create file.
- if (!createyep(hookword, pass, file))
- errx(14, "The file can not be created: %s.\n", file);
- break;
- }
- } else
- break;
- // end if ().
- } // end while ().
- printf("\n");
- // Decoding.
- switch ((int)decodingfile(hookword, pass, file, tempfile)) {
- case o_err_read:
- errx(o_err_read, "Can not open file: %s.\n", file);
- break;
- case t_err_write:
- errx(t_err_write, "Unable to open temporary file for "
- "writing: %s.\n", tempfile);
- break;
- case err_hookword:
- errx(err_hookword, "Hookword was not recognized.\n");
- break;
- case o_err_save:
- errx(o_err_save, "Unable to close file: %s.\n", file);
- break;
- case t_err_save:
- errx(t_err_save, "Unable to close file: %s.\n", tempfile);
- break;
- case decode_problem:
- errx(decode_problem, "Unable to decode the file: %s.\n", file);
- break;
- default: break;
- } // end switch ().
- // Open the file: read/write or change the password.
- if (type == editfile) {
- // Open editor.
- if (terminal("%s %s", editor, tempfile))
- errx(15, "Can not open file: %s.\n", tempfile);
- } else if (type == changepass) {
- // Change password.
- snprintf(newhookword, MAXLEN_SYSKEY, "%s", hookword);
- vs_newpass(newhookword, pass, file);
- hookword = newhookword;
- } // end if ().
- // Encoding again.
- switch ((int)encodingfile(hookword, pass, file, tempfile)) {
- case o_err_create:
- errx(o_err_create, "Can not create file: %s.\n", file);
- break;
- case o_err_write:
- errx(o_err_write, "Unable to write data to file: %s.\n", file);
- break;
- case t_err_read:
- errx(t_err_read, "Unable to read data from the "
- "temfile: %s.\n", tempfile);
- break;
- case o_err_save:
- errx(o_err_save, "Can not save the file: %s.\n", file);
- break;
- case t_err_save:
- errx(t_err_save, "Can not save the file: %s.\n", tempfile);
- break;
- case encode_problem:
- errx(encode_problem, "Unable to encode the file: %s.\n", tempfile);
- break;
- default: break;
- } // end switch ().
- if (terminal("rm -f -P %s", tempfile))
- printf("\nThe temporary file was not deleted: %s.\n", tempfile);
- exit(0);
- } // end s_main(). */
- /**
- * @brief Function-interface to change password.
- *
- * @param hookword Buffer storage keyword.
- * @param pass Buffer storage password.
- * @param file The file to change the password.
- *
- * @return No data is returned.
- */ //*
- void
- vs_newpass(char hookword[], char pass[], const char *file)
- {
- char passagain[MAXLEN_SYSKEY],
- passcode[MAXLEN_SYSKEY],
- cmd;
- int i;
- // Go-go-go!!!
- while (true) {
- for (i = 0; i < strlen(passagain); ++i)
- passcode[i] = '*';
- passcode[i + 1] = '\0';
- terminal("clear");
- printf("You are trying to change the system "
- "data to a file: %s.\n", file);
- printf("Choose one of the actions:\n");
- printf(" 1. Change password (%s).\n", passcode);
- printf(" 2. Change hookword (%s).\n", hookword);
- printf(" 3. Save and exit.");
- printf("\nTo exit, press Ctrl+C.\n");
- printf("\nYour choice: ");
- scanf("%c", &cmd);
- while (getchar() != '\n'); // Clear stdin buffer. Bad method. :(
- if (cmd == '1') {
- // Change password.
- while (true) {
- printf("\nEnter new password: ");
- geths(pass, MAXLEN_SYSKEY);
- printf("\nEnter password again: ");
- geths(passagain, MAXLEN_SYSKEY);
- if (strcmp(pass, passagain))
- printf("\nPasswords do not match. Please, enter again.\n");
- else
- break;
- } // end while ().
- } else if (cmd == '2') {
- // Change hookword.
- char hwformat[15];
- snprintf(hwformat, MAXLEN_SYSKEY, "%%%ds", MAXLEN_SYSKEY-1);
- printf("\nEnter new hookword: ");
- scanf(hwformat, hookword);
- while (getchar() != '\n'); // Clear stdin buffer. Bad method. :(
- } else if (cmd == '3') {
- // Save and exit;
- terminal("clear");
- printf("\nThe changes take effect.\n");
- return;
- } // end if ().
- } // end while ().
- exit(0);
- } // end vs_newpass(). */
- /* The End. */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement