1*1c7715ddSchristos /* $NetBSD: misc.h,v 1.29 2024/07/08 22:33:43 christos Exp $ */ 2*1c7715ddSchristos /* $OpenBSD: misc.h,v 1.109 2024/06/06 17:15:25 djm Exp $ */ 3ca32bd8dSchristos 4ca32bd8dSchristos /* 5ca32bd8dSchristos * Author: Tatu Ylonen <ylo@cs.hut.fi> 6ca32bd8dSchristos * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 7ca32bd8dSchristos * All rights reserved 8ca32bd8dSchristos * 9ca32bd8dSchristos * As far as I am concerned, the code I have written for this software 10ca32bd8dSchristos * can be used freely for any purpose. Any derived versions of this 11ca32bd8dSchristos * software must be clearly marked as such, and if the derived work is 12ca32bd8dSchristos * incompatible with the protocol description in the RFC file, it must be 13ca32bd8dSchristos * called by a name other than "ssh" or "Secure Shell". 14ca32bd8dSchristos */ 15ca32bd8dSchristos 16ca32bd8dSchristos #ifndef _MISC_H 17ca32bd8dSchristos #define _MISC_H 18ca32bd8dSchristos 19ee85abc4Schristos #include <sys/time.h> 207a183406Schristos #include <sys/types.h> 21aa36fcacSchristos #include <sys/socket.h> 22e8c0841bSchristos #include <stdio.h> 23a629fefcSchristos #include <signal.h> 24ee85abc4Schristos 25*1c7715ddSchristos /* special-case port number meaning allow any port */ 26*1c7715ddSchristos #define FWD_PERMIT_ANY_PORT 0 27*1c7715ddSchristos 28*1c7715ddSchristos /* special-case wildcard meaning allow any host */ 29*1c7715ddSchristos #define FWD_PERMIT_ANY_HOST "*" 30*1c7715ddSchristos 318a4530f9Schristos /* Data structure for representing a forwarding request. */ 328a4530f9Schristos struct Forward { 338a4530f9Schristos char *listen_host; /* Host (address) to listen on. */ 348a4530f9Schristos int listen_port; /* Port to forward. */ 358a4530f9Schristos char *listen_path; /* Path to bind domain socket. */ 368a4530f9Schristos char *connect_host; /* Host to connect. */ 378a4530f9Schristos int connect_port; /* Port to connect on connect_host. */ 388a4530f9Schristos char *connect_path; /* Path to connect domain socket. */ 398a4530f9Schristos int allocated_port; /* Dynamically allocated listen port */ 408a4530f9Schristos int handle; /* Handle for dynamic listen ports */ 418a4530f9Schristos }; 428a4530f9Schristos 435101d403Schristos int forward_equals(const struct Forward *, const struct Forward *); 44*1c7715ddSchristos int permitopen_port(const char *p); 45*1c7715ddSchristos 46ee85abc4Schristos int daemonized(void); 475101d403Schristos 488a4530f9Schristos /* Common server and client forwarding options. */ 498a4530f9Schristos struct ForwardOptions { 508a4530f9Schristos int gateway_ports; /* Allow remote connects to forwarded ports. */ 518a4530f9Schristos mode_t streamlocal_bind_mask; /* umask for streamlocal binds */ 528a4530f9Schristos int streamlocal_bind_unlink; /* unlink socket before bind */ 538a4530f9Schristos }; 548a4530f9Schristos 55ca32bd8dSchristos /* misc.c */ 56ca32bd8dSchristos 57ca32bd8dSchristos char *chop(char *); 58b592f463Schristos void rtrim(char *); 59cd4ada6aSchristos void skip_space(char **); 60ca32bd8dSchristos char *strdelim(char **); 6155a4608bSchristos char *strdelimw(char **); 62ca32bd8dSchristos int set_nonblock(int); 63ca32bd8dSchristos int unset_nonblock(int); 64ca32bd8dSchristos void set_nodelay(int); 65ffae97bbSchristos int set_reuseaddr(int); 66ffae97bbSchristos char *get_rdomain(int); 67ffae97bbSchristos int set_rdomain(int, const char *); 6817418e98Schristos int get_sock_af(int); 6917418e98Schristos void set_sock_tos(int, int); 70a629fefcSchristos int waitrfd(int, int *, volatile sig_atomic_t *); 71aa36fcacSchristos int timeout_connect(int, const struct sockaddr *, socklen_t, int *); 72ca32bd8dSchristos int a2port(const char *); 73ca32bd8dSchristos int a2tun(const char *, int *); 74ca32bd8dSchristos char *put_host_port(const char *, u_short); 75aa36fcacSchristos char *hpdelim2(char **, char *); 76ca32bd8dSchristos char *hpdelim(char **); 77ca32bd8dSchristos char *cleanhostname(char *); 78ca32bd8dSchristos char *colon(char *); 7917418e98Schristos int parse_user_host_path(const char *, char **, char **, char **); 805101d403Schristos int parse_user_host_port(const char *, char **, char **, int *); 8117418e98Schristos int parse_uri(const char *, const char *, char **, char **, int *, char **); 8217418e98Schristos int convtime(const char *); 832d3b0f52Schristos const char *fmt_timeframe(time_t t); 84b592f463Schristos int tilde_expand(const char *, uid_t, char **); 85ca32bd8dSchristos char *tilde_expand_filename(const char *, uid_t); 862d3b0f52Schristos 872d3b0f52Schristos char *dollar_expand(int *, const char *string, ...); 882d3b0f52Schristos char *percent_expand(const char *, ...) __attribute__((__sentinel__)); 892d3b0f52Schristos char *percent_dollar_expand(const char *, ...) __attribute__((__sentinel__)); 90ca32bd8dSchristos char *tohex(const void *, size_t); 91ed75d7a8Schristos void xextendf(char **s, const char *sep, const char *fmt, ...) 92ed75d7a8Schristos __attribute__((__format__ (printf, 3, 4))) __attribute__((__nonnull__ (3))); 93ca32bd8dSchristos void sanitise_stdfd(void); 948a4530f9Schristos struct timeval; 95ca32bd8dSchristos void ms_subtract_diff(struct timeval *, int *); 96a03ec00cSchristos void ms_to_timespec(struct timespec *, int); 97ffae97bbSchristos void monotime_ts(struct timespec *); 98ffae97bbSchristos void monotime_tv(struct timeval *); 9900a838c4Schristos time_t monotime(void); 1005101d403Schristos double monotime_double(void); 1018a4530f9Schristos void lowercase(char *s); 1028a4530f9Schristos int unix_listener(const char *, int, int); 103ffae97bbSchristos int valid_domain(char *, int, const char **); 104aa36fcacSchristos int valid_env_name(const char *); 105ffae97bbSchristos const char *atoi_err(const char *, int *); 106ffae97bbSchristos int parse_absolute_time(const char *, uint64_t *); 107ffae97bbSchristos void format_absolute_time(uint64_t, char *, size_t); 108514b5d45Schristos int parse_pattern_interval(const char *, char **, int *); 109aa36fcacSchristos int path_absolute(const char *); 11017418e98Schristos int stdfd_devnull(int, int, int); 111a629fefcSchristos int lib_contains_symbol(const char *, const char *); 112ca32bd8dSchristos 1138a4530f9Schristos int bcrypt_pbkdf(const char *, size_t, const u_int8_t *, size_t, 1148a4530f9Schristos u_int8_t *, size_t, unsigned int); 115313c6c94Schristos 116ca32bd8dSchristos struct passwd *pwcopy(struct passwd *); 117ca32bd8dSchristos const char *ssh_gai_strerror(int); 118ca32bd8dSchristos 11917418e98Schristos typedef void privdrop_fn(struct passwd *); 12017418e98Schristos typedef void privrestore_fn(void); 12117418e98Schristos #define SSH_SUBPROCESS_STDOUT_DISCARD (1) /* Discard stdout */ 12217418e98Schristos #define SSH_SUBPROCESS_STDOUT_CAPTURE (1<<1) /* Redirect stdout */ 12317418e98Schristos #define SSH_SUBPROCESS_STDERR_DISCARD (1<<2) /* Discard stderr */ 12417418e98Schristos #define SSH_SUBPROCESS_UNSAFE_PATH (1<<3) /* Don't check for safe cmd */ 12517418e98Schristos #define SSH_SUBPROCESS_PRESERVE_ENV (1<<4) /* Keep parent environment */ 12617418e98Schristos pid_t subprocess(const char *, const char *, int, char **, FILE **, u_int, 12717418e98Schristos struct passwd *, privdrop_fn *, privrestore_fn *); 12817418e98Schristos 129ca32bd8dSchristos typedef struct arglist arglist; 130ca32bd8dSchristos struct arglist { 131ca32bd8dSchristos char **list; 132ca32bd8dSchristos u_int num; 133ca32bd8dSchristos u_int nalloc; 134ca32bd8dSchristos }; 135185c8f97Schristos void addargs(arglist *, const char *, ...) 136ca32bd8dSchristos __attribute__((format(printf, 2, 3))); 137185c8f97Schristos void replacearg(arglist *, u_int, const char *, ...) 138ca32bd8dSchristos __attribute__((format(printf, 3, 4))); 139ca32bd8dSchristos void freeargs(arglist *); 140ca32bd8dSchristos 141ffae97bbSchristos int tun_open(int, int, char **); 142ca32bd8dSchristos 143ca32bd8dSchristos /* Common definitions for ssh tunnel device forwarding */ 144ca32bd8dSchristos #define SSH_TUNMODE_NO 0x00 145ca32bd8dSchristos #define SSH_TUNMODE_POINTOPOINT 0x01 146ca32bd8dSchristos #define SSH_TUNMODE_ETHERNET 0x02 147ca32bd8dSchristos #define SSH_TUNMODE_DEFAULT SSH_TUNMODE_POINTOPOINT 148ca32bd8dSchristos #define SSH_TUNMODE_YES (SSH_TUNMODE_POINTOPOINT|SSH_TUNMODE_ETHERNET) 149ca32bd8dSchristos 150ca32bd8dSchristos #define SSH_TUNID_ANY 0x7fffffff 151ca32bd8dSchristos #define SSH_TUNID_ERR (SSH_TUNID_ANY - 1) 152ca32bd8dSchristos #define SSH_TUNID_MAX (SSH_TUNID_ANY - 2) 153ca32bd8dSchristos 1548a4530f9Schristos /* Fake port to indicate that host field is really a path. */ 1558a4530f9Schristos #define PORT_STREAMLOCAL -2 1568a4530f9Schristos 157ca32bd8dSchristos /* Functions to extract or store big-endian words of various sizes */ 158ca32bd8dSchristos u_int64_t get_u64(const void *) 1598a4530f9Schristos __attribute__((__bounded__( __minbytes__, 1, 8))); 160ca32bd8dSchristos u_int32_t get_u32(const void *) 1618a4530f9Schristos __attribute__((__bounded__( __minbytes__, 1, 4))); 162ca32bd8dSchristos u_int16_t get_u16(const void *) 1638a4530f9Schristos __attribute__((__bounded__( __minbytes__, 1, 2))); 164ca32bd8dSchristos void put_u64(void *, u_int64_t) 1658a4530f9Schristos __attribute__((__bounded__( __minbytes__, 1, 8))); 166ca32bd8dSchristos void put_u32(void *, u_int32_t) 1678a4530f9Schristos __attribute__((__bounded__( __minbytes__, 1, 4))); 168ca32bd8dSchristos void put_u16(void *, u_int16_t) 1698a4530f9Schristos __attribute__((__bounded__( __minbytes__, 1, 2))); 1708a4530f9Schristos 1718a4530f9Schristos /* Little-endian store/load, used by umac.c */ 1728a4530f9Schristos u_int32_t get_u32_le(const void *) 1738a4530f9Schristos __attribute__((__bounded__(__minbytes__, 1, 4))); 1748a4530f9Schristos void put_u32_le(void *, u_int32_t) 1758a4530f9Schristos __attribute__((__bounded__(__minbytes__, 1, 4))); 176ca32bd8dSchristos 177185c8f97Schristos struct bwlimit { 178185c8f97Schristos size_t buflen; 179aa36fcacSchristos u_int64_t rate; /* desired rate in kbit/s */ 180aa36fcacSchristos u_int64_t thresh; /* threshold after which we'll check timers */ 181aa36fcacSchristos u_int64_t lamt; /* amount written in last timer interval */ 182185c8f97Schristos struct timeval bwstart, bwend; 183185c8f97Schristos }; 184185c8f97Schristos 185185c8f97Schristos void bandwidth_limit_init(struct bwlimit *, u_int64_t, size_t); 186185c8f97Schristos void bandwidth_limit(struct bwlimit *, size_t); 187185c8f97Schristos 188185c8f97Schristos int parse_ipqos(const char *); 1896f47b660Schristos const char *iptos2str(int); 190185c8f97Schristos void mktemp_proto(char *, size_t); 191ca32bd8dSchristos 1927a183406Schristos void child_set_env(char ***envp, u_int *envsizep, const char *name, 1937a183406Schristos const char *value); 194b592f463Schristos const char *lookup_env_in_list(const char *env, 195b592f463Schristos char * const *envs, size_t nenvs); 196e160b4e8Schristos const char *lookup_setenv_in_list(const char *env, 197e160b4e8Schristos char * const *envs, size_t nenvs); 1987a183406Schristos 199b592f463Schristos int argv_split(const char *, int *, char ***, int); 2007a183406Schristos char *argv_assemble(int, char **argv); 201b592f463Schristos char *argv_next(int *, char ***); 202b592f463Schristos void argv_consume(int *); 203b592f463Schristos void argv_free(char **, int); 204b592f463Schristos 2057a183406Schristos int exited_cleanly(pid_t, const char *, const char *, int); 2067a183406Schristos 2077a183406Schristos struct stat; 2087a183406Schristos int safe_path(const char *, struct stat *, const char *, uid_t, 2097a183406Schristos char *, size_t); 2107a183406Schristos int safe_path_fd(int, const char *, struct passwd *, 2117a183406Schristos char *err, size_t errlen); 2127a183406Schristos 213cd4ada6aSchristos /* authorized_key-style options parsing helpers */ 214cd4ada6aSchristos int opt_flag(const char *opt, int allow_negate, const char **optsp); 215cd4ada6aSchristos char *opt_dequote(const char **sp, const char **errstrp); 216cd4ada6aSchristos int opt_match(const char **opts, const char *term); 217cd4ada6aSchristos 21817418e98Schristos /* readconf/servconf option lists */ 21917418e98Schristos void opt_array_append(const char *file, const int line, 22017418e98Schristos const char *directive, char ***array, u_int *lp, const char *s); 22117418e98Schristos void opt_array_append2(const char *file, const int line, 22217418e98Schristos const char *directive, char ***array, int **iarray, u_int *lp, 22317418e98Schristos const char *s, int i); 224c5555919Schristos void opt_array_free2(char **array, int **iarray, u_int l); 22517418e98Schristos 226b1066cf3Schristos struct timespec; 227b1066cf3Schristos void ptimeout_init(struct timespec *pt); 228b1066cf3Schristos void ptimeout_deadline_sec(struct timespec *pt, long sec); 229b1066cf3Schristos void ptimeout_deadline_ms(struct timespec *pt, long ms); 230a629fefcSchristos void ptimeout_deadline_monotime_tsp(struct timespec *pt, struct timespec *when); 231b1066cf3Schristos void ptimeout_deadline_monotime(struct timespec *pt, time_t when); 232b1066cf3Schristos int ptimeout_get_ms(struct timespec *pt); 233b1066cf3Schristos struct timespec *ptimeout_get_tsp(struct timespec *pt); 234b1066cf3Schristos int ptimeout_isset(struct timespec *pt); 235b1066cf3Schristos 236ca32bd8dSchristos /* readpass.c */ 237ca32bd8dSchristos 238ca32bd8dSchristos #define RP_ECHO 0x0001 239ca32bd8dSchristos #define RP_ALLOW_STDIN 0x0002 240ca32bd8dSchristos #define RP_ALLOW_EOF 0x0004 241ca32bd8dSchristos #define RP_USE_ASKPASS 0x0008 242ca32bd8dSchristos 243ed75d7a8Schristos struct notifier_ctx; 244ed75d7a8Schristos 245ca32bd8dSchristos char *read_passphrase(const char *, int); 246ca32bd8dSchristos int ask_permission(const char *, ...) __attribute__((format(printf, 1, 2))); 247ed75d7a8Schristos struct notifier_ctx *notify_start(int, const char *, ...) 248ed75d7a8Schristos __attribute__((format(printf, 2, 3))); 24917418e98Schristos void notify_complete(struct notifier_ctx *, const char *, ...) 25017418e98Schristos __attribute__((format(printf, 2, 3))); 251ca32bd8dSchristos 252ee85abc4Schristos #define MINIMUM(a, b) (((a) < (b)) ? (a) : (b)) 253ee85abc4Schristos #define MAXIMUM(a, b) (((a) > (b)) ? (a) : (b)) 254ee85abc4Schristos #define ROUNDUP(x, y) ((((x)+((y)-1))/(y))*(y)) 255ee85abc4Schristos 256ed75d7a8Schristos typedef void (*sshsig_t)(int); 257ed75d7a8Schristos sshsig_t ssh_signal(int, sshsig_t); 258*1c7715ddSchristos int signal_is_crash(int); 25917418e98Schristos 260b1066cf3Schristos /* On OpenBSD time_t is int64_t which is long long. */ 261b1066cf3Schristos #define SSH_TIME_T_MAX LLONG_MAX 262b1066cf3Schristos 263ca32bd8dSchristos #endif /* _MISC_H */ 264