]>
Commit | Line | Data |
---|---|---|
b04d69d3 SD |
1 | /* |
2 | * Copyright (c) 2004 MontaVista Software, Inc. | |
e476a63e | 3 | * Copyright (c) 2005-2011 Red Hat, Inc. |
b04d69d3 SD |
4 | * |
5 | * All rights reserved. | |
6 | * | |
46b01638 | 7 | * Author: Steven Dake (sdake@redhat.com) |
b04d69d3 SD |
8 | * |
9 | * This software licensed under BSD license, the text of which follows: | |
f2ceecc7 | 10 | * |
b04d69d3 SD |
11 | * Redistribution and use in source and binary forms, with or without |
12 | * modification, are permitted provided that the following conditions are met: | |
13 | * | |
14 | * - Redistributions of source code must retain the above copyright notice, | |
15 | * this list of conditions and the following disclaimer. | |
16 | * - Redistributions in binary form must reproduce the above copyright notice, | |
17 | * this list of conditions and the following disclaimer in the documentation | |
18 | * and/or other materials provided with the distribution. | |
19 | * - Neither the name of the MontaVista Software, Inc. nor the names of its | |
20 | * contributors may be used to endorse or promote products derived from this | |
21 | * software without specific prior written permission. | |
22 | * | |
23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
24 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
26 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | |
27 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
28 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
29 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
30 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
31 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
32 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF | |
33 | * THE POSSIBILITY OF SUCH DAMAGE. | |
34 | */ | |
031c02f5 FDN |
35 | |
36 | #include <config.h> | |
37 | ||
b04d69d3 SD |
38 | #include <stdio.h> |
39 | #include <stdlib.h> | |
40 | #include <unistd.h> | |
41 | #include <fcntl.h> | |
3855b428 | 42 | #include <errno.h> |
1be0c3bd | 43 | #include <getopt.h> |
b04d69d3 SD |
44 | #include <sys/types.h> |
45 | #include <sys/stat.h> | |
46 | ||
47 | #include <netinet/in.h> | |
48 | ||
2135d91c | 49 | #define KEYFILE COROSYSCONFDIR "/authkey" |
20e0336d | 50 | |
1be0c3bd RB |
51 | static const char usage[] = |
52 | "Usage: corosync-keygen [-l]\n" | |
53 | " -l / --less-secure - Use a less secure random number source\n" | |
54 | " (/dev/urandom) that is guaranteed not to require user\n" | |
55 | " input for entropy. This can be used when this\n" | |
56 | " application is used from a script.\n"; | |
57 | ||
58 | ||
59 | int main (int argc, char *argv[]) | |
60 | { | |
b04d69d3 SD |
61 | int authkey_fd; |
62 | int random_fd; | |
63 | unsigned char key[128]; | |
17c06251 | 64 | ssize_t res; |
69ced801 | 65 | ssize_t bytes_read; |
1be0c3bd RB |
66 | int c; |
67 | int option_index; | |
68 | int less_secure = 0; | |
69 | static struct option long_options[] = { | |
70 | { "less-secure", no_argument, NULL, 'l' }, | |
71 | { "help", no_argument, NULL, 'h' }, | |
72 | { 0, 0, NULL, 0 }, | |
73 | }; | |
74 | ||
75 | while ((c = getopt_long (argc, argv, "lh", | |
76 | long_options, &option_index)) != -1) { | |
77 | switch (c) { | |
78 | case 'l': | |
79 | less_secure = 1; | |
80 | break; | |
81 | case 'h': | |
82 | printf ("%s\n", usage); | |
83 | exit(0); | |
84 | break; | |
85 | default: | |
86 | printf ("Error parsing command line options.\n"); | |
87 | exit (1); | |
88 | } | |
89 | } | |
f2ceecc7 | 90 | |
01b8bc6a | 91 | printf ("Corosync Cluster Engine Authentication key generator.\n"); |
b04d69d3 SD |
92 | if (geteuid() != 0) { |
93 | printf ("Error: Authorization key must be generated as root user.\n"); | |
69ced801 | 94 | exit (errno); |
b04d69d3 | 95 | } |
2135d91c | 96 | if (mkdir (COROSYSCONFDIR, 0700)) { |
3855b428 | 97 | if (errno != EEXIST) { |
2135d91c | 98 | perror ("Failed to create directory: " COROSYSCONFDIR); |
69ced801 | 99 | exit (errno); |
3855b428 | 100 | } |
f2ceecc7 | 101 | } |
b04d69d3 | 102 | |
1be0c3bd RB |
103 | if (less_secure) { |
104 | random_fd = open ("/dev/urandom", O_RDONLY); | |
105 | } else { | |
106 | printf ("Gathering %lu bits for key from /dev/random.\n", (unsigned long)(sizeof (key) * 8)); | |
107 | printf ("Press keys on your keyboard to generate entropy.\n"); | |
108 | random_fd = open ("/dev/random", O_RDONLY); | |
109 | } | |
110 | ||
b04d69d3 | 111 | if (random_fd == -1) { |
1be0c3bd | 112 | perror ("Failed to open random source\n"); |
69ced801 | 113 | exit (errno); |
b04d69d3 SD |
114 | } |
115 | ||
116 | /* | |
117 | * Read random data | |
118 | */ | |
69ced801 SD |
119 | bytes_read = 0; |
120 | ||
121 | retry_read: | |
122 | res = read (random_fd, &key[bytes_read], sizeof (key) - bytes_read); | |
123 | if (res == -1) { | |
856c7455 | 124 | perror ("Could not read /dev/random"); |
69ced801 SD |
125 | exit (errno); |
126 | } | |
127 | bytes_read += res; | |
128 | if (bytes_read != sizeof (key)) { | |
1e17751d | 129 | printf ("Press keys on your keyboard to generate entropy (bits = %d).\n", (int)(bytes_read * 8)); |
69ced801 | 130 | goto retry_read; |
b04d69d3 | 131 | } |
f2ceecc7 | 132 | close (random_fd); |
b04d69d3 SD |
133 | |
134 | /* | |
135 | * Open key | |
136 | */ | |
20e0336d | 137 | authkey_fd = open (KEYFILE, O_CREAT|O_WRONLY, 600); |
b04d69d3 | 138 | if (authkey_fd == -1) { |
20e0336d | 139 | perror ("Could not create " KEYFILE); |
69ced801 | 140 | exit (errno); |
b04d69d3 SD |
141 | } |
142 | /* | |
ee82f483 | 143 | * Set security of authorization key to uid = 0 gid = 0 mode = 0400 |
b04d69d3 | 144 | */ |
ee82f483 SD |
145 | res = fchown (authkey_fd, 0, 0); |
146 | if (res == -1) { | |
147 | perror ("Could not fchown key to uid 0 and gid 0\n"); | |
69ced801 | 148 | exit (errno); |
ee82f483 | 149 | } |
f2ceecc7 JM |
150 | if (fchmod (authkey_fd, 0400)) { |
151 | perror ("Failed to set key file permissions to 0400\n"); | |
69ced801 | 152 | exit (errno); |
f2ceecc7 | 153 | } |
b04d69d3 | 154 | |
20e0336d | 155 | printf ("Writing corosync key to " KEYFILE ".\n"); |
b04d69d3 SD |
156 | |
157 | /* | |
158 | * Write key | |
159 | */ | |
160 | res = write (authkey_fd, key, sizeof (key)); | |
f2ceecc7 JM |
161 | if (res != sizeof (key)) { |
162 | perror ("Could not write " KEYFILE); | |
69ced801 | 163 | exit (errno); |
f2ceecc7 JM |
164 | } |
165 | ||
166 | if (close (authkey_fd)) { | |
20e0336d | 167 | perror ("Could not write " KEYFILE); |
69ced801 | 168 | exit (errno); |
b04d69d3 | 169 | } |
f2ceecc7 | 170 | |
b04d69d3 SD |
171 | return (0); |
172 | } |