2 * Copyright (C) 2005, 2007, 2008, 2009 Free Software Foundation
4 * This file is part of GNUTLS.
6 * GNUTLS is free software: you can redistribute it and/or modify
7 * it 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,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU 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 <http://www.gnu.org/licenses/>.
22 /* Gnulib portability files. */
23 #include <version-etc.h>
31 main (int argc
, char **argv
)
33 printf ("\nPSK not supported. This program is a dummy.\n\n");
42 #include <gnutls/gnutls.h>
43 #include <gnutls/extra.h>
46 #include "../lib/random.h" /* for random */
48 #include <sys/types.h>
58 /* Gnulib portability files. */
62 static int write_key (const char *username
, const char *key
, int key_size
,
65 #define KPASSWD "/etc/passwd.psk"
66 #define MAX_KEY_SIZE 64
68 main (int argc
, char **argv
)
73 unsigned char key
[MAX_KEY_SIZE
];
74 char hex_key
[MAX_KEY_SIZE
* 2 + 1];
76 size_t hex_key_size
= sizeof (hex_key
);
78 set_program_name (argv
[0]);
80 if ((ret
= gnutls_global_init ()) < 0)
82 fprintf (stderr
, "global_init: %s\n", gnutls_strerror (ret
));
88 if (gaa (argc
, argv
, &info
) != -1)
90 fprintf (stderr
, "Error in the arguments.\n");
94 if (info
.passwd
== NULL
)
95 info
.passwd
= (char*) KPASSWD
;
97 if (info
.username
== NULL
)
100 pwd
= getpwuid (getuid ());
104 fprintf (stderr
, "No such user\n");
108 info
.username
= pwd
->pw_name
;
110 fprintf (stderr
, "Please specify a user\n");
115 if (info
.key_size
> MAX_KEY_SIZE
)
117 fprintf (stderr
, "Key size is too long\n");
121 if (info
.netconf_hint
)
125 if (info
.key_size
!= 0 && info
.key_size
!= 20)
127 fprintf (stderr
, "For netconf, key size must always be 20.\n");
131 passwd
= getpass ("Enter password: ");
134 fprintf (stderr
, "Please specify a password\n");
138 ret
= gnutls_psk_netconf_derive_key (passwd
,
140 info
.netconf_hint
, &dkey
);
143 fprintf (stderr
, "Deriving the key failed\n");
149 if (info
.key_size
< 1)
152 printf ("Generating a random key for user '%s'\n", info
.username
);
154 ret
= _gnutls_rnd (GNUTLS_RND_RANDOM
, (char *) key
, info
.key_size
);
157 fprintf (stderr
, "Not enough randomness\n");
162 dkey
.size
= info
.key_size
;
165 ret
= gnutls_hex_encode (&dkey
, hex_key
, &hex_key_size
);
166 if (info
.netconf_hint
)
167 gnutls_free (dkey
.data
);
170 fprintf (stderr
, "HEX encoding error\n");
174 ret
= write_key (info
.username
, hex_key
, hex_key_size
, info
.passwd
);
176 printf ("Key stored to %s\n", info
.passwd
);
182 filecopy (char *src
, char *dst
)
188 fd
= fopen (dst
, "w");
191 fprintf (stderr
, "Cannot open '%s' for write\n", dst
);
195 fd2
= fopen (src
, "r");
203 line
[sizeof (line
) - 1] = 0;
206 p
= fgets (line
, sizeof (line
) - 1, fd2
);
221 write_key (const char *username
, const char *key
, int key_size
,
230 /* delete previous entry */
235 if (strlen (passwd_file
) > sizeof (tmpname
) + 5)
237 fprintf (stderr
, "file '%s' is tooooo long\n", passwd_file
);
240 strcpy (tmpname
, passwd_file
);
241 strcat (tmpname
, ".tmp");
243 if (stat (tmpname
, &st
) != -1)
245 fprintf (stderr
, "file '%s' is locked\n", tmpname
);
249 if (filecopy (passwd_file
, tmpname
) != 0)
251 fprintf (stderr
, "Cannot copy '%s' to '%s'\n", passwd_file
, tmpname
);
255 fd
= fopen (passwd_file
, "w");
258 fprintf (stderr
, "Cannot open '%s' for write\n", passwd_file
);
263 fd2
= fopen (tmpname
, "r");
266 fprintf (stderr
, "Cannot open '%s' for read\n", tmpname
);
274 p
= fgets (line
, sizeof (line
) - 1, fd2
);
278 pp
= strchr (line
, ':');
282 if (strncmp (p
, username
,
283 MAX (strlen (username
), (unsigned int) (pp
- p
))) == 0)
286 fprintf (fd
, "%s:%s\n", username
, key
);
297 fprintf (fd
, "%s:%s\n", username
, key
);
309 #endif /* ENABLE_PSK */
311 void psktool_version (void);
314 psktool_version (void)
316 const char *p
= PACKAGE_NAME
;
317 if (strcmp (gnutls_check_version (NULL
), PACKAGE_VERSION
) != 0)
319 version_etc (stdout
, "psktool", p
, gnutls_check_version (NULL
),
320 "Nikos Mavrogiannopoulos", (char *) NULL
);