Fix handling of errors with strtol(), factor out port parsing
[trust_router.git] / gsscon / test / gsscon_client.c
1 /*
2  * Copyright (c) 2012, JANET(UK)
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * 3. Neither the name of JANET(UK) nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
25  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
31  * OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  * This code was adapted from the MIT Kerberos Consortium's
34  * GSS example code, which was distributed under the following
35  * license:
36  *
37  * Copyright 2004-2006 Massachusetts Institute of Technology.
38  * All Rights Reserved.
39  *
40  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
41  * distribute this software and its documentation for any purpose and
42  * without fee is hereby granted, provided that the above copyright
43  * notice appear in all copies and that both that copyright notice and
44  * this permission notice appear in supporting documentation, and that
45  * the name of M.I.T. not be used in advertising or publicity pertaining
46  * to distribution of the software without specific, written prior
47  * permission.  Furthermore if you modify this software you must label
48  * your software as modified software and not distribute it in such a
49  * fashion that it might be confused with the original M.I.T. software.
50  * M.I.T. makes no representations about the suitability of
51  * this software for any purpose.  It is provided "as is" without express
52  * or implied warranty.
53  */
54
55 #include <gsscon.h>
56
57 static void Usage (const char *argv[])
58 {
59     fprintf (stderr, "Usage: %s [--port portNumber] [--server serverHostName]\n"
60              "\t[--sprinc servicePrincipal] [--cprinc clientPrincipal]\n", argv[0]);
61     exit (1);
62 }
63
64 /* --------------------------------------------------------------------------- */
65
66 int main (int argc, const char *argv[]) 
67 {
68     int err = 0;
69     int fd = -1;
70     int port = kDefaultPort;
71     long tmp;
72     const char *server = "127.0.0.1";
73     const char *clientName = NULL;
74     const char *serviceName = "host";
75     gss_ctx_id_t gssContext = GSS_C_NO_CONTEXT;
76     OM_uint32 minorStatus = 0;
77     int i = 0;
78         
79     for (i = 1; (i < argc) && !err; i++) {
80         if ((strcmp (argv[i], "--port") == 0) && (i < (argc - 1))) {
81             errno = 0; /* ensure this starts off as 0 */
82             tmp = strtol (argv[++i], NULL, 0);
83             if (errno)
84                 err = errno;
85             else if ((tmp <= 0) || (tmp > 65535))
86                 err = ERANGE;
87             else
88                 port = (int) tmp;
89         } else if ((strcmp (argv[i], "--server") == 0) && (i < (argc - 1))) {
90             server = argv[++i];
91         } else if ((strcmp(argv[i], "--cprinc") == 0) && (i < (argc - 1))) {
92             clientName = argv[++i];
93         } else if ((strcmp(argv[i], "--sprinc") == 0) && (i < (argc - 1))) {
94             serviceName = argv[++i];
95         } else {
96             err = EINVAL;
97         }
98     }
99     
100     if (!err) {
101         printf ("%s: Starting up...\n", argv[0]);
102         
103         err = gsscon_connect (server, (unsigned int) port, serviceName, &fd, &gssContext);
104     }
105     
106     if (!err) {
107         char *buffer = NULL;
108         size_t bufferLength = 0;
109
110         /* 
111          * Here is where your protocol would go.  This sample client just
112          * reads a nul terminated string from the server.
113          */
114         err = gsscon_read_encrypted_token (fd, gssContext, &buffer, &bufferLength);
115
116         if (!err) {
117             printf ("Server message: '%s'\n", buffer);
118         }
119         
120         if (buffer != NULL) { free (buffer); }
121     }
122     
123     
124     if (err) {
125         if (err == EINVAL) {
126             Usage (argv);
127         } else {
128             gsscon_print_error (err, "Client failed");
129         }
130     }
131     
132     if (fd >= 0) { printf ("Closing socket.\n"); close (fd); }
133     if (gssContext != GSS_C_NO_CONTEXT) { 
134         gss_delete_sec_context (&minorStatus, &gssContext, GSS_C_NO_BUFFER); }
135     
136     return err ? 1 : 0;
137 }
138
139
140