diff options
| author | Mattias Andrée <maandree@operamail.com> | 2013-11-23 22:05:21 +0100 | 
|---|---|---|
| committer | Mattias Andrée <maandree@operamail.com> | 2013-11-23 22:05:21 +0100 | 
| commit | b85a41caa489e780f361c4b8121d6e52160c0590 (patch) | |
| tree | 46418f66dfff2cadb423f9a0a701f6c8f2c86292 | |
| parent | m (diff) | |
| download | libpassphrase-b85a41caa489e780f361c4b8121d6e52160c0590.tar.gz libpassphrase-b85a41caa489e780f361c4b8121d6e52160c0590.tar.bz2 libpassphrase-b85a41caa489e780f361c4b8121d6e52160c0590.tar.xz | |
draft of PASSPHRASE_MOVE option implementation
Signed-off-by: Mattias Andrée <maandree@operamail.com>
Diffstat (limited to '')
| -rw-r--r-- | Makefile | 14 | ||||
| -rw-r--r-- | src/passphrase.c | 245 | 
2 files changed, 233 insertions, 26 deletions
| @@ -3,9 +3,17 @@ LIB = /lib  INCLUDE = /include  OPTIONS =  -# PASSPHRASE_ECHO:    Do not hide the passphrase -# PASSPHRASE_STAR:    Use '*' for each character instead of no echo -# PASSPHRASE_REALLOC: Soften security by using `realloc` +# PASSPHRASE_ECHO:      Do not hide the passphrase +# PASSPHRASE_STAR:      Use '*' for each character instead of no echo +# PASSPHRASE_REALLOC:   Soften security by using `realloc` +# PASSPHRASE_MOVE:      Enable move of point +# PASSPHRASE_INSERT:    Enable insert mode +# PASSPHRASE_OVERRIDE:  Enable override mode +# PASSPHRASE_DELETE:    Enable reversed erase command +# PASSPHRASE_CONTROL:   Enable use of control key combinations +# PASSPHRASE_DEDICATED: Enable use of dedicated keys +# DEFAULT_INSERT:       Use insert mode as default +# PASSPHRASE_INVALID:   Prevent duplication of non-initialised memory  OPTIMISE = -Os  CPPFLAGS = $(foreach D, $(OPTIONS), -D'$(D)=1') diff --git a/src/passphrase.c b/src/passphrase.c index 8ff4c56..751a77b 100644 --- a/src/passphrase.c +++ b/src/passphrase.c @@ -27,7 +27,7 @@  #define START_PASSPHRASE_LIMIT  32 -#ifndef PASSPHRASE_ECHO +#if !defined(PASSPHRASE_ECHO) || defined(PASSPHRASE_MOVE)  /**   * The original TTY settings   */ @@ -36,28 +36,43 @@ static struct termios saved_stty;  #ifndef PASSPHRASE_REALLOC -static inline char* xrealloc(char* array, size_t size) +static inline char* xrealloc(char* array, size_t cur_size, size_t new_size)  { -  char* rc = malloc(size); -  int i; +  char* rc = malloc(new_size * sizeof(char)); +  size_t i;    if (rc) -    for (i = 0; *(array + i); i++) -      { +    for (i = 0; i < cur_size; i++)  	*(rc + i) = *(array + i); -	*(array + i) = 0; -      } -  else -    for (i = 0; *(array + i); i++) -      *(array + i) = 0; +  for (i = 0; i < cur_size; i++) +    *(array + i) = 0;    free(array);    return rc;  }  #else -#define  xrealloc  realloc +#define xrealloc(array, _cur_size, new_size)  realloc(array, (new_size) * sizeof(char))  #endif -#define xprintf(...)  ({ printf(__VA_ARGS__); fflush(stdout); }) +#if defined(PASSPHRASE_MOVE) && !defined(PASSPHRASE_STAR) && !defined(PASSPHRASE_ECHO) +#  define xprintf(...)  /* do nothing */ +#  define xflush()      /* do nothing */ +#elif defined(PASSPHRASE_MOVE) || defined(PASSPHRASE_STAR) +#  define xprintf       printf +#  define xflush()      fflush(stdout) +#else +#  define xflush()      fflush(stdout) +#endif + + +#ifdef PASSPHRASE_MOVE +#  if defined(PASSPHRASE_STAR) +#    define xputchar(C)  ({ if ((c & 0xC0) != 0x80)  putchar('*'); }) +#  elif defined(PASSPHRASE_ECHO) +#    define xputchar(C)  putchar(C) +#  else +#    define xputchar(C)  /* be silent */ +#  endif +#endif  /** @@ -69,7 +84,18 @@ char* passphrase_read(void)  {    char* rc = malloc(START_PASSPHRASE_LIMIT * sizeof(char));    long size = START_PASSPHRASE_LIMIT; -  long len = 0; +  long len =  0; +#ifdef PASSPHRASE_MOVE +  long point = 0; +  long i = 0; +#  ifdef PASSPHRASE_OVERRIDE +#    if defined(PASSPHRASE_INSERT) && defined(DEFAULT_INSERT) +  char insert = 1; +#    elif defined(PASSPHRASE_INSERT) +  char insert = 0; +#    endif +#  endif +#endif    int c;    if (rc == NULL) @@ -85,28 +111,201 @@ char* passphrase_read(void)  	break;        if (c != 0)          { -#ifdef PASSPHRASE_STAR +#if defined(PASSPHRASE_MOVE) +	  /* \e[1~  \eOH  ^A  -1  home   */ +	  /* \e[2~            -2  insert */ +	  /* \e[3~  ^D        -3  delete */ +	  /* \e[4~  \eOF  ^E  -4  end    */ +	  /* \8     \127      -5  erase  */ +	  /* \e[C   ^F        -6  right  */ +	  /* \e[D   ^B        -7  left   */ +	  int cc = 0; +#ifdef PASSPHRASE_DEDICATED +	  if (c == '\033') +	    { +	      c = getchar(); +	      if (c == 'O') +		{ +		  c = getchar(); +		  if      (c == 'H')  cc = -1; +		  else if (c == 'F')  cc = -4; +		} +	      else if (c == '[') +		{ +		  c = getchar(); +		  if      (c == 'C')  cc = -6; +		  else if (c == 'D')  cc = -7; +		  else if (('1' <= c) && (c <= '4') && (getchar() == '~')) +		    cc = -(c - '0'); +		} +	    } +	  else +#endif +	    if ((c == 8) || (c == 127)) +	      cc = -5; +	    else if ((c < 0) || (c >= ' ')) +	      cc = ((int)c) & 255; +#ifdef PASSPHRASE_CONTROL +	    else if (c == 'A' - '@')  cc = -1; +	    else if (c == 'B' - '@')  cc = -7; +	    else if (c == 'D' - '@')  cc = -3; +	    else if (c == 'E' - '@')  cc = -4; +	    else if (c == 'F' - '@')  cc = -6; +#endif +	   +	  if (cc > 0) +	    { +	      c = (char)cc; +	      if (point == len) +		{ +		  xputchar(c); +		  *(rc + len++) = c; +		} +#ifdef PASSPHRASE_INSERT +	      else +#ifdef PASSPHRASE_OVERRIDE +		if (insert) +#endif +		  { +		    if ((c & 0xC0) != 0x80) +		      xprintf("\033[@"); +		    xputchar(c); +		    for (i = point; i < len; i++) +		      *(rc + i + 1) = *(rc + i); +		    len++; +		    *(rc + point++) = c; +		  } +#endif +#ifdef PASSPHRASE_OVERRIDE +		else +		  { +		    long n = 1; +		    char cn = c; +		    while (*(rc + point + n)) +		      n++; +		    for (i = point; i < len; i++) +		      *(rc + i) = *(rc + i + n); +		    for (i = len - n; i < len; i++) +		      *(rc + point + i) = 0; +		    len -= n; +		    n = 0; +		    while (cn & 0x80) +		      { +			cn <<= 1; +			n++; +		      } +		    n = n ?: 1; +		    if (len + n > size) +		      { +			if ((rc = xrealloc(rc, size, size << 1L)) == NULL) +			  return NULL; +			size <<= 1L; +		      } +		    for (i = point; i < len; i++) +		      *(rc + i + n) = *(rc + i); +		    len += n; +		    for (i = 0; i < n; i++) +		      { +			if (i) +			  c = getchar(); +			xputchar(c); +			*(rc + point++) = c; +		      } +		  } +#endif +	    } +	  else if ((cc == -1) && point) /* home */ +	    { +	      xprintf("\033[%liD", point); +	      point = 0; +	    } +#if defined(PASSPHRASE_INSERT) && defined(PASSPHRASE_OVERRIDE) +	  else if (cc == -2) /* insert */ +	    insert ^= 1; +#endif +#ifdef PASSPHRASE_DELETE +	  else if ((cc == -3) && (len != point)) /* delete */ +	    { +	      xprintf("\033[P"); +#ifdef PASSPHRASE_INVALID +	      *(rc + len) = 0; +#endif +	      do +		{ +		  for (i = point; i < len; i++) +		    *(rc + i) = *(rc + i + 1); +		  len--; +		} +	      while ((len != point) && ((*(rc + point) & 0xC0) == 0x80)); +	    } +#endif +	  else if ((cc == -4) && (len != point)) /* end */ +	    { +	      xprintf("\033[%liC", len - point); +	      point = len; +	    } +	  else if ((cc == -5) && point) /* erase */ +	    { +	      char redo = 1; +	      xprintf("\033[D\033[P"); +#ifdef PASSPHRASE_INVALID +	      *(rc + len) = 0; +#endif +	      while (redo) +		{ +		  redo = (*(rc + point) & 0xC0) == 0x80; +		  for (i = point; i <= len; i++) +		    *(rc + i - 1) = *(rc + i); +		  point--; +		  len--; +		} +	    } +	  else if ((cc == -6) && (len != point)) /* right */ +	    { +	      xprintf("\033[C"); +	      do +		point++; +	      while ((len != point) && ((*(rc + point) & 0xC0) == 0x80)); +	    } +	  else if ((cc == -7) && point) /* left */ +	    { +	      char redo = 1 +	      xprintf("\033[D"); +	      while (redo) +		redo = (*(rc + point--) & 0xC0) == 0x80; +	    } +	   +#elif defined(PASSPHRASE_STAR)  	  if ((c == 8) || (c == 127))  	    {  	      if (len == 0)  		continue;  	      xprintf("\033[D \033[D"); +	      xflush();  	      *(rc + --len) = 0;  	      continue;  	    } -	  putchar('*'); -#endif +	  if ((c & 0xC0) != 0x80) +	    putchar('*');  	  *(rc + len++) = c; +#else +	  *(rc + len++) = c; +#endif +	   +	  xflush();  	  if (len == size) -	    if ((rc = xrealloc(rc, (size <<= 1L) * sizeof(char))) == NULL) -	      return rc; +	    { +	      if ((rc = xrealloc(rc, size, size << 1L)) == NULL) +		return NULL; +	      size <<= 1L; +	    }  	}      }    /* NUL-terminate passphrase */    *(rc + len) = 0; -#ifndef PASSPHRASE_ECHO +#if !defined(PASSPHRASE_ECHO) || defined(PASSPHRASE_MOVE)    printf("\n");  #endif    return rc; @@ -118,13 +317,13 @@ char* passphrase_read(void)   */  void passphrase_disable_echo(void)  { -#ifndef PASSPHRASE_ECHO +#if !defined(PASSPHRASE_ECHO) || defined(PASSPHRASE_MOVE)    struct termios stty;    tcgetattr(STDIN_FILENO, &stty);    saved_stty = stty;    stty.c_lflag &= ~ECHO; -#ifdef PASSPHRASE_STAR +#if defined(PASSPHRASE_STAR) || defined(PASSPHRASE_MOVE)    stty.c_lflag &= ~ICANON;  #endif    tcsetattr(STDIN_FILENO, TCSAFLUSH, &stty); @@ -137,7 +336,7 @@ void passphrase_disable_echo(void)   */  void passphrase_reenable_echo(void)  { -#ifndef PASSPHRASE_ECHO +#if !defined(PASSPHRASE_ECHO) || defined(PASSPHRASE_MOVE)    tcsetattr(STDIN_FILENO, TCSAFLUSH, &saved_stty);  #endif  } | 
