2 * Copyright (C) 2005, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
4 * This file is part of GNUTLS.
6 * GNUTLS is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * GNUTLS is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see
18 * <http://www.gnu.org/licenses/>.
23 /* Gnulib portability files. */
24 #include <version-etc.h>
32 main (int argc
, char **argv
)
34 printf ("\nPSK not supported. This program is a dummy.\n\n");
43 #include <gnutls/gnutls.h>
44 #include <gnutls/extra.h>
47 #include "../lib/random.h" /* for random */
49 #include <sys/types.h>
59 /* Gnulib portability files. */
63 static int write_key (const char *username
, const char *key
, int key_size
,
66 #define KPASSWD "/etc/passwd.psk"
67 #define MAX_KEY_SIZE 64
69 main (int argc
, char **argv
)
74 unsigned char key
[MAX_KEY_SIZE
];
75 char hex_key
[MAX_KEY_SIZE
* 2 + 1];
77 size_t hex_key_size
= sizeof (hex_key
);
79 set_program_name (argv
[0]);
81 if ((ret
= gnutls_global_init ()) < 0)
83 fprintf (stderr
, "global_init: %s\n", gnutls_strerror (ret
));
89 if (gaa (argc
, argv
, &info
) != -1)
91 fprintf (stderr
, "Error in the arguments.\n");
95 if (info
.passwd
== NULL
)
96 info
.passwd
= (char *) KPASSWD
;
98 if (info
.username
== NULL
)
101 pwd
= getpwuid (getuid ());
105 fprintf (stderr
, "No such user\n");
109 info
.username
= pwd
->pw_name
;
111 fprintf (stderr
, "Please specify a user\n");
116 if (info
.key_size
> MAX_KEY_SIZE
)
118 fprintf (stderr
, "Key size is too long\n");
122 if (info
.netconf_hint
)
126 if (info
.key_size
!= 0 && info
.key_size
!= 20)
128 fprintf (stderr
, "For netconf, key size must always be 20.\n");
132 passwd
= getpass ("Enter password: ");
135 fprintf (stderr
, "Please specify a password\n");
139 ret
= gnutls_psk_netconf_derive_key (passwd
,
141 info
.netconf_hint
, &dkey
);
144 fprintf (stderr
, "Deriving the key failed\n");
150 if (info
.key_size
< 1)
153 printf ("Generating a random key for user '%s'\n", info
.username
);
155 ret
= _gnutls_rnd (GNUTLS_RND_RANDOM
, (char *) key
, info
.key_size
);
158 fprintf (stderr
, "Not enough randomness\n");
163 dkey
.size
= info
.key_size
;
166 ret
= gnutls_hex_encode (&dkey
, hex_key
, &hex_key_size
);
167 if (info
.netconf_hint
)
168 gnutls_free (dkey
.data
);
171 fprintf (stderr
, "HEX encoding error\n");
175 ret
= write_key (info
.username
, hex_key
, hex_key_size
, info
.passwd
);
177 printf ("Key stored to %s\n", info
.passwd
);
183 filecopy (char *src
, char *dst
)
189 fd
= fopen (dst
, "w");
192 fprintf (stderr
, "Cannot open '%s' for write\n", dst
);
196 fd2
= fopen (src
, "r");
204 line
[sizeof (line
) - 1] = 0;
207 p
= fgets (line
, sizeof (line
) - 1, fd2
);
222 write_key (const char *username
, const char *key
, int key_size
,
231 /* delete previous entry */
236 if (strlen (passwd_file
) > sizeof (tmpname
) + 5)
238 fprintf (stderr
, "file '%s' is tooooo long\n", passwd_file
);
241 strcpy (tmpname
, passwd_file
);
242 strcat (tmpname
, ".tmp");
244 if (stat (tmpname
, &st
) != -1)
246 fprintf (stderr
, "file '%s' is locked\n", tmpname
);
250 if (filecopy (passwd_file
, tmpname
) != 0)
252 fprintf (stderr
, "Cannot copy '%s' to '%s'\n", passwd_file
, tmpname
);
256 fd
= fopen (passwd_file
, "w");
259 fprintf (stderr
, "Cannot open '%s' for write\n", passwd_file
);
264 fd2
= fopen (tmpname
, "r");
267 fprintf (stderr
, "Cannot open '%s' for read\n", tmpname
);
275 p
= fgets (line
, sizeof (line
) - 1, fd2
);
279 pp
= strchr (line
, ':');
283 if (strncmp (p
, username
,
284 MAX (strlen (username
), (unsigned int) (pp
- p
))) == 0)
287 fprintf (fd
, "%s:%s\n", username
, key
);
298 fprintf (fd
, "%s:%s\n", username
, key
);
310 #endif /* ENABLE_PSK */
312 void psktool_version (void);
315 psktool_version (void)
317 const char *p
= PACKAGE_NAME
;
318 if (strcmp (gnutls_check_version (NULL
), PACKAGE_VERSION
) != 0)
320 version_etc (stdout
, "psktool", p
, gnutls_check_version (NULL
),
321 "Nikos Mavrogiannopoulos", (char *) NULL
);