Implemented server main loop and started with import command.
[gnupg.git] / sm / server.c
1 /* server.c - Server mode and main entry point 
2  *      Copyright (C) 2001 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG 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 2 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG 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.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 #include <config.h>
22 #include <errno.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <ctype.h>
27 #include <unistd.h>
28
29 #include "gpgsm.h"
30 #include "../assuan/assuan.h"
31
32 #define set_error(e,t) assuan_set_error (ctx, ASSUAN_ ## e, (t))
33
34
35 /*  RECIPIENT <userID>
36
37   Set the recipient for the encryption.  <userID> should be the
38   internal representation of the key; the server may accept any other
39   way of specification [we will support this].  If this is a valid and
40   trusted recipient the server does respond with OK, otherwise the
41   return is an ERR with the reason why the recipient can't be used,
42   the encryption will then not be done for this recipient.  IF the
43   policy is not to encrypt at all if not all recipients are valid, the
44   client has to take care of this.  All RECIPIENT commands are
45   cumulative until a RESET or ENCRYPT command.  */
46 static int 
47 cmd_recipient (ASSUAN_CONTEXT ctx, char *line)
48 {
49   
50
51   return set_error (Not_Implemented, "fixme");
52 }
53
54
55 /* ENCRYPT [armor]
56
57   Do the actual encryption process. Takes the plaintext from the INPUT
58   command, writes to the ciphertext to the file descriptor set with
59   the OUTPUT command, take the recipients form all the recipients set
60   so far.  If this command fails the clients should try to delete all
61   output currently done or otherwise mark it as invalid.  GPGSM does
62   ensure that there won't be any security problem with leftover data
63   on the output in this case.
64
65   This command should in general not fail, as all necessary checks
66   have been done while setting the recipients.  The input and output
67   pipes are closed.
68
69   The optional armor parameter may be used to request base64 encoded
70   output.  */
71 static int 
72 cmd_encrypt (ASSUAN_CONTEXT ctx, char *line)
73 {
74   
75
76   return set_error (Not_Implemented, "fixme");
77 }
78
79 /* DECRYPT
80
81   This performs the decrypt operation after doing some check on the
82   internal state. (e.g. that only needed data has been set).  Because
83   it utilises the GPG-Agent for the session key decryption, there is
84   no need to ask the client for a protecting passphrase - GpgAgent
85   does take care of this but requesting this from the user. */
86 static int 
87 cmd_decrypt (ASSUAN_CONTEXT ctx, char *line)
88 {
89   
90
91   return set_error (Not_Implemented, "fixme");
92 }
93
94
95 /* VERIFY
96
97   This does a verify operation on the message send to the input-FD.
98   The result is written out using status lines.  If an output FD was
99   given, the signed text will be written to that.
100
101   The behavior for detached signatures has not yet been specified.  */
102 static int 
103 cmd_verify (ASSUAN_CONTEXT ctx, char *line)
104 {
105   
106
107   return set_error (Not_Implemented, "fixme");
108 }
109
110
111 /* SIGN
112
113    FIXME */
114 static int 
115 cmd_sign (ASSUAN_CONTEXT ctx, char *line)
116 {
117   
118
119   return set_error (Not_Implemented, "fixme");
120 }
121
122
123 /* IMPORT
124
125   Import the certificates read form the input-fd, return status
126   message for each imported one.  The import checks the validity of
127   the certificate but not of the path.  It is possible to import
128   expired certificates.  */
129 static int 
130 cmd_import (ASSUAN_CONTEXT ctx, char *line)
131 {
132   int fd = assuan_get_input_fd (ctx);
133
134   if (fd == -1)
135     return set_error (No_Input, NULL);
136
137   gpgsm_import (fd);
138
139   return 0;
140 }
141
142
143
144 \f
145 /* Tell the assuan library about our commands */
146 static int
147 register_commands (ASSUAN_CONTEXT ctx)
148 {
149   static struct {
150     const char *name;
151     int cmd_id;
152     int (*handler)(ASSUAN_CONTEXT, char *line);
153   } table[] = {
154     { "RECIPIENT",  0,  cmd_recipient },
155     { "ENCRYPT",    0,  cmd_encrypt },
156     { "DECRYPT",    0,  cmd_decrypt },
157     { "VERIFY",     0,  cmd_verify },
158     { "SIGN",       0,  cmd_sign },
159     { "IMPORT",     0,  cmd_import },
160     { "",     ASSUAN_CMD_INPUT, NULL }, 
161     { "",     ASSUAN_CMD_OUTPUT, NULL }, 
162     { NULL }
163   };
164   int i, j, rc;
165
166   for (i=j=0; table[i].name; i++)
167     {
168       rc = assuan_register_command (ctx,
169                                     table[i].cmd_id? table[i].cmd_id
170                                                    : (ASSUAN_CMD_USER + j++),
171                                     table[i].name, table[i].handler);
172       if (rc)
173         return rc;
174     } 
175   return 0;
176 }
177
178 /* Startup the server */
179 void
180 gpgsm_server (void)
181 {
182   int rc;
183   int filedes[2];
184   ASSUAN_CONTEXT ctx;
185
186   /* For now we use a simple pipe based server so that we can work
187      from scripts.  We will later add options to run as a daemon and
188      wait for requests on a Unix domain socket */
189   filedes[0] = 0;
190   filedes[1] = 1;
191   rc = assuan_init_pipe_server (&ctx, filedes);
192   if (rc)
193     {
194       log_error ("failed to initialize the server: %s\n",
195                  assuan_strerror(rc));
196       gpgsm_exit (2);
197     }
198   rc = register_commands (ctx);
199   if (rc)
200     {
201       log_error ("failed to the register commands with Assuan: %s\n",
202                  assuan_strerror(rc));
203       gpgsm_exit (2);
204     }
205
206   log_info ("Assuan started\n");
207   for (;;)
208     {
209       rc = assuan_accept (ctx);
210       if (rc == -1)
211         {
212           log_info ("Assuan terminated\n");
213           break;
214         }
215       else if (rc)
216         {
217           log_info ("Assuan accept problem: %s\n", assuan_strerror (rc));
218           break;
219         }
220       
221       rc = assuan_process (ctx);
222       if (rc)
223         {
224           log_info ("Assuan processing failed: %s\n", assuan_strerror (rc));
225           continue;
226         }
227     }
228
229
230   assuan_deinit_pipe_server (ctx);
231 }
232
233
234
235
236
237
238