1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423
|
#ifndef __GST_COMMON_H__
#define __GST_COMMON_H__ 1
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#ifdef HAVE_SYS_PARAM_H
# include <sys/param.h>
#endif
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/resource.h>
#ifdef HAVE_SYS_LOADAVG_H
# include <sys/loadavg.h> // Solaris11
#endif
#ifdef HAVE_SYS_ENDIAN_H
# include <sys/endian.h>
#endif
#include <netinet/in.h>
#ifdef HAVE_NETINET_IN_SYSTM_H
# include <netinet/in_systm.h>
#endif
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <netinet/ip_icmp.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <errno.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef HAVE_FNMATCH_H
#include <fnmatch.h>
#endif
#include <stdio.h>
#include <string.h>
#include <strings.h> // Solaris11
#include <stdarg.h>
#include <stdlib.h>
#include <stdint.h>
#include <ctype.h>
#include <inttypes.h>
#include <signal.h>
#include <libgen.h> /* basename() */
#include <termios.h>
#include <pwd.h>
#ifdef HAVE_WORDEXP_H
# include <wordexp.h>
#else
# warning "wordexp.h not found. File Transfer may not work with globbing"
#endif
#ifdef HAVE_UTMPX_H
# include <utmpx.h>
#endif
#ifdef HAVE_UTMP_H
# include <utmp.h>
#endif
#ifdef HAVE_LIBUTIL_H
# include <libutil.h> /* FreeBSD */
#endif
#ifdef HAVE_PTY_H
# include <pty.h>
#endif
#ifdef HAVE_UTIL_H
# include <util.h> /* MacOS */
#endif
#if defined __sun || defined __hpux /* Solaris, HP-UX */
# include <stropts.h>
#endif
#include <locale.h>
#include <openssl/ssl.h>
#include <openssl/srp.h>
#include <gsocket/gsocket.h>
#include <gsocket/gs-select.h>
#include "filetransfer.h"
#ifdef __sun
# ifdef HAVE_OPEN64
# define IS_SOL10 1 // Solaris 10
# else
# define IS_SOL11 1 // Solaris 11
# endif
# define IS_SOLARIS 1
#endif
#ifndef O_NOCTTY
# warning "O_NOCTTY not defined. Using 0."
# define O_NOCTTY 0
#endif
// Older fbsd's dont have this defined
#ifndef UT_NAMESIZE
# define UT_NAMESIZE 32
#endif
// debian-hurd does not define PATH_MAX (and has no limit on filename length)
#ifndef PATH_MAX
# define GS_PATH_MAX 4096
#else
# define GS_PATH_MAX PATH_MAX
#endif
#if defined(__sun)
# if !defined(be64toh) // Solaris11
# define be64toh(x) ntohll(x)
# define htobe64(x) htonll(x)
# endif
# if !defined(htonll) // Solaris10
# if __BIG_ENDIAN__
# define htonll(x) (x)
# define ntohll(x) (x)
# else
# define htonll(x) ((uint64_t)htonl((x) & 0xFFFFFFFF) << 32) | htonl((uint64_t)(x) >> 32)
# define ntohll(x) ((uint64_t)ntohl((x) & 0xFFFFFFFF) << 32) | ntohl((uint64_t)(x) >> 32)
# endif
# endif
#endif
#ifndef htonll
# define htonll(x) htobe64(x)
#endif
#ifndef ntohll
# define ntohll(x) be64toh(x)
#endif
struct _gopt
{
GS_CTX gs_ctx;
GS *gsocket; /* Listening gsocket */
FILE *log_fp;
FILE *err_fp;
int verbosity; // verbosity level (-v => 1, -vv => 2 etc)
int flags;
int verboselevel;
const char *sec_str;
const char *sec_file;
GS_ADDR gs_addr;
char *token_str;
int is_sock_wait;
int is_client_or_server;
int is_no_encryption;
int is_blocking;
int is_interactive; /* PTY interactive shell? */
int is_receive_only;
int is_use_tor;
int is_socks_server; /* -S flag */
int is_multi_peer; /* -p / -S / -d [client & server] */
int is_daemon;
int is_watchdog; // Never die but die if stdin closes
int is_logfile;
int is_quiet;
int is_win_resized; // window size changed (signal)
int is_console; // console is being displayed
int is_pong_pending; // Server: Answer to PING waiting to be send
int is_status_nopty_pending;
int is_pty_failed; // Tried to create PTY but failed. Dump terminal.
int is_want_pwd; // Client: Wants server to send cwd
int is_pwdreply_pending; // Server: Answer to pwd-request
int is_want_chdir;
int is_want_ids_on;
int is_want_authcookie;
int is_send_authcookie;
int is_internal; // -I flag
int is_udp; // Port forwarding only. GSRN is always TCP.
int is_built_debug; // DEBUG is set
int is_greetings;
int is_try_server; // Check with GSRN is server is listening.
int gs_server_check_sec;
int is_stdin_a_tty;
int is_stdin_ignore_eof;
char *prg_name; // argv[0]
uint64_t ts_ping_sent; // TimeStamp ping sent
fd_set rfd, r;
fd_set wfd, w;
struct timeval tv_now;
const char *cmd;
uint32_t dst_ip; /* NBO */
uint16_t port; /* NBO */
int listen_fd;
struct winsize winsize;
struct winsize winsize_prev;
int row_total; // Rows including console
int peer_count;
int peer_id_counter;
GS_EVENT event_ping;
GS_EVENT event_bps;
GS_EVENT *event_ids;
GS_LIST ids_peers;
char *ids_active_user;
int ids_idle;
int n_users; // Number of unique logged in users (from utmp)
int app_keepalive_sec; // Interval for app-keepalive
};
#ifdef DEBUG
#define GS_APP_KEEPALIVE 10 // If no activty send app-layer ping (-i needed)
#else
#define GS_APP_KEEPALIVE GSRN_DEFAULT_PING_INTERVAL // If no activty send app-layer ping (-i needed)
#endif
// Let the client be in control to send PING's to keep the connection busy
// but if the client is 5 sec late then start sending PINGS to client.
#define GS_APP_KEEPALIVE_SERVER (GS_APP_KEEPALIVE + 5)
#define EX_CONNREFUSED 61 // Used by deploy.sh to verify that server is responding
#define EX_BAD_AUTH 201 // Used to terminate watchdog/daemon
#define EX_ALARM 202
#define EX_NETERROR 203 // likely TCP ECONNREFUSED
#define EX_EXECFAILED 248
#define EX_NOTREACHED 249
#define EX_BADWRITE 250 // write() failed
#define EX_UNKNWNCMD 251 // Unknown command line parameter
#define EX_BADSELECT 253
#define EX_SIGTERM 254
#define EX_FATAL 255
struct _socks
{
uint32_t dst_ip;
uint16_t dst_port;
char dst_hostname[256]; // dst host name.
int state;
};
#define GSNC_STATE_AWAITING_MSG_AUTH (0x01)
#define GSNC_STATE_AWAITING_MSG_CONNECT (0x02)
#define GSNC_STATE_RESOLVING_DN (0x03)
#define GSNC_STATE_CONNECTING (0x04)
#define GSNC_STATE_CONNECTED (0x05)
/* gs-netcat peers */
struct _peer
{
/* A peer is connected to a gsocket and the a cmd_fd */
GS *gs;
int fd_in;
int fd_out; /* Same as fd_in unless client reads from stdin/stdout */
uint8_t rbuf[2048]; /* from GS, to fd */
size_t r_max;
ssize_t rlen;
uint8_t wbuf[2048]; /* from fd, to GS */
size_t w_max;
ssize_t wlen;
uint8_t pbuf[2048]; /* for pkt-encode/decode */
int is_network_forward;
int is_stdin_forward;
int is_app_forward;
int is_fd_connected;
int is_pty_first_read; /* send stty hack */
int is_stty_set_raw; /* Client only */
int is_received_gs_eof; // EOF from GSRN
int is_want_ping; // Client: Wants to send a ping
/* For Statistics */
int id; /* Stats: assign an ID to each pere */
struct _socks socks;
GS_PKT pkt; // In-band data for interactive shell (-i)
GS_FT ft; // Filetransfer (-i)
GS_LIST logs; // Queue for log messages from Server to Client (-i)
int is_pending_logs; // Log files need to be send to peer.
GS_LIST_ITEM *ids_li; // Peer is interested in global IDS logs
pid_t pid;
uint64_t ts_peer_io; // TimeStamp of last peer I/O (e.g. UDP, stdin, ...)
GS_BUF udp_buf; // UDP un-stacker (for -u)
GS_EVENT event_peer_timeout;
};
#define GSC_FL_IS_SERVER (0x01)
extern struct _gopt gopt; // declared in utils.c
#define xfprintf(fp, a...) do {if (fp != NULL) { fprintf(fp, a); fflush(fp); } } while (0)
#define int_ntoa(x) inet_ntoa(*((struct in_addr *)&x))
#ifndef MAX
# define MAX(X, Y) (((X) < (Y)) ? (Y) : (X))
#endif
#ifndef MIN
# define MIN(X, Y) (((X) < (Y)) ? (X) : (Y))
#endif
#define D_RED(a) "\033[0;31m"a"\033[0m"
#define D_GRE(a) "\033[0;32m"a"\033[0m"
#define D_YEL(a) "\033[0;33m"a"\033[0m"
#define D_BLU(a) "\033[0;34m"a"\033[0m"
#define D_MAG(a) "\033[0;35m"a"\033[0m"
#define D_BRED(a) "\033[1;31m"a"\033[0m"
#define D_BGRE(a) "\033[1;32m"a"\033[0m"
#define D_BYEL(a) "\033[1;33m"a"\033[0m"
#define D_BBLU(a) "\033[1;34m"a"\033[0m"
#define D_BMAG(a) "\033[1;35m"a"\033[0m"
#ifdef DEBUG
struct _g_debug_ctx
{
struct timeval tv_last;
struct timeval tv_now;
};
extern struct _g_debug_ctx g_dbg_ctx; // declared in utils.c
#define DEBUGF_T(xcolor, a...) do { \
gettimeofday(&g_dbg_ctx.tv_now, NULL); \
if (g_dbg_ctx.tv_last.tv_sec == 0) { memcpy(&g_dbg_ctx.tv_last, &g_dbg_ctx.tv_now, sizeof g_dbg_ctx.tv_last); } \
xfprintf(gopt.err_fp, "DEBUG %4"PRIu64" %s:%d %s", GS_TV_TO_MSEC(&g_dbg_ctx.tv_now) - GS_TV_TO_MSEC(&g_dbg_ctx.tv_last), __func__, __LINE__, xcolor?xcolor:""); \
memcpy(&g_dbg_ctx.tv_last, &g_dbg_ctx.tv_now, sizeof g_dbg_ctx.tv_last); \
xfprintf(gopt.err_fp, a); \
if (xcolor) { xfprintf(gopt.err_fp, "\033[0m"); } \
} while (0)
# define DEBUGF(a...) do{DEBUGF_T(NULL, a); } while(0)
# define DEBUGF_R(a...) do{DEBUGF_T("\033[1;31m", a); } while(0)
# define DEBUGF_G(a...) do{DEBUGF_T("\033[1;32m", a); } while(0)
# define DEBUGF_B(a...) do{DEBUGF_T("\033[1;34m", a); } while(0)
# define DEBUGF_Y(a...) do{DEBUGF_T("\033[1;33m", a); } while(0)
# define DEBUGF_M(a...) do{DEBUGF_T("\033[1;35m", a); } while(0)
# define DEBUGF_C(a...) do{DEBUGF_T("\033[1;36m", a); } while(0)
# define DEBUGF_W(a...) do{DEBUGF_T("\033[1;37m", a); } while(0)
#else // DEBUG
# define DEBUGF(a...)
# define DEBUGF_R(a...)
# define DEBUGF_G(a...)
# define DEBUGF_B(a...)
# define DEBUGF_Y(a...)
# define DEBUGF_M(a...)
# define DEBUGF_C(a...)
# define DEBUGF_W(a...)
# define DEBUGF_A(a...)
#endif
// Increase ptr by number of characters added to ptr.
#define SXPRINTF(ptr, len, a...) do {\
size_t n = snprintf(ptr, len, a); \
ptr += MIN(n, len); \
} while(0)
// Overcome GCC warning for truncation. Abort() if truncation happen.
#define SNPRINTF_ABORT(...) (snprintf(__VA_ARGS__) < 0 ? abort() : (void)0)
#define VOUT(level, a...) do { \
if (level > gopt.verboselevel) \
break; \
xfprintf(gopt.out, a); \
fflush(gopt.out); \
} while (0)
#define XFREE(ptr) do{if(ptr) free(ptr); ptr = NULL;}while(0)
#define ERREXITC(code, a...) do { \
xfprintf(gopt.err_fp, "ERROR(%d): ", code); \
xfprintf(gopt.err_fp, a); \
exit(code); \
} while (0)
#ifdef DEBUG
# define ERREXIT(a...) do { \
xfprintf(gopt.err_fp, "ERROR "); \
xfprintf(gopt.err_fp, "%s():%d ", __func__, __LINE__); \
xfprintf(gopt.err_fp, a); \
exit(255); \
} while (0)
#else
# define ERREXIT(a...) do { \
xfprintf(gopt.err_fp, "ERROR: "); \
xfprintf(gopt.err_fp, a); \
exit(255); \
} while (0)
#endif
#ifndef XASSERT
# define XASSERT(expr, a...) do { \
if (!(expr)) { \
xfprintf(gopt.err_fp, "%s:%d:%s() ASSERT(%s) ", __FILE__, __LINE__, __func__, #expr); \
xfprintf(gopt.err_fp, a); \
xfprintf(gopt.err_fp, " Exiting...\n"); \
exit(255); \
} \
} while (0)
#endif
#define XCLOSE(fd) do { \
if (fd < 0) { DEBUGF_R("*** WARNING *** CLosing BAD fd\n"); break; } \
DEBUGF_W("Closing fd = %d\n", fd); \
close(fd); \
fd = -1; \
} while (0)
#define XFCLOSE(fp) do { \
if (fp == NULL) { DEBUGF_R("*** WARNING *** Closing BAD fp\n"); break; } \
fclose(fp); \
fp = NULL; \
} while (0)
#define XFD_SET(fd, set) do { \
if (fd < 0) { DEBUGF_R("WARNING: FD_SET(%d, )\n", fd); break; } \
FD_SET(fd, set); \
} while (0)
#ifdef DEBUG
# define HEXDUMP(a, _len) do { \
size_t _n = 0; \
xfprintf(gopt.err_fp, "%s:%d HEX[%zd] ", __FILE__, __LINE__, _len); \
while (_n < (_len)) xfprintf(gopt.err_fp, "%2.2x", ((unsigned char *)a)[_n++]); \
xfprintf(gopt.err_fp, "\n"); \
} while (0)
# define HEXDUMPF(a, len, m...) do{xfprintf(gopt.err_fp, m); HEXDUMP(a, len);}while(0)
#else
# define HEXDUMP(a, len)
# define HEXDUMPF(a, len, m...)
#endif
#endif /* !__GST_COMMON_H__ */
|