Update gnulib files.
[shishi.git] / examples / server.c
blob83bb1ca5dc38760b96a1dd3a0da8574ee2f6700c
1 /* server.c --- Sample server with authentication using Shishi.
2 * Copyright (C) 2003, 2004, 2007 Simon Josefsson
4 * This file is part of Shishi.
6 * Shishi is free software; you can redistribute it and/or modify it
7 * 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 * Shishi is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with Shishi; if not, see http://www.gnu.org/licenses or write
18 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
19 * Floor, Boston, MA 02110-1301, USA
23 #include <stdio.h>
24 #include <stdlib.h>
26 #include <shishi.h>
28 #define SERVICE "sample"
30 /* XXX remove this */
31 const char *program_name = "client";
33 static int
34 doit (Shishi * h, Shishi_ap * ap, int verbose)
36 Shishi_asn1 asn1safe;
37 Shishi_safe *safe;
38 char *userdata;
39 size_t userdatalen;
40 int res;
42 printf ("Application exchange start. Press ^D to finish.\n");
44 while ((res = shishi_safe_parse (h, stdin, &asn1safe)) == SHISHI_OK)
46 if (res != SHISHI_OK)
48 fprintf (stderr, "Could not read SAFE:\n%s\n%s\n",
49 shishi_strerror (res), shishi_error (h));
50 return 1;
53 res = shishi_safe (h, &safe);
54 if (res != SHISHI_OK)
56 fprintf (stderr, "Could not create SAFE:\n%s\n%s\n",
57 shishi_strerror (res), shishi_error (h));
58 return 1;
61 shishi_safe_safe_set (safe, asn1safe);
63 res = shishi_safe_verify (safe, shishi_ap_key (ap));
64 if (res != SHISHI_OK)
66 fprintf (stderr, "Could not verify SAFE:\n%s\n%s\n",
67 shishi_strerror (res), shishi_error (h));
68 return 1;
71 printf ("Verified SAFE successfully...\n");
73 res = shishi_safe_user_data (h, asn1safe, &userdata, &userdatalen);
74 if (res != SHISHI_OK)
76 fprintf (stderr, "Could not extract user data:\n%s\n%s\n",
77 shishi_strerror (res), shishi_error (h));
78 return 1;
80 userdata[userdatalen] = '\0';
81 printf ("user data: `%s'\n", userdata);
85 if (ferror (stdin))
87 printf ("error reading stdin\n");
88 return 1;
91 return 0;
94 static Shishi_ap *
95 auth (Shishi * h, int verbose, const char *cname, const char *sname)
97 Shishi_key *key;
98 Shishi_ap *ap;
99 Shishi_asn1 apreq;
100 char buf[BUFSIZ];
101 int buflen;
102 int rc;
104 printf ("Client: %s\n", cname);
105 printf ("Server: %s\n", sname);
107 /* Get key for the server. */
109 key = shishi_hostkeys_for_server (h, sname);
110 if (!key)
112 printf ("could not find key: %s\n", shishi_error (h));
113 return NULL;
116 if (verbose)
117 shishi_key_print (h, stderr, key);
119 /* Read Authentication request from client */
121 printf ("Waiting for client to authenticate itself...\n");
123 rc = shishi_apreq_parse (h, stdin, &apreq);
124 if (rc != SHISHI_OK)
126 printf ("could not read AP-REQ: %s\n", shishi_strerror (rc));
127 return NULL;
130 /* Create Authentication context */
132 rc = shishi_ap (h, &ap);
133 if (rc != SHISHI_OK)
135 printf ("Could not create AP: %s\n", shishi_strerror (rc));
136 return NULL;
139 /* Store request in context */
141 shishi_ap_req_set (ap, apreq);
143 /* Process authentication request */
145 rc = shishi_ap_req_process (ap, key);
146 if (rc != SHISHI_OK)
148 printf ("Could not process AP-REQ: %s\n", shishi_strerror (rc));
149 return NULL;
152 if (verbose)
153 shishi_authenticator_print (h, stderr, shishi_ap_authenticator (ap));
155 buflen = sizeof (buf);
156 rc = shishi_authenticator_cnamerealm_get (h, shishi_ap_authenticator (ap),
157 buf, &buflen);
158 buf[buflen] = '\0';
159 printf ("Client name (from authenticator): %s\n", buf);
161 buflen = sizeof (buf);
162 rc = shishi_encticketpart_cnamerealm_get
163 (h, shishi_tkt_encticketpart (shishi_ap_tkt (ap)), buf, &buflen);
164 buf[buflen] = '\0';
165 printf ("Client name (from encticketpart): %s\n", buf);
167 buflen = sizeof (buf);
168 rc =
169 shishi_ticket_snamerealm_get (h, shishi_tkt_ticket (shishi_ap_tkt (ap)),
170 buf, &buflen);
171 buf[buflen] = '\0';
172 printf ("Server name (from ticket): %s\n", buf);
174 /* User is authenticated. */
176 printf ("User authenticated.\n");
178 /* Authenticate ourself to client, if request */
180 if (shishi_apreq_mutual_required_p (h, apreq))
182 Shishi_asn1 aprep;
184 printf ("Mutual authentication required.\n");
186 rc = shishi_ap_rep_asn1 (ap, &aprep);
187 if (rc != SHISHI_OK)
189 printf ("Error creating AP-REP: %s\n", shishi_strerror (rc));
190 return NULL;
193 if (verbose)
194 shishi_encapreppart_print (h, stderr, shishi_ap_encapreppart (ap));
196 shishi_aprep_print (h, stdout, aprep);
198 /* We are authenticated to client */
201 return ap;
205 main (int argc, char *argv[])
207 Shishi *h;
208 Shishi_ap *ap;
209 char *sname;
210 int rc;
212 printf ("sample-server (shishi " SHISHI_VERSION ")\n");
214 if (!shishi_check_version (SHISHI_VERSION))
216 printf ("shishi_check_version() failed:\n"
217 "Header file incompatible with shared library.\n");
218 return 1;
221 rc = shishi_init_server (&h);
222 if (rc != SHISHI_OK)
224 printf ("error initializing shishi: %s\n", shishi_strerror (rc));
225 return 1;
228 if (argc > 1)
229 sname = argv[1];
230 else
231 sname = shishi_server_for_local_service (h, SERVICE);
233 ap = auth (h, 1, shishi_principal_default (h), sname);
235 if (ap)
236 rc = doit (h, ap, 1);
237 else
238 rc = 1;
240 shishi_done (h);
242 return rc;