source: trunk/src/ifd/ifdproxy.c @ 964

Revision 964, 5.5 KB checked in by aj, 5 years ago (diff)

indent changes only.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/*
2 * Remote device access - debugging utility that allows to
3 * test smart card readers on remote hosts.
4 *
5 * Copyright (C) 2003, Olaf Kirch <okir@suse.de>
6 */
7
8#ifdef HAVE_CONFIG_H
9#include <config.h>
10#endif
11#include <sys/types.h>
12#include <sys/stat.h>
13#include <sys/poll.h>
14#include <sys/socket.h>
15#include <arpa/inet.h>
16#ifdef HAVE_GETOPT_H
17#include <getopt.h>
18#endif
19#include <stdio.h>
20#include <stdlib.h>
21#include <string.h>
22#include <unistd.h>
23#include <fcntl.h>
24#include <errno.h>
25#include <pwd.h>
26#include <grp.h>
27#include <limits.h>
28
29#include <openct/path.h>
30#include <openct/socket.h>
31#include <openct/server.h>
32#include <openct/logging.h>
33#include "internal.h"
34#include "ria.h"
35
36static int opt_foreground = 0;
37static char *opt_config = NULL;
38static const char *opt_device_port = ":6666";
39static const char *opt_server_port = "proxy";
40static const char *opt_chroot = NULL;
41static const char *opt_user = NULL;
42
43static int get_ports(void);
44static int run_server(int, char **);
45static int run_client(int, char **);
46static int list_devices(int, char **);
47static void usage(int);
48static void version(void);
49
50int main(int argc, char **argv)
51{
52        char *command;
53        int c;
54
55        if (argc < 2)
56                usage(1);
57
58        ct_log_destination("@stderr");
59
60        while ((c = getopt(argc, argv, "df:FR:U:v")) != -1) {
61                switch (c) {
62                case 'd':
63                        ct_config.debug++;
64                        break;
65                case 'f':
66                        opt_config = optarg;
67                        break;
68                case 'F':
69                        opt_foreground++;
70                        break;
71                case 'R':
72                        opt_chroot = optarg;
73                        break;
74                case 'U':
75                        opt_user = optarg;
76                        break;
77                case 'v':
78                        version();
79                        break;
80                default:
81                        usage(1);
82                }
83        }
84
85        if (ifd_config_parse(opt_config) < 0)
86                return 1;
87
88        if (optind >= argc)
89                usage(1);
90        command = argv[optind++];
91
92        if (get_ports() < 0)
93                return 1;
94
95        if (!strcmp(command, "server")) {
96                run_server(argc - optind, argv + optind);
97        } else if (!strcmp(command, "export")) {
98                return run_client(argc - optind, argv + optind);
99        } else if (!strcmp(command, "list")) {
100                list_devices(argc - optind, argv + optind);
101        } else if (!strcmp(command, "version")) {
102                version();
103        } else {
104                ct_error("Unknown command `%s'\n", command);
105                return 1;
106        }
107
108        return 0;
109}
110
111static void enter_jail(void)
112{
113        struct passwd *pw = NULL;
114
115        if (opt_chroot && !opt_user)
116                opt_user = "nobody";
117        if (opt_user) {
118                if (!(pw = getpwnam(opt_user))) {
119                        ct_error("Unknown user %s\n", opt_user);
120                        exit(1);
121                }
122                endpwent();
123        }
124
125        if (opt_chroot) {
126                if (chdir("/") < 0 || chroot(opt_chroot) < 0) {
127                        ct_error("chroot(%s) failed: %m", opt_chroot);
128                        exit(1);
129                }
130        }
131
132        if (pw) {
133                if (setgroups(0, NULL) < 0
134                    || setgid(pw->pw_gid) < 0 || setuid(pw->pw_uid) < 0) {
135                        ct_error("Failed to drop privileges: %m");
136                        exit(1);
137                }
138        }
139}
140
141static void background_process(void)
142{
143        int fd;
144
145        if (daemon(0, 0) < 0) {
146                ct_error("failed to background process: %m");
147                exit(1);
148        }
149
150        if ((fd = open("/dev/null", O_RDWR)) >= 0) {
151                dup2(fd, 0);
152                dup2(fd, 1);
153                dup2(fd, 2);
154                if (fd > 2)
155                        close(fd);
156        }
157
158        ct_log_destination("@syslog");
159        setsid();
160}
161
162static int get_ports(void)
163{
164        char *address;
165        int rc;
166
167        if ((rc = ifd_conf_get_string("ifdproxy.device-port", &address)) >= 0)
168                opt_device_port = address;
169        if ((rc = ifd_conf_get_string("ifdproxy.server-port", &address)) >= 0)
170                opt_server_port = address;
171        return 0;
172}
173
174static int run_server(int argc, char **argv)
175{
176        int rc;
177        char path[PATH_MAX];
178
179        if (!ct_format_path(path, PATH_MAX, opt_server_port)) {
180                return -1;
181        }
182
183        if (argc != 0)
184                usage(1);
185        if (ct_config.debug)
186                ct_socket_reuseaddr(1);
187
188        if ((rc = ria_svc_listen(path, 1)) < 0) {
189                ct_error("Cannot bind to server port \"%s\": %s\n",
190                         path, ct_strerror(rc));
191                return rc;
192        }
193        if ((rc = ria_svc_listen(opt_device_port, 0)) < 0) {
194                ct_error("Cannot bind to device port \"%s\": %s\n",
195                         opt_device_port, ct_strerror(rc));
196                return rc;
197        }
198
199        enter_jail();
200        if (!opt_foreground)
201                background_process();
202
203        ct_mainloop();
204        return 0;
205}
206
207static int run_client(int argc, char **argv)
208{
209        const char *name, *device, *address;
210        ria_client_t *ria;
211        int rc;
212
213        /* Initialize IFD library */
214        if (ifd_init())
215                return 1;
216
217        if (argc != 2 && argc != 3)
218                usage(1);
219        name = argv[0];
220        device = argv[1];
221        address = argc == 3 ? argv[2] : opt_device_port;
222
223        ria = ria_export_device(address, device);
224
225        ifd_debug(1, "About to register device as \"%s\"", name);
226        if ((rc = ria_register_device(ria, name)) < 0) {
227                ct_error("Unable to register device: %s\n", ct_strerror(rc));
228                exit(1);
229        }
230
231        enter_jail();
232        if (!opt_foreground)
233                background_process();
234
235        ct_mainloop();
236        return 0;
237}
238
239static int list_devices(int argc, char **argv)
240{
241        unsigned char buffer[8192];
242        ria_device_t *info;
243        ria_client_t *clnt;
244        unsigned int n, count;
245        int rc;
246
247        if (argc == 1)
248                opt_server_port = argv[0];
249        else if (argc > 1)
250                usage(1);
251
252        if (!(clnt = ria_connect(opt_server_port)))
253                exit(1);
254        rc = ria_command(clnt, RIA_MGR_LIST, NULL, 0, buffer, sizeof(buffer),
255                         -1);
256        if (rc < 0) {
257                ct_error("Failed to list exported devices: %s",
258                         ct_strerror(rc));
259                ria_free(clnt);
260                return 1;
261        }
262
263        count = rc / sizeof(ria_device_t);
264        if (count == 0) {
265                printf("No exported devices\n");
266                ria_free(clnt);
267                return 0;
268        }
269
270        printf("Exported devices\n");
271        for (info = (ria_device_t *) buffer, n = 0; n < count; info++, n++) {
272                printf("  %-16s %-30s %s\n",
273                       info->handle, info->address, info->name);
274        }
275
276        ria_free(clnt);
277        return 0;
278}
279
280static void version(void)
281{
282        fprintf(stderr, "OpenCT " VERSION "\n");
283        exit(0);
284}
285
286static void usage(int exval)
287{
288        fprintf(exval ? stderr : stdout,
289                "Usage:\n"
290                "ifdproxy server [-dF]\n"
291                "ifdproxy export [-dF] name device address\n"
292                "ifdproxy list [-dF] address\n" "ifdproxy version\n");
293        exit(exval);
294}
Note: See TracBrowser for help on using the repository browser.