Index: libabac/abac_util.c
===================================================================
--- libabac/abac_util.c	(revision 4b46680a90e4903fb5b827f0c0ea41e0a98c03d4)
+++ libabac/abac_util.c	(revision ba6027a0fac78c4a2e819aabd3ccc80779620acc)
@@ -11,4 +11,6 @@
 #include <stdarg.h>
 #include <sys/stat.h>
+#include <termios.h>
+#include <unistd.h>
 
 #include "abac_util.h"
@@ -16,10 +18,27 @@
 static int debug=0;
 
+/* Callback configuration */
+struct cb_opts {
+    bool use_prompt;    /* Print a prompt to stderr */
+    bool use_echo;      /* If true, turn off input echo on stdin */
+    unsigned int tries; /* Number of attempts allowed */
+    char prompt[20];    /* The prompt to display if use_echo is true */
+};
+
+
 #define SHA1_LENGTH 40
-#define ABAC_VERSION "0.2.1"
+#define ABAC_VERSION "0.2.2"
 
 char *abac_version()
 {
    return ABAC_VERSION;
+}
+
+void abac_clean_string(char *string)
+{
+   int len=strlen(string);
+   int i;
+   for(i=0;i<len;i++)
+       string[i]=0;
 }
 
@@ -248,2 +267,118 @@
 
 
+chunk_t abac_get_potato_file(char *filename)
+{
+   chunk_t pp=chunk_empty;
+   if(file_exist(filename)) {
+       if(debug) printf("trying to open %s\n", filename);
+       FILE *fp=fopen(filename,"r");
+       char str[PWLEN]; 
+       int rc=fscanf(fp,"%s",str);
+       if(rc) {
+           pp.ptr=abac_xstrdup(str); 
+           pp.len=strlen(pp.ptr);
+           if(str[pp.len-1]=='\n')
+               pp.len--;
+       }
+       abac_clean_string(str);
+       fclose(fp);
+   }
+   return pp;
+}
+
+/***
+***/
+chunk_t abac_get_potato_cb(int try, char *name) {
+    /* Get a password from stdin and return it as a chunk_t.  If too many tries
+     * have occurred or there is any other problem, return an empty chunk_t,
+     * which libstrongswan takes as giving up.  The chunk is alloated here
+     * (inside getline), and presumably freed by libstrongswan. User points to
+     * a cb_opts struct, which affects this routine in the obvious ways.
+     */
+    /* Configuration options */
+ 
+    if(name!=NULL) {
+        char *n=(char *)memrchr(name,'/',strlen(name));
+        if(n==NULL)
+            printf("[%s] ", name);
+            else printf("[%s] ",n);
+    }
+    struct cb_opts c_opts = { 1, 0, 3, "Key passphrase:" };
+    struct cb_opts *opts = &c_opts;
+    chunk_t rv = chunk_empty;   /* Return value, starts empty */
+
+    if (try -1 < opts->tries ) {
+        struct termios t;   /* Terminal settings */
+        size_t len = 0;     /* Length of string from getline */
+        tcflag_t orig = 0;  /* Holds the original local flags (echo in here) */
+
+        if (!opts->use_echo) {
+            /* Use tc{get,set}attr to turn echo off and restore the intial
+             * echo settings */
+            if (!tcgetattr(0, &t)) {
+                orig = t.c_lflag;
+
+                t.c_lflag &= ~ECHO;
+                if ( tcsetattr(0, TCSANOW, &t) ) {
+                    perror("Cannot turn off echo");
+                    return rv;
+                }
+            }
+            else {
+                perror("Cannot turn get attributes to off echo");
+                return rv;
+            }
+        }
+        if (opts->use_prompt) printf("%s", opts->prompt);
+
+        /* Because rv.ptr starts as NULL, getline allocates memory.  The size
+         * of the allocation returns in rv.len and the size of the string
+         * (including newline and NUL) is in len.  */
+        if ((rv.ptr = (u_char *) malloc(rv.len = PWLEN))) {
+            if ( fgets(rv.ptr, rv.len, stdin) ) {
+                /* Readjust the chunk_t's len field to the size of the string
+                 * w/o the newline or NUL */
+                /* would prefer strnlen, but no such luck in FBSD7 or earlier*/
+                size_t len = strlen(rv.ptr);
+
+                /* \n\0, \n or \0 */
+                if (rv.ptr[len-2] == '\n') rv.len = len-2;
+                   else if (rv.ptr[len-1] == '\n') rv.len = len-1;
+                     else rv.len = len -1;
+            } else {
+                /* Read failed.  Deallocate and clear rv */
+                free(rv.ptr);
+                rv = chunk_empty;
+            }
+        }
+        else {
+            /* Failed malloc.  Restore rv to empty and return it */
+            perror("malloc");
+            rv = chunk_empty;
+            return rv;
+        }
+
+        if (!opts->use_echo ) {
+            /* Pop echo beck to its original setting. */
+            t.c_lflag = orig;
+
+            if ( tcsetattr(0, TCSANOW, &t) )
+                perror("Cannot restore echo setting?");
+
+            if (opts->use_prompt) printf("\n");
+        }
+    }
+    else fprintf(stderr, "Too many tries (%d)", try-1);
+    return rv;
+}
+
+chunk_t extract_potato(char *filename, char *pfile)
+{
+    chunk_t pp;
+    if(pfile==NULL || strlen(pfile)==0 ) {
+      pp=abac_get_potato_cb(2,filename);
+      } else {
+        pp=abac_get_potato_file(pfile);
+    }
+    return pp;
+}
