On Tue, 23. Aug 2005, 11:38:28 +0200, Simon Josefsson wrote:
> >> I'll try to fix getpass.  There is no reason for the tool to use mmap
> >> to read keys/certificates; a patch to fix this would be appreciated.
> >
> > The attached patch against src/cli.c uses only C89 functions. It works
> > for me. 
> 
> The patch look good!  To be able to use it, you'll have to assign
> copyright of your work to the FSF.  Is this OK with you?  I can send
> you the required form offline.

The copyright assignment process is started.

The patch unfortunately leaves '#include <sys/mman.h>' (line 30) in cli.c.
This line must be removed. A corrected patch is attached.

As a test, I changed gl/getpass.h and gl/getpass.c so that it compiles
on Win32 (and always returns NULL ;)
After that, a crossbuild with the Debian mingw32 package worked fine! So
a gnulib getpass module that works for MinGW is all that is missing for
a successful Win32 build.

I have one question, though: src/common.h defines socklen_t to int for
Win32. This is a redefinition since configure previously detected a
missing socklen_t and then defined it to be size_t in config.h.
I think the definition in src/common.h (line 11) should be removed, and
the configure script should always define socklen_t to int. The
'NOTE' section in the Linux connect(2) man page says that it was
historically an int, and Win32 and MacOS X still use int.

Last, I wrote a simple getpass() version for Win32 (attached). This
works completely different from the gnulib getpass module since 
- Windows has no /dev/tty concept
- Windows cannot switch terminal properties (AFAIK).
I have no idea how something like this could be properly integrated into
a gnulib module.

Regards,
Martin
--- cli.c.orig  2005-05-26 17:23:01.000000000 +0200
+++ cli.c       2005-08-23 22:06:55.902740000 +0200
@@ -27,7 +27,6 @@
 #include <sys/types.h>
 #include <string.h>
 #include <sys/time.h>
-#include <sys/mman.h>
 #include <sys/stat.h>
 #include <unistd.h>
 #include <fcntl.h>
@@ -124,35 +123,33 @@
 
 
 /* Helper functions to load a certificate and key
- * files into memory. They use mmap for simplicity.
+ * files into memory.
  */
-static gnutls_datum mmap_file(const char *file)
+static gnutls_datum load_file(const char *file)
 {
-    int fd;
-    gnutls_datum mmaped_file = { NULL, 0 };
-    struct stat stat_st;
+    FILE *f;
+    gnutls_datum loaded_file = { NULL, 0 };
+    long filelen;
     void *ptr;
 
-    fd = open(file, 0);
-    if (fd == -1)
-       return mmaped_file;
-
-    fstat(fd, &stat_st);
-
-    if ((ptr =
-        mmap(NULL, stat_st.st_size, PROT_READ, MAP_SHARED, fd,
-             0)) == MAP_FAILED)
-       return mmaped_file;
-
-    mmaped_file.data = ptr;
-    mmaped_file.size = stat_st.st_size;
-
-    return mmaped_file;
+    if (!(f = fopen(file, "r"))
+           || fseek(f, 0, SEEK_END) != 0 
+           || (filelen = ftell(f)) < 0 
+           || fseek(f, 0, SEEK_SET) != 0
+           || !(ptr = malloc((size_t)filelen))
+           || fread(ptr, 1, (size_t)filelen, f) < (size_t)filelen)
+    {
+       return loaded_file;
+    }
+    
+    loaded_file.data = ptr;
+    loaded_file.size = (unsigned int)filelen;
+    return loaded_file;
 }
 
-static void munmap_file(gnutls_datum data)
+static void unload_file(gnutls_datum data)
 {
-    munmap(data.data, data.size);
+    free(data.data);
 }
 
 #define MAX_CRT 6
@@ -172,7 +169,7 @@
     gnutls_datum data;
 
     if (x509_certfile != NULL && x509_keyfile != NULL) {
-       data = mmap_file(x509_certfile);
+       data = load_file(x509_certfile);
        if (data.data == NULL) {
            fprintf(stderr, "*** Error loading cert file.\n");
            exit(1);
@@ -196,9 +193,9 @@
        x509_crt_size = ret;
        /* fprintf(stderr, "Processed %d client certificates...\n", ret); */
 
-       munmap_file(data);
+       unload_file(data);
 
-       data = mmap_file(x509_keyfile);
+       data = load_file(x509_keyfile);
        if (data.data == NULL) {
            fprintf(stderr, "*** Error loading key file.\n");
            exit(1);
@@ -215,11 +212,11 @@
            exit(1);
        }
 
-       munmap_file(data);
+       unload_file(data);
     }
 #ifdef USE_OPENPGP
     if (pgp_certfile != NULL && pgp_keyfile != NULL) {
-       data = mmap_file(pgp_certfile);
+       data = load_file(pgp_certfile);
        if (data.data == NULL) {
            fprintf(stderr, "*** Error loading PGP cert file.\n");
            exit(1);
@@ -236,9 +233,9 @@
            exit(1);
        }
 
-       munmap_file(data);
+       unload_file(data);
 
-       data = mmap_file(x509_keyfile);
+       data = load_file(x509_keyfile);
        if (data.data == NULL) {
            fprintf(stderr, "*** Error loading PGP key file.\n");
            exit(1);
@@ -257,7 +254,7 @@
            exit(1);
        }
 
-       munmap_file(data);
+       unload_file(data);
     }
 #endif
 
#ifndef WIN32_GETPASS_H
#define WIN32_GETPASS_H

#define PASS_MAX 256

char *getpass(const char *prompt);

#endif
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>

#include "win32-getpass.h"

static char getpassbuf[PASS_MAX + 1];

char *getpass(const char *prompt)
{
    int c;
    int i = 0;
    
    memset(getpassbuf, sizeof(getpassbuf), 0);
    fputs(prompt, stderr);
    for (;;)
    {
	c = _getch();
	if (c == '\r')
	{
	    getpassbuf[i] = '\0';
	    break;
	}
	else if (i < PASS_MAX)
	{
	    getpassbuf[i++] = c;
	}
    }
    fputs("\r\n", stderr);

    return getpassbuf;
}

#ifdef TEST
int main(void)
{
    char *pw = getpass("Password: ");
    printf("Password is '%s'\n", pw);
    return 0;
}
#endif /* TEST */
_______________________________________________
Help-gnutls mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/help-gnutls

Reply via email to