core: use string instead of compound literal
[rofl0r-proxychains-ng.git] / src / main.c
blob381c71c8090934ccd6dae02c86405dd3807bc8ca
1 /* (C) 2011, 2012 rofl0r
2 * *
3 * This program is free software; you can redistribute it and/or modify *
4 * it under the terms of the GNU General Public License as published by *
5 * the Free Software Foundation; either version 2 of the License, or *
6 * (at your option) any later version. *
7 * *
8 ***************************************************************************/
10 #define _DEFAULT_SOURCE
11 #include <stdio.h>
12 #include <unistd.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <errno.h>
16 #include <sys/types.h>
17 #include <sys/wait.h>
19 #ifdef IS_MAC
20 #define _DARWIN_C_SOURCE
21 #endif
22 #include <dlfcn.h>
24 #include "common.h"
26 static int usage(char **argv) {
27 printf("\nUsage:\t%s -q -f config_file program_name [arguments]\n"
28 "\t-q makes proxychains quiet - this overrides the config setting\n"
29 "\t-f allows one to manually specify a configfile to use\n"
30 "\tfor example : proxychains telnet somehost.com\n" "More help in README file\n\n", argv[0]);
31 return EXIT_FAILURE;
34 static const char *dll_name = DLL_NAME;
36 static char own_dir[256];
37 static const char *dll_dirs[] = {
38 #ifndef SUPER_SECURE /* CVE-2015-3887 */
39 ".",
40 #endif
41 own_dir,
42 LIB_DIR,
43 "/lib",
44 "/usr/lib",
45 "/usr/local/lib",
46 "/lib64",
47 NULL
50 static void set_own_dir(const char *argv0) {
51 size_t l = strlen(argv0);
52 while(l && argv0[l - 1] != '/')
53 l--;
54 if(l == 0 || l >= sizeof(own_dir))
55 #ifdef SUPER_SECURE
56 memcpy(own_dir, "/dev/null/", 11);
57 #else
58 memcpy(own_dir, ".", 2);
59 #endif
60 else {
61 memcpy(own_dir, argv0, l - 1);
62 own_dir[l] = 0;
66 #define MAX_COMMANDLINE_FLAGS 2
68 int main(int argc, char *argv[]) {
69 char *path = NULL;
70 char buf[256];
71 char pbuf[256];
72 int start_argv = 1;
73 int quiet = 0;
74 size_t i;
75 const char *prefix = NULL;
77 if(argc == 2 && !strcmp(argv[1], "--help"))
78 return usage(argv);
80 for(i = 0; i < MAX_COMMANDLINE_FLAGS; i++) {
81 if(start_argv < argc && argv[start_argv][0] == '-') {
82 if(argv[start_argv][1] == 'q') {
83 quiet = 1;
84 start_argv++;
85 } else if(argv[start_argv][1] == 'f') {
87 if(start_argv + 1 < argc)
88 path = argv[start_argv + 1];
89 else
90 return usage(argv);
92 start_argv += 2;
94 } else
95 break;
98 if(start_argv >= argc)
99 return usage(argv);
101 /* check if path of config file has not been passed via command line */
102 path = get_config_path(path, pbuf, sizeof(pbuf));
104 if(!quiet)
105 fprintf(stderr, LOG_PREFIX "config file found: %s\n", path);
107 /* Set PROXYCHAINS_CONF_FILE to get proxychains lib to use new config file. */
108 setenv(PROXYCHAINS_CONF_FILE_ENV_VAR, path, 1);
110 if(quiet)
111 setenv(PROXYCHAINS_QUIET_MODE_ENV_VAR, "1", 1);
114 // search DLL
116 Dl_info dli;
117 dladdr(own_dir, &dli);
118 set_own_dir(dli.dli_fname);
120 i = 0;
122 while(dll_dirs[i]) {
123 snprintf(buf, sizeof(buf), "%s/%s", dll_dirs[i], dll_name);
124 if(access(buf, R_OK) != -1) {
125 prefix = dll_dirs[i];
126 break;
128 i++;
131 if(!prefix) {
132 fprintf(stderr, "couldnt locate %s\n", dll_name);
133 return EXIT_FAILURE;
135 if(!quiet)
136 fprintf(stderr, LOG_PREFIX "preloading %s/%s\n", prefix, dll_name);
138 #if defined(IS_MAC) || defined(IS_OPENBSD)
139 #define LD_PRELOAD_SEP ":"
140 #else
141 /* Dynlinkers for Linux and most BSDs seem to support space
142 as LD_PRELOAD separator, with colon added only recently.
143 We use the old syntax for maximum compat */
144 #define LD_PRELOAD_SEP " "
145 #endif
147 #ifdef IS_MAC
148 putenv("DYLD_FORCE_FLAT_NAMESPACE=1");
149 #define LD_PRELOAD_ENV "DYLD_INSERT_LIBRARIES"
150 #else
151 #define LD_PRELOAD_ENV "LD_PRELOAD"
152 #endif
153 char *old_val = getenv(LD_PRELOAD_ENV);
154 snprintf(buf, sizeof(buf), LD_PRELOAD_ENV "=%s/%s%s%s",
155 prefix, dll_name,
156 /* append previous LD_PRELOAD content, if existent */
157 old_val ? LD_PRELOAD_SEP : "",
158 old_val ? old_val : "");
159 putenv(buf);
160 execvp(argv[start_argv], &argv[start_argv]);
161 fprintf(stderr, "proxychains: can't load process '%s'.", argv[start_argv]);
162 perror(" (hint: it's probably a typo)");
164 return EXIT_FAILURE;