1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
--- src/bin/pg_passwd/pg_passwd.c.orig Sat Mar 24 01:54:55 2001
+++ src/bin/pg_passwd/pg_passwd.c Wed Apr 18 04:54:14 2001
@@ -7,6 +7,12 @@
#include <errno.h>
#include <time.h>
#include <ctype.h>
+
+#if defined(__FreeBSD__)
+#include <pwd.h> /* defines _PASSWORD_LEN, max # of characters in a password */
+#include <sys/time.h> /* gettimeofday for password salt */
+#endif
+
#define issaltchar(c) (isalnum((unsigned char) (c)) || (c) == '.' || (c) == '/')
#ifdef HAVE_TERMIOS_H
@@ -23,18 +29,31 @@
* We assume that the output of crypt(3) is always 13 characters,
* and that at most 8 characters can usefully be sent to it.
*
+ * For FreeBSD, take these values from /usr/include/pwd.h
* Postgres usernames are assumed to be less than NAMEDATALEN chars long.
*/
+#if defined(__FreeBSD__)
+#define CLEAR_PASSWD_LEN _PASSWORD_LEN
+#define CRYPTED_PASSWD_LEN _PASSWORD_LEN /* max length, not containing NULL */
+#define SALT_LEN 10
+#else
#define CLEAR_PASSWD_LEN 8 /* not including null */
#define CRYPTED_PASSWD_LEN 13 /* not including null */
+#define SALT_LEN 3
+#endif
+
+static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */
+ "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
const char *progname;
static void usage(void);
+static void to64(char *s, long v, int n);
static void read_pwd_file(char *filename);
static void write_pwd_file(char *filename, char *bkname);
static void encrypt_pwd(char key[CLEAR_PASSWD_LEN + 1],
- char salt[3],
+ char salt[SALT_LEN],
char passwd[CRYPTED_PASSWD_LEN + 1]);
static void prompt_for_username(char *username);
static void prompt_for_password(char *prompt, char *password);
@@ -47,6 +66,15 @@
printf("Report bugs to <pgsql-bugs@postgresql.org>.\n");
}
+static void
+to64(char *s, long v, int n)
+{
+ while (--n >= 0) {
+ *s++ = itoa64[v&0x3f];
+ v >>= 6;
+ }
+}
+
typedef struct
{
char *uname;
@@ -154,7 +182,7 @@
if (q != NULL)
*(q++) = '\0';
- if (strlen(p) != CRYPTED_PASSWD_LEN && strcmp(p, "+") != 0)
+ if (strlen(p) > CRYPTED_PASSWD_LEN && strcmp(p, "+") != 0)
{
fprintf(stderr, "%s:%d: warning: invalid password length\n",
filename, npwds + 1);
@@ -221,15 +249,25 @@
static void
encrypt_pwd(char key[CLEAR_PASSWD_LEN + 1],
- char salt[3],
+ char salt[SALT_LEN],
char passwd[CRYPTED_PASSWD_LEN + 1])
{
+#if !defined(__FreeBSD__)
int n;
-
+#endif
/* select a salt, if not already given */
if (salt[0] == '\0')
{
+#if defined(__FreeBSD__)
+ struct timeval tv;
+ srandomdev();
+ gettimeofday(&tv,0);
+ to64(&salt[0], random(), 3);
+ to64(&salt[3], tv.tv_usec, 3);
+ to64(&salt[6], tv.tv_sec, 2);
+ salt[8] = '\0';
srand(time(NULL));
+#else
do
{
n = rand() % 256;
@@ -241,6 +279,7 @@
} while (!issaltchar(n));
salt[1] = n;
salt[2] = '\0';
+#endif
}
/* get encrypted password */
@@ -335,7 +374,7 @@
char *filename;
char bkname[MAXPGPATH];
char username[NAMEDATALEN];
- char salt[3];
+ char salt[SALT_LEN];
char key[CLEAR_PASSWD_LEN + 1],
key2[CLEAR_PASSWD_LEN + 1];
char e_passwd[CRYPTED_PASSWD_LEN + 1];
|