OSDN Git Service

2013.10.24
[uclinux-h8/uClinux-dist.git] / user / ssh / gen-keys.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <sys/types.h>
5 #include <sys/wait.h>
6 #include <sys/stat.h>
7 #include <fcntl.h>
8 #include <unistd.h>
9 #include <dirent.h>
10 #include <signal.h>
11 #include "config.h"
12 #include <config/autoconf.h>
13
14
15 /* This little program is a wrapper for the ssh key-gen program that produces
16  * ssh keys as required.  The basic outline is simple, keys will be produced
17  * at boot time for sshd only if they don't already exist.  For ssh the path
18  * is slightly more complex, keys will be created every boot unless sshd is
19  * also installed in which case its behaviour will override.
20  *
21  * In addition, the flash file system will be synced if sshd is enabled.
22  * This means that sshd will only use a single set of keys which is good
23  * because ssh causes pain if the daemon it is connecting to changes its
24  * keys.
25  */
26
27
28 /* Where we end up installing our key files */
29 #define BASE_DIR        "/etc/config/"
30
31 /* List of file names to mangle.
32  * The key type is included at the end after a \0 which happens to terminate
33  * the string for us :-)
34  */
35 static const char *files[] = {
36         "ssh_host_rsa_key\0rsa",
37 #ifndef CONFIG_USER_SSH_ONLY_RSA_V2_KEYGEN
38         "ssh_host_dsa_key\0dsa",
39         "ssh_host_key\0rsa1",
40 #if defined(INCLUDE_SSH)
41         "id_rsa\0rsa",
42         "id_dsa\0dsa",
43         "identity\0rsa1",
44 #endif
45 #endif /* CONFIG_USER_SSH_ONLY_RSA_V2_KEYGEN */
46         NULL
47 };
48
49
50 #if defined(INCLUDE_SSHD) || defined(INCLUDE_SSH)
51 /* Check if the key files are alreayd there or not */
52 static inline int check_files(void) {
53 int               i;
54 struct stat       st;
55 char              fname[40];
56         for (i=0; files[i] != NULL; i++) {
57                 strcpy(fname, BASE_DIR);
58                 strcpy(fname+sizeof(BASE_DIR)-1, files[i]);
59                 if (-1 == stat(fname, &st))
60                         return 0;
61                 strcat(fname, ".pub");
62                 if (-1 == stat(fname, &st))
63                         return 0;
64         }
65         return 1;
66 }
67 #endif
68
69
70 /* Remove all key files.  The key generator fails if they're already there */
71 static inline void remove_files(void) {
72 int               i;
73 char              fname[40];
74         for (i=0; files[i] != NULL; i++) {
75                 strcpy(fname, BASE_DIR);
76                 strcpy(fname+sizeof(BASE_DIR)-1, files[i]);
77                 unlink(fname);
78                 strcat(fname+sizeof(BASE_DIR)-1, ".pub");
79                 unlink(fname);
80         }
81 }
82
83
84 /* Exec the key generation program with the specified args */
85 static void exec(char *const av[]) {
86 extern char     **environ;
87 int               status;
88 pid_t             pid;
89 #ifdef __uClinux__
90         pid = vfork();
91 #else
92         pid = fork();
93 #endif
94         if (pid == 0) {
95                 /* Child */
96                 execve("/bin/ssh-keygen", av, environ);
97 #ifdef __uClinux__
98                 _exit(0);
99 #else
100                 exit(0);
101 #endif
102         } else if (pid != -1) {
103                 waitpid(pid, &status, 0);
104         }
105 }
106
107
108 /* Scan through and generate the appropriate keys */
109 static inline void gen_files(void) {
110 char             *av[14];
111 int               ac, tc;
112 char              fname[40];
113 int               i;
114         /* set up command args... */
115         ac = 0;
116         av[ac++] = "ssh-keygen";
117         av[ac++] = "-q";
118         av[ac++] = "-f";
119         strcpy(fname, BASE_DIR);
120         av[ac++] = fname;
121         av[ac++] = "-C";
122         av[ac++] = "";
123         av[ac++] = "-N";
124         av[ac++] = "";
125         av[ac++] = "-t";
126         tc = ac++;              /* Placeholder for type */
127         av[ac] = NULL;
128
129         /* Loop through the files creating keys */
130         for (i=0; files[i] != NULL; i++) {
131                 strcpy(fname+sizeof(BASE_DIR)-1, files[i]);
132                 av[tc] = 1+strchr(files[i], '\0');
133                 exec(av);
134         }
135 }
136
137
138 #if defined(INCLUDE_SSHD) || defined(INCLUDE_SSH)
139 /* Write back our config file system */
140 static inline void
141 sync_files(void)
142 {
143         system("exec flatfsd -s");
144 }
145 #endif
146
147
148 /* The main driver routine */
149 int main(int argc, char *argv[]) {
150         sleep(10);      
151 #if defined(INCLUDE_SSHD) || defined(INCLUDE_SSH)
152         if (check_files())
153                 return 0;
154 #endif
155         remove_files();
156         gen_files();
157 #if defined(INCLUDE_SSHD) || defined(INCLUDE_SSH)
158         sync_files();
159 #endif
160         return 0;
161 }