Fix dangling/unused bindings in `(gnutls)'.
[gnutls.git] / src / psk.c
blob1602e6e146fc7fd0a47df426debcba5d04e82818
1 /*
2 * Copyright (C) 2005, 2007 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/>.
20 #include <config.h>
22 #define _MAX(x,y) (x>y?x:y)
24 #ifndef ENABLE_PSK
26 #include <stdio.h>
29 int
30 main (int argc, char **argv)
32 printf ("\nPSK not supported. This program is a dummy.\n\n");
33 return 1;
36 void
37 psktool_version (void)
39 fprintf (stderr, "GNU TLS dummy psktool.\n");
42 #else
44 #include <stdio.h>
45 #include <string.h>
46 #include <stdlib.h>
47 #include <gnutls/gnutls.h>
48 #include <gnutls/extra.h>
49 #include <psk-gaa.h>
51 #include <gc.h> /* for randomize */
53 #include <sys/types.h>
54 #include <sys/stat.h>
56 #ifndef _WIN32
57 # include <pwd.h>
58 # include <unistd.h>
59 #else
60 # include <windows.h>
61 #endif
63 static int write_key (const char *username, const char *key, int key_size,
64 char *passwd_file);
66 void
67 psktool_version (void)
69 const char *v = gnutls_check_version (NULL);
71 printf ("psktool (GnuTLS) %s\n", LIBGNUTLS_VERSION);
72 if (strcmp (v, LIBGNUTLS_VERSION) != 0)
73 printf ("libgnutls %s\n", v);
77 #define KPASSWD "/etc/passwd.psk"
78 #define MAX_KEY_SIZE 64
79 int
80 main (int argc, char **argv)
82 gaainfo info;
83 int ret;
84 struct passwd *pwd;
85 unsigned char key[MAX_KEY_SIZE];
86 char hex_key[MAX_KEY_SIZE * 2 + 1];
87 gnutls_datum_t dkey;
88 size_t hex_key_size = sizeof (hex_key);
90 if ((ret = gnutls_global_init ()) < 0)
92 fprintf (stderr, "global_init: %s\n", gnutls_strerror (ret));
93 exit (1);
96 #ifdef HAVE_UMASK
97 umask (066);
98 #endif
100 if (gaa (argc, argv, &info) != -1)
102 fprintf (stderr, "Error in the arguments.\n");
103 return -1;
106 if (info.passwd == NULL)
107 info.passwd = KPASSWD;
109 if (info.username == NULL)
111 #ifndef _WIN32
112 pwd = getpwuid (getuid ());
114 if (pwd == NULL)
116 fprintf (stderr, "No such user\n");
117 return -1;
120 info.username = pwd->pw_name;
121 #else
122 fprintf (stderr, "Please specify a user\n");
123 return -1;
124 #endif
127 if (info.key_size > MAX_KEY_SIZE)
129 fprintf (stderr, "Key size is too long\n");
130 exit (1);
133 if (info.key_size < 1)
134 info.key_size = 16;
136 ret = gc_pseudo_random ((char *) key, info.key_size);
137 if (ret != GC_OK)
139 fprintf (stderr, "Not enough randomness\n");
140 exit (1);
143 printf ("Generating a random key for user '%s'\n", info.username);
145 dkey.data = key;
146 dkey.size = info.key_size;
147 ret = gnutls_hex_encode (&dkey, hex_key, &hex_key_size);
148 if (ret < 0)
150 fprintf (stderr, "HEX encoding error\n");
151 exit (1);
154 ret = write_key (info.username, hex_key, hex_key_size, info.passwd);
155 if (ret == 0)
156 printf ("Key stored to %s\n", info.passwd);
158 return ret;
161 static int
162 filecopy (char *src, char *dst)
164 FILE *fd, *fd2;
165 char line[5 * 1024];
166 char *p;
168 fd = fopen (dst, "w");
169 if (fd == NULL)
171 fprintf (stderr, "Cannot open '%s' for write\n", dst);
172 return -1;
175 fd2 = fopen (src, "r");
176 if (fd2 == NULL)
178 /* empty file */
179 fclose (fd);
180 return 0;
183 line[sizeof (line) - 1] = 0;
186 p = fgets (line, sizeof (line) - 1, fd2);
187 if (p == NULL)
188 break;
190 fputs (line, fd);
192 while (1);
194 fclose (fd);
195 fclose (fd2);
197 return 0;
200 static int
201 write_key (const char *username, const char *key, int key_size,
202 char *passwd_file)
204 FILE *fd;
205 char line[5 * 1024];
206 char *p, *pp;
207 char tmpname[1024];
210 /* delete previous entry */
211 struct stat st;
212 FILE *fd2;
213 int put;
215 if (strlen (passwd_file) > sizeof (tmpname) + 5)
217 fprintf (stderr, "file '%s' is tooooo long\n", passwd_file);
218 return -1;
220 strcpy (tmpname, passwd_file);
221 strcat (tmpname, ".tmp");
223 if (stat (tmpname, &st) != -1)
225 fprintf (stderr, "file '%s' is locked\n", tmpname);
226 return -1;
229 if (filecopy (passwd_file, tmpname) != 0)
231 fprintf (stderr, "Cannot copy '%s' to '%s'\n", passwd_file, tmpname);
232 return -1;
235 fd = fopen (passwd_file, "w");
236 if (fd == NULL)
238 fprintf (stderr, "Cannot open '%s' for write\n", passwd_file);
239 remove (tmpname);
240 return -1;
243 fd2 = fopen (tmpname, "r");
244 if (fd2 == NULL)
246 fprintf (stderr, "Cannot open '%s' for read\n", tmpname);
247 remove (tmpname);
248 return -1;
251 put = 0;
254 p = fgets (line, sizeof (line) - 1, fd2);
255 if (p == NULL)
256 break;
258 pp = strchr (line, ':');
259 if (pp == NULL)
260 continue;
262 if (strncmp
263 (p, username,
264 _MAX (strlen (username), (unsigned int) (pp - p))) == 0)
266 put = 1;
267 fprintf (fd, "%s:%s\n", username, key);
269 else
271 fputs (line, fd);
274 while (1);
276 if (put == 0)
278 fprintf (fd, "%s:%s\n", username, key);
281 fclose (fd);
282 fclose (fd2);
284 remove (tmpname);
287 return 0;
290 #endif /* ENABLE_PSK */