mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-09 09:27:59 +00:00
Replace method-dispatch #defines with inline functions.
This replaces all the macros like ssh_key_sign() and win_draw_text() which take an object containing a vtable pointer and do the dereferencing to find the actual concrete method to call. Now they're all inline functions, which means more sensible type-checking and more comprehensible error reports when the types go wrong, and also means that there's no risk of double-evaluating the object argument.
This commit is contained in:
parent
07ebd88c3a
commit
1b4a08a953
49
network.h
49
network.h
@ -148,23 +148,31 @@ Socket *sk_new(SockAddr *addr, int port, bool privport, bool oobinline,
|
||||
Socket *sk_newlistener(const char *srcaddr, int port, Plug *plug,
|
||||
bool local_host_only, int address_family);
|
||||
|
||||
#define sk_plug(s,p) (((s)->vt->plug) (s, p))
|
||||
#define sk_close(s) (((s)->vt->close) (s))
|
||||
#define sk_write(s,buf,len) (((s)->vt->write) (s, buf, len))
|
||||
#define sk_write_oob(s,buf,len) (((s)->vt->write_oob) (s, buf, len))
|
||||
#define sk_write_eof(s) (((s)->vt->write_eof) (s))
|
||||
#define sk_flush(s) (((s)->vt->flush) (s))
|
||||
static inline Plug *sk_plug(Socket *s, Plug *p)
|
||||
{ return s->vt->plug(s, p); }
|
||||
static inline void sk_close(Socket *s)
|
||||
{ s->vt->close(s); }
|
||||
static inline size_t sk_write(Socket *s, const void *data, size_t len)
|
||||
{ return s->vt->write(s, data, len); }
|
||||
static inline size_t sk_write_oob(Socket *s, const void *data, size_t len)
|
||||
{ return s->vt->write_oob(s, data, len); }
|
||||
static inline void sk_write_eof(Socket *s)
|
||||
{ s->vt->write_eof(s); }
|
||||
static inline void sk_flush(Socket *s)
|
||||
{ s->vt->flush(s); }
|
||||
|
||||
#define plug_log(p,type,addr,port,msg,code) \
|
||||
(((p)->vt->log) (p, type, addr, port, msg, code))
|
||||
#define plug_closing(p,msg,code,callback) \
|
||||
(((p)->vt->closing) (p, msg, code, callback))
|
||||
#define plug_receive(p,urgent,buf,len) \
|
||||
(((p)->vt->receive) (p, urgent, buf, len))
|
||||
#define plug_sent(p,bufsize) \
|
||||
(((p)->vt->sent) (p, bufsize))
|
||||
#define plug_accepting(p, constructor, ctx) \
|
||||
(((p)->vt->accepting)(p, constructor, ctx))
|
||||
static inline void plug_log(
|
||||
Plug *p, int type, SockAddr *addr, int port, const char *msg, int code)
|
||||
{ return p->vt->log(p, type, addr, port, msg, code); }
|
||||
static inline void plug_closing(
|
||||
Plug *p, const char *msg, int code, bool calling_back)
|
||||
{ return p->vt->closing(p, msg, code, calling_back); }
|
||||
static inline void plug_receive(Plug *p, int urg, const char *data, size_t len)
|
||||
{ return p->vt->receive(p, urg, data, len); }
|
||||
static inline void plug_sent (Plug *p, size_t bufsize)
|
||||
{ return p->vt->sent(p, bufsize); }
|
||||
static inline int plug_accepting(Plug *p, accept_fn_t cons, accept_ctx_t ctx)
|
||||
{ return p->vt->accepting(p, cons, ctx); }
|
||||
|
||||
/*
|
||||
* Special error values are returned from sk_namelookup and sk_new
|
||||
@ -172,7 +180,8 @@ Socket *sk_newlistener(const char *srcaddr, int port, Plug *plug,
|
||||
* or return NULL if there's no problem.
|
||||
*/
|
||||
const char *sk_addr_error(SockAddr *addr);
|
||||
#define sk_socket_error(s) (((s)->vt->socket_error) (s))
|
||||
static inline const char *sk_socket_error(Socket *s)
|
||||
{ return s->vt->socket_error(s); }
|
||||
|
||||
/*
|
||||
* Set the `frozen' flag on a socket. A frozen socket is one in
|
||||
@ -191,7 +200,8 @@ const char *sk_addr_error(SockAddr *addr);
|
||||
* associated local socket in order to avoid unbounded buffer
|
||||
* growth.
|
||||
*/
|
||||
#define sk_set_frozen(s, is_frozen) (((s)->vt->set_frozen) (s, is_frozen))
|
||||
static inline void sk_set_frozen(Socket *s, bool is_frozen)
|
||||
{ s->vt->set_frozen(s, is_frozen); }
|
||||
|
||||
/*
|
||||
* Return a structure giving some information about the other end of
|
||||
@ -199,7 +209,8 @@ const char *sk_addr_error(SockAddr *addr);
|
||||
* not NULL, then it is dynamically allocated, and should be freed by
|
||||
* a call to sk_free_peer_info(). See below for the definition.
|
||||
*/
|
||||
#define sk_peer_info(s) (((s)->vt->peer_info) (s))
|
||||
static inline SocketPeerInfo *sk_peer_info(Socket *s)
|
||||
{ return s->vt->peer_info(s); }
|
||||
|
||||
/*
|
||||
* The structure returned from sk_peer_info, and a function to free
|
||||
|
252
putty.h
252
putty.h
@ -530,23 +530,39 @@ struct BackendVtable {
|
||||
int default_port;
|
||||
};
|
||||
|
||||
#define backend_init(vt, seat, out, logctx, conf, host, port, rhost, nd, ka) \
|
||||
((vt)->init(seat, out, logctx, conf, host, port, rhost, nd, ka))
|
||||
#define backend_free(be) ((be)->vt->free(be))
|
||||
#define backend_reconfig(be, conf) ((be)->vt->reconfig(be, conf))
|
||||
#define backend_send(be, buf, len) ((be)->vt->send(be, buf, len))
|
||||
#define backend_sendbuffer(be) ((be)->vt->sendbuffer(be))
|
||||
#define backend_size(be, w, h) ((be)->vt->size(be, w, h))
|
||||
#define backend_special(be, code, arg) ((be)->vt->special(be, code, arg))
|
||||
#define backend_get_specials(be) ((be)->vt->get_specials(be))
|
||||
#define backend_connected(be) ((be)->vt->connected(be))
|
||||
#define backend_exitcode(be) ((be)->vt->exitcode(be))
|
||||
#define backend_sendok(be) ((be)->vt->sendok(be))
|
||||
#define backend_ldisc_option_state(be, opt) \
|
||||
((be)->vt->ldisc_option_state(be, opt))
|
||||
#define backend_provide_ldisc(be, ldisc) ((be)->vt->provide_ldisc(be, ldisc))
|
||||
#define backend_unthrottle(be, bufsize) ((be)->vt->unthrottle(be, bufsize))
|
||||
#define backend_cfg_info(be) ((be)->vt->cfg_info(be))
|
||||
static inline const char *backend_init(
|
||||
const BackendVtable *vt, Seat *seat, Backend **out, LogContext *logctx,
|
||||
Conf *conf, const char *host, int port, char **rhost, bool nd, bool ka)
|
||||
{ return vt->init(seat, out, logctx, conf, host, port, rhost, nd, ka); }
|
||||
static inline void backend_free(Backend *be)
|
||||
{ be->vt->free(be); }
|
||||
static inline void backend_reconfig(Backend *be, Conf *conf)
|
||||
{ be->vt->reconfig(be, conf); }
|
||||
static inline size_t backend_send(Backend *be, const char *buf, size_t len)
|
||||
{ return be->vt->send(be, buf, len); }
|
||||
static inline size_t backend_sendbuffer(Backend *be)
|
||||
{ return be->vt->sendbuffer(be); }
|
||||
static inline void backend_size(Backend *be, int width, int height)
|
||||
{ be->vt->size(be, width, height); }
|
||||
static inline void backend_special(
|
||||
Backend *be, SessionSpecialCode code, int arg)
|
||||
{ be->vt->special(be, code, arg); }
|
||||
static inline const SessionSpecial *backend_get_specials(Backend *be)
|
||||
{ return be->vt->get_specials(be); }
|
||||
static inline bool backend_connected(Backend *be)
|
||||
{ return be->vt->connected(be); }
|
||||
static inline int backend_exitcode(Backend *be)
|
||||
{ return be->vt->exitcode(be); }
|
||||
static inline bool backend_sendok(Backend *be)
|
||||
{ return be->vt->sendok(be); }
|
||||
static inline bool backend_ldisc_option_state(Backend *be, int state)
|
||||
{ return be->vt->ldisc_option_state(be, state); }
|
||||
static inline void backend_provide_ldisc(Backend *be, Ldisc *ldisc)
|
||||
{ be->vt->provide_ldisc(be, ldisc); }
|
||||
static inline void backend_unthrottle(Backend *be, size_t bufsize)
|
||||
{ be->vt->unthrottle(be, bufsize); }
|
||||
static inline int backend_cfg_info(Backend *be)
|
||||
{ return be->vt->cfg_info(be); }
|
||||
|
||||
extern const struct BackendVtable *const backends[];
|
||||
|
||||
@ -915,36 +931,44 @@ struct SeatVtable {
|
||||
bool (*get_window_pixel_size)(Seat *seat, int *width, int *height);
|
||||
};
|
||||
|
||||
#define seat_output(seat, is_stderr, data, len) \
|
||||
((seat)->vt->output(seat, is_stderr, data, len))
|
||||
#define seat_eof(seat) \
|
||||
((seat)->vt->eof(seat))
|
||||
#define seat_get_userpass_input(seat, p, input) \
|
||||
((seat)->vt->get_userpass_input(seat, p, input))
|
||||
#define seat_notify_remote_exit(seat) \
|
||||
((seat)->vt->notify_remote_exit(seat))
|
||||
#define seat_update_specials_menu(seat) \
|
||||
((seat)->vt->update_specials_menu(seat))
|
||||
#define seat_get_ttymode(seat, mode) \
|
||||
((seat)->vt->get_ttymode(seat, mode))
|
||||
#define seat_set_busy_status(seat, status) \
|
||||
((seat)->vt->set_busy_status(seat, status))
|
||||
#define seat_verify_ssh_host_key(seat, h, p, typ, str, fp, cb, ctx) \
|
||||
((seat)->vt->verify_ssh_host_key(seat, h, p, typ, str, fp, cb, ctx))
|
||||
#define seat_confirm_weak_crypto_primitive(seat, typ, alg, cb, ctx) \
|
||||
((seat)->vt->confirm_weak_crypto_primitive(seat, typ, alg, cb, ctx))
|
||||
#define seat_confirm_weak_cached_hostkey(seat, alg, better, cb, ctx) \
|
||||
((seat)->vt->confirm_weak_cached_hostkey(seat, alg, better, cb, ctx))
|
||||
#define seat_is_utf8(seat) \
|
||||
((seat)->vt->is_utf8(seat))
|
||||
#define seat_echoedit_update(seat, echoing, editing) \
|
||||
((seat)->vt->echoedit_update(seat, echoing, editing))
|
||||
#define seat_get_x_display(seat) \
|
||||
((seat)->vt->get_x_display(seat))
|
||||
#define seat_get_windowid(seat, out) \
|
||||
((seat)->vt->get_windowid(seat, out))
|
||||
#define seat_get_window_pixel_size(seat, width, height) \
|
||||
((seat)->vt->get_window_pixel_size(seat, width, height))
|
||||
static inline size_t seat_output(
|
||||
Seat *seat, bool err, const void *data, size_t len)
|
||||
{ return seat->vt->output(seat, err, data, len); }
|
||||
static inline bool seat_eof(Seat *seat)
|
||||
{ return seat->vt->eof(seat); }
|
||||
static inline int seat_get_userpass_input(
|
||||
Seat *seat, prompts_t *p, bufchain *input)
|
||||
{ return seat->vt->get_userpass_input(seat, p, input); }
|
||||
static inline void seat_notify_remote_exit(Seat *seat)
|
||||
{ seat->vt->notify_remote_exit(seat); }
|
||||
static inline void seat_update_specials_menu(Seat *seat)
|
||||
{ seat->vt->update_specials_menu(seat); }
|
||||
static inline char *seat_get_ttymode(Seat *seat, const char *mode)
|
||||
{ return seat->vt->get_ttymode(seat, mode); }
|
||||
static inline void seat_set_busy_status(Seat *seat, BusyStatus status)
|
||||
{ seat->vt->set_busy_status(seat, status); }
|
||||
static inline int seat_verify_ssh_host_key(
|
||||
Seat *seat, const char *h, int p, const char *ktyp, char *kstr,
|
||||
char *fp, void (*cb)(void *ctx, int result), void *ctx)
|
||||
{ return seat->vt->verify_ssh_host_key(seat, h, p, ktyp, kstr, fp, cb, ctx); }
|
||||
static inline int seat_confirm_weak_crypto_primitive(
|
||||
Seat *seat, const char *atyp, const char *aname,
|
||||
void (*cb)(void *ctx, int result), void *ctx)
|
||||
{ return seat->vt->confirm_weak_crypto_primitive(seat, atyp, aname, cb, ctx); }
|
||||
static inline int seat_confirm_weak_cached_hostkey(
|
||||
Seat *seat, const char *aname, const char *better,
|
||||
void (*cb)(void *ctx, int result), void *ctx)
|
||||
{ return seat->vt->confirm_weak_cached_hostkey(seat, aname, better, cb, ctx); }
|
||||
static inline bool seat_is_utf8(Seat *seat)
|
||||
{ return seat->vt->is_utf8(seat); }
|
||||
static inline void seat_echoedit_update(Seat *seat, bool ec, bool ed)
|
||||
{ seat->vt->echoedit_update(seat, ec, ed); }
|
||||
static inline const char *seat_get_x_display(Seat *seat)
|
||||
{ return seat->vt->get_x_display(seat); }
|
||||
static inline bool seat_get_windowid(Seat *seat, long *id_out)
|
||||
{ return seat->vt->get_windowid(seat, id_out); }
|
||||
static inline bool seat_get_window_pixel_size(Seat *seat, int *w, int *h)
|
||||
{ return seat->vt->get_window_pixel_size(seat, w, h); }
|
||||
|
||||
/* Unlike the seat's actual method, the public entry point
|
||||
* seat_connection_fatal is a wrapper function with a printf-like API,
|
||||
@ -952,10 +976,10 @@ struct SeatVtable {
|
||||
void seat_connection_fatal(Seat *seat, const char *fmt, ...);
|
||||
|
||||
/* Handy aliases for seat_output which set is_stderr to a fixed value. */
|
||||
#define seat_stdout(seat, data, len) \
|
||||
seat_output(seat, false, data, len)
|
||||
#define seat_stderr(seat, data, len) \
|
||||
seat_output(seat, true, data, len)
|
||||
static inline size_t seat_stdout(Seat *seat, const void *data, size_t len)
|
||||
{ return seat_output(seat, false, data, len); }
|
||||
static inline size_t seat_stderr(Seat *seat, const void *data, size_t len)
|
||||
{ return seat_output(seat, true, data, len); }
|
||||
|
||||
/*
|
||||
* Stub methods for seat implementations that want to use the obvious
|
||||
@ -1083,60 +1107,66 @@ struct TermWinVtable {
|
||||
bool (*is_utf8)(TermWin *);
|
||||
};
|
||||
|
||||
#define win_setup_draw_ctx(win) \
|
||||
((win)->vt->setup_draw_ctx(win))
|
||||
#define win_draw_text(win, x, y, text, len, attrs, lattrs, tc) \
|
||||
((win)->vt->draw_text(win, x, y, text, len, attrs, lattrs, tc))
|
||||
#define win_draw_cursor(win, x, y, text, len, attrs, lattrs, tc) \
|
||||
((win)->vt->draw_cursor(win, x, y, text, len, attrs, lattrs, tc))
|
||||
#define win_char_width(win, uc) \
|
||||
((win)->vt->char_width(win, uc))
|
||||
#define win_free_draw_ctx(win) \
|
||||
((win)->vt->free_draw_ctx(win))
|
||||
#define win_set_cursor_pos(win, x, y) \
|
||||
((win)->vt->set_cursor_pos(win, x, y))
|
||||
#define win_set_raw_mouse_mode(win, enable) \
|
||||
((win)->vt->set_raw_mouse_mode(win, enable))
|
||||
#define win_set_scrollbar(win, total, start, page) \
|
||||
((win)->vt->set_scrollbar(win, total, start, page))
|
||||
#define win_bell(win, mode) \
|
||||
((win)->vt->bell(win, mode))
|
||||
#define win_clip_write(win, clipboard, text, attrs, colours, len, desel) \
|
||||
((win)->vt->clip_write(win, clipboard, text, attrs, colours, len, desel))
|
||||
#define win_clip_request_paste(win, clipboard) \
|
||||
((win)->vt->clip_request_paste(win, clipboard))
|
||||
#define win_refresh(win) \
|
||||
((win)->vt->refresh(win))
|
||||
#define win_request_resize(win, w, h) \
|
||||
((win)->vt->request_resize(win, w, h))
|
||||
#define win_set_title(win, title) \
|
||||
((win)->vt->set_title(win, title))
|
||||
#define win_set_icon_title(win, ititle) \
|
||||
((win)->vt->set_icon_title(win, ititle))
|
||||
#define win_set_minimised(win, minimised) \
|
||||
((win)->vt->set_minimised(win, minimised))
|
||||
#define win_is_minimised(win) \
|
||||
((win)->vt->is_minimised(win))
|
||||
#define win_set_maximised(win, maximised) \
|
||||
((win)->vt->set_maximised(win, maximised))
|
||||
#define win_move(win, x, y) \
|
||||
((win)->vt->move(win, x, y))
|
||||
#define win_set_zorder(win, top) \
|
||||
((win)->vt->set_zorder(win, top))
|
||||
#define win_palette_get(win, n, r, g, b) \
|
||||
((win)->vt->palette_get(win, n, r, g, b))
|
||||
#define win_palette_set(win, n, r, g, b) \
|
||||
((win)->vt->palette_set(win, n, r, g, b))
|
||||
#define win_palette_reset(win) \
|
||||
((win)->vt->palette_reset(win))
|
||||
#define win_get_pos(win, x, y) \
|
||||
((win)->vt->get_pos(win, x, y))
|
||||
#define win_get_pixels(win, x, y) \
|
||||
((win)->vt->get_pixels(win, x, y))
|
||||
#define win_get_title(win, icon) \
|
||||
((win)->vt->get_title(win, icon))
|
||||
#define win_is_utf8(win) \
|
||||
((win)->vt->is_utf8(win))
|
||||
static inline bool win_setup_draw_ctx(TermWin *win)
|
||||
{ return win->vt->setup_draw_ctx(win); }
|
||||
static inline void win_draw_text(
|
||||
TermWin *win, int x, int y, wchar_t *text, int len,
|
||||
unsigned long attrs, int line_attrs, truecolour tc)
|
||||
{ win->vt->draw_text(win, x, y, text, len, attrs, line_attrs, tc); }
|
||||
static inline void win_draw_cursor(
|
||||
TermWin *win, int x, int y, wchar_t *text, int len,
|
||||
unsigned long attrs, int line_attrs, truecolour tc)
|
||||
{ win->vt->draw_cursor(win, x, y, text, len, attrs, line_attrs, tc); }
|
||||
static inline int win_char_width(TermWin *win, int uc)
|
||||
{ return win->vt->char_width(win, uc); }
|
||||
static inline void win_free_draw_ctx(TermWin *win)
|
||||
{ win->vt->free_draw_ctx(win); }
|
||||
static inline void win_set_cursor_pos(TermWin *win, int x, int y)
|
||||
{ win->vt->set_cursor_pos(win, x, y); }
|
||||
static inline void win_set_raw_mouse_mode(TermWin *win, bool enable)
|
||||
{ win->vt->set_raw_mouse_mode(win, enable); }
|
||||
static inline void win_set_scrollbar(TermWin *win, int t, int s, int p)
|
||||
{ win->vt->set_scrollbar(win, t, s, p); }
|
||||
static inline void win_bell(TermWin *win, int mode)
|
||||
{ win->vt->bell(win, mode); }
|
||||
static inline void win_clip_write(
|
||||
TermWin *win, int clipboard, wchar_t *text, int *attrs,
|
||||
truecolour *colours, int len, bool deselect)
|
||||
{ win->vt->clip_write(win, clipboard, text, attrs, colours, len, deselect); }
|
||||
static inline void win_clip_request_paste(TermWin *win, int clipboard)
|
||||
{ win->vt->clip_request_paste(win, clipboard); }
|
||||
static inline void win_refresh(TermWin *win)
|
||||
{ win->vt->refresh(win); }
|
||||
static inline void win_request_resize(TermWin *win, int w, int h)
|
||||
{ win->vt->request_resize(win, w, h); }
|
||||
static inline void win_set_title(TermWin *win, const char *title)
|
||||
{ win->vt->set_title(win, title); }
|
||||
static inline void win_set_icon_title(TermWin *win, const char *icontitle)
|
||||
{ win->vt->set_icon_title(win, icontitle); }
|
||||
static inline void win_set_minimised(TermWin *win, bool minimised)
|
||||
{ win->vt->set_minimised(win, minimised); }
|
||||
static inline bool win_is_minimised(TermWin *win)
|
||||
{ return win->vt->is_minimised(win); }
|
||||
static inline void win_set_maximised(TermWin *win, bool maximised)
|
||||
{ win->vt->set_maximised(win, maximised); }
|
||||
static inline void win_move(TermWin *win, int x, int y)
|
||||
{ win->vt->move(win, x, y); }
|
||||
static inline void win_set_zorder(TermWin *win, bool top)
|
||||
{ win->vt->set_zorder(win, top); }
|
||||
static inline bool win_palette_get(TermWin *win, int n, int *r, int *g, int *b)
|
||||
{ return win->vt->palette_get(win, n, r, g, b); }
|
||||
static inline void win_palette_set(TermWin *win, int n, int r, int g, int b)
|
||||
{ win->vt->palette_set(win, n, r, g, b); }
|
||||
static inline void win_palette_reset(TermWin *win)
|
||||
{ win->vt->palette_reset(win); }
|
||||
static inline void win_get_pos(TermWin *win, int *x, int *y)
|
||||
{ win->vt->get_pos(win, x, y); }
|
||||
static inline void win_get_pixels(TermWin *win, int *x, int *y)
|
||||
{ win->vt->get_pixels(win, x, y); }
|
||||
static inline const char *win_get_title(TermWin *win, bool icon)
|
||||
{ return win->vt->get_title(win, icon); }
|
||||
static inline bool win_is_utf8(TermWin *win)
|
||||
{ return win->vt->is_utf8(win); }
|
||||
|
||||
/*
|
||||
* Global functions not specific to a connection instance.
|
||||
@ -1606,9 +1636,15 @@ struct LogPolicyVtable {
|
||||
struct LogPolicy {
|
||||
const LogPolicyVtable *vt;
|
||||
};
|
||||
#define lp_eventlog(lp, event) ((lp)->vt->eventlog(lp, event))
|
||||
#define lp_askappend(lp, fn, cb, ctx) ((lp)->vt->askappend(lp, fn, cb, ctx))
|
||||
#define lp_logging_error(lp, event) ((lp)->vt->logging_error(lp, event))
|
||||
|
||||
static inline void lp_eventlog(LogPolicy *lp, const char *event)
|
||||
{ lp->vt->eventlog(lp, event); }
|
||||
static inline int lp_askappend(
|
||||
LogPolicy *lp, Filename *filename,
|
||||
void (*callback)(void *ctx, int result), void *ctx)
|
||||
{ return lp->vt->askappend(lp, filename, callback, ctx); }
|
||||
static inline void lp_logging_error(LogPolicy *lp, const char *event)
|
||||
{ lp->vt->logging_error(lp, event); }
|
||||
|
||||
LogContext *log_init(LogPolicy *lp, Conf *conf);
|
||||
void log_free(LogContext *logctx);
|
||||
|
134
sftp.h
134
sftp.h
@ -390,40 +390,58 @@ struct SftpServerVtable {
|
||||
int max_entries, bool omit_longname);
|
||||
};
|
||||
|
||||
#define sftpsrv_new(vt) \
|
||||
((vt)->new(vt))
|
||||
#define sftpsrv_free(srv) \
|
||||
((srv)->vt->free(srv))
|
||||
#define sftpsrv_realpath(srv, reply, path) \
|
||||
((srv)->vt->realpath(srv, reply, path))
|
||||
#define sftpsrv_open(srv, reply, path, flags, attrs) \
|
||||
((srv)->vt->open(srv, reply, path, flags, attrs))
|
||||
#define sftpsrv_opendir(srv, reply, path) \
|
||||
((srv)->vt->opendir(srv, reply, path))
|
||||
#define sftpsrv_close(srv, reply, handle) \
|
||||
((srv)->vt->close(srv, reply, handle))
|
||||
#define sftpsrv_mkdir(srv, reply, path, attrs) \
|
||||
((srv)->vt->mkdir(srv, reply, path, attrs))
|
||||
#define sftpsrv_rmdir(srv, reply, path) \
|
||||
((srv)->vt->rmdir(srv, reply, path))
|
||||
#define sftpsrv_remove(srv, reply, path) \
|
||||
((srv)->vt->remove(srv, reply, path))
|
||||
#define sftpsrv_rename(srv, reply, srcpath, dstpath) \
|
||||
((srv)->vt->rename(srv, reply, srcpath, dstpath))
|
||||
#define sftpsrv_stat(srv, reply, path, follow) \
|
||||
((srv)->vt->stat(srv, reply, path, follow))
|
||||
#define sftpsrv_fstat(srv, reply, handle) \
|
||||
((srv)->vt->fstat(srv, reply, handle))
|
||||
#define sftpsrv_setstat(srv, reply, path, attrs) \
|
||||
((srv)->vt->setstat(srv, reply, path, attrs))
|
||||
#define sftpsrv_fsetstat(srv, reply, handle, attrs) \
|
||||
((srv)->vt->fsetstat(srv, reply, handle, attrs))
|
||||
#define sftpsrv_read(srv, reply, handle, offset, length) \
|
||||
((srv)->vt->read(srv, reply, handle, offset, length))
|
||||
#define sftpsrv_write(srv, reply, handle, offset, data) \
|
||||
((srv)->vt->write(srv, reply, handle, offset, data))
|
||||
#define sftpsrv_readdir(srv, reply, handle, max, nolongname) \
|
||||
((srv)->vt->readdir(srv, reply, handle, max, nolongname))
|
||||
static inline SftpServer *sftpsrv_new(const SftpServerVtable *vt)
|
||||
{ return vt->new(vt); }
|
||||
static inline void sftpsrv_free(SftpServer *srv)
|
||||
{ srv->vt->free(srv); }
|
||||
static inline void sftpsrv_realpath(SftpServer *srv, SftpReplyBuilder *reply,
|
||||
ptrlen path)
|
||||
{ srv->vt->realpath(srv, reply, path); }
|
||||
static inline void sftpsrv_open(
|
||||
SftpServer *srv, SftpReplyBuilder *reply,
|
||||
ptrlen path, unsigned flags, struct fxp_attrs attrs)
|
||||
{ srv->vt->open(srv, reply, path, flags, attrs); }
|
||||
static inline void sftpsrv_opendir(
|
||||
SftpServer *srv, SftpReplyBuilder *reply, ptrlen path)
|
||||
{ srv->vt->opendir(srv, reply, path); }
|
||||
static inline void sftpsrv_close(
|
||||
SftpServer *srv, SftpReplyBuilder *reply, ptrlen handle)
|
||||
{ srv->vt->close(srv, reply, handle); }
|
||||
static inline void sftpsrv_mkdir(SftpServer *srv, SftpReplyBuilder *reply,
|
||||
ptrlen path, struct fxp_attrs attrs)
|
||||
{ srv->vt->mkdir(srv, reply, path, attrs); }
|
||||
static inline void sftpsrv_rmdir(
|
||||
SftpServer *srv, SftpReplyBuilder *reply, ptrlen path)
|
||||
{ srv->vt->rmdir(srv, reply, path); }
|
||||
static inline void sftpsrv_remove(
|
||||
SftpServer *srv, SftpReplyBuilder *reply, ptrlen path)
|
||||
{ srv->vt->remove(srv, reply, path); }
|
||||
static inline void sftpsrv_rename(SftpServer *srv, SftpReplyBuilder *reply,
|
||||
ptrlen srcpath, ptrlen dstpath)
|
||||
{ srv->vt->rename(srv, reply, srcpath, dstpath); }
|
||||
static inline void sftpsrv_stat(
|
||||
SftpServer *srv, SftpReplyBuilder *reply, ptrlen path, bool follow)
|
||||
{ srv->vt->stat(srv, reply, path, follow); }
|
||||
static inline void sftpsrv_fstat(
|
||||
SftpServer *srv, SftpReplyBuilder *reply, ptrlen handle)
|
||||
{ srv->vt->fstat(srv, reply, handle); }
|
||||
static inline void sftpsrv_setstat(SftpServer *srv, SftpReplyBuilder *reply,
|
||||
ptrlen path, struct fxp_attrs attrs)
|
||||
{ srv->vt->setstat(srv, reply, path, attrs); }
|
||||
static inline void sftpsrv_fsetstat(SftpServer *srv, SftpReplyBuilder *reply,
|
||||
ptrlen handle, struct fxp_attrs attrs)
|
||||
{ srv->vt->fsetstat(srv, reply, handle, attrs); }
|
||||
static inline void sftpsrv_read(
|
||||
SftpServer *srv, SftpReplyBuilder *reply,
|
||||
ptrlen handle, uint64_t offset, unsigned length)
|
||||
{ srv->vt->read(srv, reply, handle, offset, length); }
|
||||
static inline void sftpsrv_write(SftpServer *srv, SftpReplyBuilder *reply,
|
||||
ptrlen handle, uint64_t offset, ptrlen data)
|
||||
{ srv->vt->write(srv, reply, handle, offset, data); }
|
||||
static inline void sftpsrv_readdir(
|
||||
SftpServer *srv, SftpReplyBuilder *reply, ptrlen handle,
|
||||
int max_entries, bool omit_longname)
|
||||
{ srv->vt->readdir(srv, reply, handle, max_entries, omit_longname); }
|
||||
|
||||
typedef struct SftpReplyBuilderVtable SftpReplyBuilderVtable;
|
||||
struct SftpReplyBuilder {
|
||||
@ -442,22 +460,26 @@ struct SftpReplyBuilderVtable {
|
||||
void (*reply_attrs)(SftpReplyBuilder *reply, struct fxp_attrs attrs);
|
||||
};
|
||||
|
||||
#define fxp_reply_ok(reply) \
|
||||
((reply)->vt->reply_ok(reply))
|
||||
#define fxp_reply_error(reply, code, msg) \
|
||||
((reply)->vt->reply_error(reply, code, msg))
|
||||
#define fxp_reply_simple_name(reply, name) \
|
||||
((reply)->vt->reply_simple_name(reply, name))
|
||||
#define fxp_reply_name_count(reply, count) \
|
||||
((reply)->vt->reply_name_count(reply, count))
|
||||
#define fxp_reply_full_name(reply, name, longname, attrs) \
|
||||
((reply)->vt->reply_full_name(reply, name, longname, attrs))
|
||||
#define fxp_reply_handle(reply, handle) \
|
||||
((reply)->vt->reply_handle(reply, handle))
|
||||
#define fxp_reply_data(reply, data) \
|
||||
((reply)->vt->reply_data(reply, data))
|
||||
#define fxp_reply_attrs(reply, attrs) \
|
||||
((reply)->vt->reply_attrs(reply, attrs))
|
||||
static inline void fxp_reply_ok(SftpReplyBuilder *reply)
|
||||
{ reply->vt->reply_ok(reply); }
|
||||
static inline void fxp_reply_error(SftpReplyBuilder *reply, unsigned code,
|
||||
const char *msg)
|
||||
{ reply->vt->reply_error(reply, code, msg); }
|
||||
static inline void fxp_reply_simple_name(SftpReplyBuilder *reply, ptrlen name)
|
||||
{ reply->vt->reply_simple_name(reply, name); }
|
||||
static inline void fxp_reply_name_count(
|
||||
SftpReplyBuilder *reply, unsigned count)
|
||||
{ reply->vt->reply_name_count(reply, count); }
|
||||
static inline void fxp_reply_full_name(SftpReplyBuilder *reply, ptrlen name,
|
||||
ptrlen longname, struct fxp_attrs attrs)
|
||||
{ reply->vt->reply_full_name(reply, name, longname, attrs); }
|
||||
static inline void fxp_reply_handle(SftpReplyBuilder *reply, ptrlen handle)
|
||||
{ reply->vt->reply_handle(reply, handle); }
|
||||
static inline void fxp_reply_data(SftpReplyBuilder *reply, ptrlen data)
|
||||
{ reply->vt->reply_data(reply, data); }
|
||||
static inline void fxp_reply_attrs(
|
||||
SftpReplyBuilder *reply, struct fxp_attrs attrs)
|
||||
{ reply->vt->reply_attrs(reply, attrs); }
|
||||
|
||||
/*
|
||||
* The usual implementation of an SftpReplyBuilder, containing a
|
||||
@ -499,10 +521,14 @@ struct ScpServerVtable {
|
||||
void (*eof)(ScpServer *s);
|
||||
};
|
||||
|
||||
#define scp_free(s) ((s)->vt->free(s))
|
||||
#define scp_send(s, data, len) ((s)->vt->send(s, data, len))
|
||||
#define scp_throttle(s, th) ((s)->vt->throttle(s, th))
|
||||
#define scp_eof(s) ((s)->vt->eof(s))
|
||||
static inline void scp_free(ScpServer *s)
|
||||
{ s->vt->free(s); }
|
||||
static inline size_t scp_send(ScpServer *s, const void *data, size_t length)
|
||||
{ return s->vt->send(s, data, length); }
|
||||
static inline void scp_throttle(ScpServer *s, bool throttled)
|
||||
{ s->vt->throttle(s, throttled); }
|
||||
static inline void scp_eof(ScpServer *s)
|
||||
{ s->vt->eof(s); }
|
||||
|
||||
/*
|
||||
* Create an ScpServer by calling this function, giving it the command
|
||||
|
262
ssh.h
262
ssh.h
@ -306,50 +306,70 @@ struct ConnectionLayer {
|
||||
const struct ConnectionLayerVtable *vt;
|
||||
};
|
||||
|
||||
#define ssh_rportfwd_alloc(cl, sh, sp, dh, dp, af, ld, pfr, share) \
|
||||
((cl)->vt->rportfwd_alloc(cl, sh, sp, dh, dp, af, ld, pfr, share))
|
||||
#define ssh_rportfwd_remove(cl, rpf) ((cl)->vt->rportfwd_remove(cl, rpf))
|
||||
#define ssh_lportfwd_open(cl, h, p, desc, pi, chan) \
|
||||
((cl)->vt->lportfwd_open(cl, h, p, desc, pi, chan))
|
||||
#define ssh_serverside_x11_open(cl, chan, pi) \
|
||||
((cl)->vt->serverside_x11_open(cl, chan, pi))
|
||||
#define ssh_serverside_agent_open(cl, chan) \
|
||||
((cl)->vt->serverside_agent_open(cl, chan))
|
||||
#define ssh_session_open(cl, chan) \
|
||||
((cl)->vt->session_open(cl, chan))
|
||||
#define ssh_add_x11_display(cl, auth, disp) \
|
||||
((cl)->vt->add_x11_display(cl, auth, disp))
|
||||
#define ssh_add_sharing_x11_display(cl, auth, cs, ch) \
|
||||
((cl)->vt->add_sharing_x11_display(cl, auth, cs, ch))
|
||||
#define ssh_remove_sharing_x11_display(cl, fa) \
|
||||
((cl)->vt->remove_sharing_x11_display(cl, fa))
|
||||
#define ssh_send_packet_from_downstream(cl, id, type, pkt, len, log) \
|
||||
((cl)->vt->send_packet_from_downstream(cl, id, type, pkt, len, log))
|
||||
#define ssh_alloc_sharing_channel(cl, cs) \
|
||||
((cl)->vt->alloc_sharing_channel(cl, cs))
|
||||
#define ssh_delete_sharing_channel(cl, ch) \
|
||||
((cl)->vt->delete_sharing_channel(cl, ch))
|
||||
#define ssh_sharing_queue_global_request(cl, cs) \
|
||||
((cl)->vt->sharing_queue_global_request(cl, cs))
|
||||
#define ssh_sharing_no_more_downstreams(cl) \
|
||||
((cl)->vt->sharing_no_more_downstreams(cl))
|
||||
#define ssh_agent_forwarding_permitted(cl) \
|
||||
((cl)->vt->agent_forwarding_permitted(cl))
|
||||
#define ssh_terminal_size(cl, w, h) ((cl)->vt->terminal_size(cl, w, h))
|
||||
#define ssh_stdout_unthrottle(cl, bufsize) \
|
||||
((cl)->vt->stdout_unthrottle(cl, bufsize))
|
||||
#define ssh_stdin_backlog(cl) ((cl)->vt->stdin_backlog(cl))
|
||||
#define ssh_throttle_all_channels(cl, throttled) \
|
||||
((cl)->vt->throttle_all_channels(cl, throttled))
|
||||
#define ssh_ldisc_option(cl, option) ((cl)->vt->ldisc_option(cl, option))
|
||||
#define ssh_set_ldisc_option(cl, opt, val) \
|
||||
((cl)->vt->set_ldisc_option(cl, opt, val))
|
||||
#define ssh_enable_x_fwd(cl) ((cl)->vt->enable_x_fwd(cl))
|
||||
#define ssh_enable_agent_fwd(cl) ((cl)->vt->enable_agent_fwd(cl))
|
||||
#define ssh_set_wants_user_input(cl, wanted) \
|
||||
((cl)->vt->set_wants_user_input(cl, wanted))
|
||||
#define ssh_setup_server_x_forwarding(cl, conf, ap, ad, scr) \
|
||||
((cl)->vt->setup_server_x_forwarding(cl, conf, ap, ad, scr))
|
||||
static inline struct ssh_rportfwd *ssh_rportfwd_alloc(
|
||||
ConnectionLayer *cl, const char *sh, int sp, const char *dh, int dp,
|
||||
int af, const char *log, PortFwdRecord *pfr, ssh_sharing_connstate *cs)
|
||||
{ return cl->vt->rportfwd_alloc(cl, sh, sp, dh, dp, af, log, pfr, cs); }
|
||||
static inline void ssh_rportfwd_remove(
|
||||
ConnectionLayer *cl, struct ssh_rportfwd *rpf)
|
||||
{ cl->vt->rportfwd_remove(cl, rpf); }
|
||||
static inline SshChannel *ssh_lportfwd_open(
|
||||
ConnectionLayer *cl, const char *host, int port,
|
||||
const char *desc, const SocketPeerInfo *pi, Channel *chan)
|
||||
{ return cl->vt->lportfwd_open(cl, host, port, desc, pi, chan); }
|
||||
static inline SshChannel *ssh_session_open(ConnectionLayer *cl, Channel *chan)
|
||||
{ return cl->vt->session_open(cl, chan); }
|
||||
static inline SshChannel *ssh_serverside_x11_open(
|
||||
ConnectionLayer *cl, Channel *chan, const SocketPeerInfo *pi)
|
||||
{ return cl->vt->serverside_x11_open(cl, chan, pi); }
|
||||
static inline SshChannel *ssh_serverside_agent_open(
|
||||
ConnectionLayer *cl, Channel *chan)
|
||||
{ return cl->vt->serverside_agent_open(cl, chan); }
|
||||
static inline struct X11FakeAuth *ssh_add_x11_display(
|
||||
ConnectionLayer *cl, int authtype, struct X11Display *x11disp)
|
||||
{ return cl->vt->add_x11_display(cl, authtype, x11disp); }
|
||||
static inline struct X11FakeAuth *ssh_add_sharing_x11_display(
|
||||
ConnectionLayer *cl, int authtype, ssh_sharing_connstate *share_cs,
|
||||
share_channel *share_chan)
|
||||
{ return cl->vt->add_sharing_x11_display(cl, authtype, share_cs, share_chan); }
|
||||
static inline void ssh_remove_sharing_x11_display(
|
||||
ConnectionLayer *cl, struct X11FakeAuth *auth)
|
||||
{ cl->vt->remove_sharing_x11_display(cl, auth); }
|
||||
static inline void ssh_send_packet_from_downstream(
|
||||
ConnectionLayer *cl, unsigned id, int type,
|
||||
const void *pkt, int len, const char *log)
|
||||
{ cl->vt->send_packet_from_downstream(cl, id, type, pkt, len, log); }
|
||||
static inline unsigned ssh_alloc_sharing_channel(
|
||||
ConnectionLayer *cl, ssh_sharing_connstate *connstate)
|
||||
{ return cl->vt->alloc_sharing_channel(cl, connstate); }
|
||||
static inline void ssh_delete_sharing_channel(
|
||||
ConnectionLayer *cl, unsigned localid)
|
||||
{ cl->vt->delete_sharing_channel(cl, localid); }
|
||||
static inline void ssh_sharing_queue_global_request(
|
||||
ConnectionLayer *cl, ssh_sharing_connstate *connstate)
|
||||
{ cl->vt->sharing_queue_global_request(cl, connstate); }
|
||||
static inline void ssh_sharing_no_more_downstreams(ConnectionLayer *cl)
|
||||
{ cl->vt->sharing_no_more_downstreams(cl); }
|
||||
static inline bool ssh_agent_forwarding_permitted(ConnectionLayer *cl)
|
||||
{ return cl->vt->agent_forwarding_permitted(cl); }
|
||||
static inline void ssh_terminal_size(ConnectionLayer *cl, int w, int h)
|
||||
{ cl->vt->terminal_size(cl, w, h); }
|
||||
static inline void ssh_stdout_unthrottle(ConnectionLayer *cl, size_t bufsize)
|
||||
{ cl->vt->stdout_unthrottle(cl, bufsize); }
|
||||
static inline size_t ssh_stdin_backlog(ConnectionLayer *cl)
|
||||
{ return cl->vt->stdin_backlog(cl); }
|
||||
static inline void ssh_throttle_all_channels(ConnectionLayer *cl, bool thr)
|
||||
{ cl->vt->throttle_all_channels(cl, thr); }
|
||||
static inline bool ssh_ldisc_option(ConnectionLayer *cl, int option)
|
||||
{ return cl->vt->ldisc_option(cl, option); }
|
||||
static inline void ssh_set_ldisc_option(ConnectionLayer *cl, int opt, bool val)
|
||||
{ cl->vt->set_ldisc_option(cl, opt, val); }
|
||||
static inline void ssh_enable_x_fwd(ConnectionLayer *cl)
|
||||
{ cl->vt->enable_x_fwd(cl); }
|
||||
static inline void ssh_enable_agent_fwd(ConnectionLayer *cl)
|
||||
{ cl->vt->enable_agent_fwd(cl); }
|
||||
static inline void ssh_set_wants_user_input(ConnectionLayer *cl, bool wanted)
|
||||
{ cl->vt->set_wants_user_input(cl, wanted); }
|
||||
|
||||
/* Exports from portfwd.c */
|
||||
PortFwdManager *portfwdmgr_new(ConnectionLayer *cl);
|
||||
@ -600,17 +620,26 @@ struct ssh_cipheralg {
|
||||
const void *extra;
|
||||
};
|
||||
|
||||
#define ssh_cipher_new(alg) ((alg)->new(alg))
|
||||
#define ssh_cipher_free(ctx) ((ctx)->vt->free(ctx))
|
||||
#define ssh_cipher_setiv(ctx, iv) ((ctx)->vt->setiv(ctx, iv))
|
||||
#define ssh_cipher_setkey(ctx, key) ((ctx)->vt->setkey(ctx, key))
|
||||
#define ssh_cipher_encrypt(ctx, blk, len) ((ctx)->vt->encrypt(ctx, blk, len))
|
||||
#define ssh_cipher_decrypt(ctx, blk, len) ((ctx)->vt->decrypt(ctx, blk, len))
|
||||
#define ssh_cipher_encrypt_length(ctx, blk, len, seq) \
|
||||
((ctx)->vt->encrypt_length(ctx, blk, len, seq))
|
||||
#define ssh_cipher_decrypt_length(ctx, blk, len, seq) \
|
||||
((ctx)->vt->decrypt_length(ctx, blk, len, seq))
|
||||
#define ssh_cipher_alg(ctx) ((ctx)->vt)
|
||||
static inline ssh_cipher *ssh_cipher_new(const ssh_cipheralg *alg)
|
||||
{ return alg->new(alg); }
|
||||
static inline void ssh_cipher_free(ssh_cipher *c)
|
||||
{ c->vt->free(c); }
|
||||
static inline void ssh_cipher_setiv(ssh_cipher *c, const void *iv)
|
||||
{ c->vt->setiv(c, iv); }
|
||||
static inline void ssh_cipher_setkey(ssh_cipher *c, const void *key)
|
||||
{ c->vt->setkey(c, key); }
|
||||
static inline void ssh_cipher_encrypt(ssh_cipher *c, void *blk, int len)
|
||||
{ c->vt->encrypt(c, blk, len); }
|
||||
static inline void ssh_cipher_decrypt(ssh_cipher *c, void *blk, int len)
|
||||
{ c->vt->decrypt(c, blk, len); }
|
||||
static inline void ssh_cipher_encrypt_length(
|
||||
ssh_cipher *c, void *blk, int len, unsigned long seq)
|
||||
{ return c->vt->encrypt_length(c, blk, len, seq); }
|
||||
static inline void ssh_cipher_decrypt_length(
|
||||
ssh_cipher *c, void *blk, int len, unsigned long seq)
|
||||
{ return c->vt->decrypt_length(c, blk, len, seq); }
|
||||
static inline const struct ssh_cipheralg *ssh_cipher_alg(ssh_cipher *c)
|
||||
{ return c->vt; }
|
||||
|
||||
struct ssh2_ciphers {
|
||||
int nciphers;
|
||||
@ -637,13 +666,21 @@ struct ssh2_macalg {
|
||||
const void *extra;
|
||||
};
|
||||
|
||||
#define ssh2_mac_new(alg, cipher) ((alg)->new(alg, cipher))
|
||||
#define ssh2_mac_free(ctx) ((ctx)->vt->free(ctx))
|
||||
#define ssh2_mac_setkey(ctx, key) ((ctx)->vt->setkey(ctx, key))
|
||||
#define ssh2_mac_start(ctx) ((ctx)->vt->start(ctx))
|
||||
#define ssh2_mac_genresult(ctx, out) ((ctx)->vt->genresult(ctx, out))
|
||||
#define ssh2_mac_text_name(ctx) ((ctx)->vt->text_name(ctx))
|
||||
#define ssh2_mac_alg(ctx) ((ctx)->vt)
|
||||
static inline ssh2_mac *ssh2_mac_new(
|
||||
const ssh2_macalg *alg, ssh_cipher *cipher)
|
||||
{ return alg->new(alg, cipher); }
|
||||
static inline void ssh2_mac_free(ssh2_mac *m)
|
||||
{ m->vt->free(m); }
|
||||
static inline void ssh2_mac_setkey(ssh2_mac *m, ptrlen key)
|
||||
{ m->vt->setkey(m, key); }
|
||||
static inline void ssh2_mac_start(ssh2_mac *m)
|
||||
{ m->vt->start(m); }
|
||||
static inline void ssh2_mac_genresult(ssh2_mac *m, unsigned char *out)
|
||||
{ m->vt->genresult(m, out); }
|
||||
static inline const char *ssh2_mac_text_name(ssh2_mac *m)
|
||||
{ return m->vt->text_name(m); }
|
||||
static inline const ssh2_macalg *ssh2_mac_alg(ssh2_mac *m)
|
||||
{ return m->vt; }
|
||||
|
||||
/* Centralised 'methods' for ssh2_mac, defined in sshmac.c. These run
|
||||
* the MAC in a specifically SSH-2 style, i.e. taking account of a
|
||||
@ -673,11 +710,16 @@ struct ssh_hashalg {
|
||||
const char *text_name; /* both combined, e.g. "SHA-n (unaccelerated)" */
|
||||
};
|
||||
|
||||
#define ssh_hash_new(alg) ((alg)->new(alg))
|
||||
#define ssh_hash_copy(ctx) ((ctx)->vt->copy(ctx))
|
||||
#define ssh_hash_final(ctx, out) ((ctx)->vt->final(ctx, out))
|
||||
#define ssh_hash_free(ctx) ((ctx)->vt->free(ctx))
|
||||
#define ssh_hash_alg(ctx) ((ctx)->vt)
|
||||
static inline ssh_hash *ssh_hash_new(const ssh_hashalg *alg)
|
||||
{ return alg->new(alg); }
|
||||
static inline ssh_hash *ssh_hash_copy(ssh_hash *h)
|
||||
{ return h->vt->copy(h); }
|
||||
static inline void ssh_hash_final(ssh_hash *h, unsigned char *out)
|
||||
{ return h->vt->final(h, out); }
|
||||
static inline void ssh_hash_free(ssh_hash *h)
|
||||
{ return h->vt->free(h); }
|
||||
static inline const ssh_hashalg *ssh_hash_alg(ssh_hash *h)
|
||||
{ return h->vt; }
|
||||
|
||||
/* Handy macros for defining all those text-name fields at once */
|
||||
#define HASHALG_NAMES_BARE(base) \
|
||||
@ -725,25 +767,39 @@ struct ssh_keyalg {
|
||||
const unsigned supported_flags; /* signature-type flags we understand */
|
||||
};
|
||||
|
||||
#define ssh_key_new_pub(alg, data) ((alg)->new_pub(alg, data))
|
||||
#define ssh_key_new_priv(alg, pub, priv) ((alg)->new_priv(alg, pub, priv))
|
||||
#define ssh_key_new_priv_openssh(alg, bs) ((alg)->new_priv_openssh(alg, bs))
|
||||
|
||||
#define ssh_key_free(key) ((key)->vt->freekey(key))
|
||||
#define ssh_key_invalid(key, flags) ((key)->vt->invalid(key, flags))
|
||||
#define ssh_key_sign(key, data, flags, bs) \
|
||||
((key)->vt->sign(key, data, flags, bs))
|
||||
#define ssh_key_verify(key, sig, data) ((key)->vt->verify(key, sig, data))
|
||||
#define ssh_key_public_blob(key, bs) ((key)->vt->public_blob(key, bs))
|
||||
#define ssh_key_private_blob(key, bs) ((key)->vt->private_blob(key, bs))
|
||||
#define ssh_key_openssh_blob(key, bs) ((key)->vt->openssh_blob(key, bs))
|
||||
#define ssh_key_cache_str(key) ((key)->vt->cache_str(key))
|
||||
|
||||
#define ssh_key_public_bits(alg, blob) ((alg)->pubkey_bits(alg, blob))
|
||||
|
||||
#define ssh_key_alg(key) (key)->vt
|
||||
#define ssh_key_ssh_id(key) ((key)->vt->ssh_id)
|
||||
#define ssh_key_cache_id(key) ((key)->vt->cache_id)
|
||||
static inline ssh_key *ssh_key_new_pub(const ssh_keyalg *self, ptrlen pub)
|
||||
{ return self->new_pub(self, pub); }
|
||||
static inline ssh_key *ssh_key_new_priv(
|
||||
const ssh_keyalg *self, ptrlen pub, ptrlen priv)
|
||||
{ return self->new_priv(self, pub, priv); }
|
||||
static inline ssh_key *ssh_key_new_priv_openssh(
|
||||
const ssh_keyalg *self, BinarySource *src)
|
||||
{ return self->new_priv_openssh(self, src); }
|
||||
static inline void ssh_key_free(ssh_key *key)
|
||||
{ key->vt->freekey(key); }
|
||||
static inline char *ssh_key_invalid(ssh_key *key, unsigned flags)
|
||||
{ return key->vt->invalid(key, flags); }
|
||||
static inline void ssh_key_sign(
|
||||
ssh_key *key, ptrlen data, unsigned flags, BinarySink *bs)
|
||||
{ key->vt->sign(key, data, flags, bs); }
|
||||
static inline bool ssh_key_verify(ssh_key *key, ptrlen sig, ptrlen data)
|
||||
{ return key->vt->verify(key, sig, data); }
|
||||
static inline void ssh_key_public_blob(ssh_key *key, BinarySink *bs)
|
||||
{ key->vt->public_blob(key, bs); }
|
||||
static inline void ssh_key_private_blob(ssh_key *key, BinarySink *bs)
|
||||
{ key->vt->private_blob(key, bs); }
|
||||
static inline void ssh_key_openssh_blob(ssh_key *key, BinarySink *bs)
|
||||
{ key->vt->openssh_blob(key, bs); }
|
||||
static inline char *ssh_key_cache_str(ssh_key *key)
|
||||
{ return key->vt->cache_str(key); }
|
||||
static inline int ssh_key_public_bits(const ssh_keyalg *self, ptrlen blob)
|
||||
{ return self->pubkey_bits(self, blob); }
|
||||
static inline const ssh_keyalg *ssh_key_alg(ssh_key *key)
|
||||
{ return key->vt; }
|
||||
static inline const char *ssh_key_ssh_id(ssh_key *key)
|
||||
{ return key->vt->ssh_id; }
|
||||
static inline const char *ssh_key_cache_id(ssh_key *key)
|
||||
{ return key->vt->cache_id; }
|
||||
|
||||
/*
|
||||
* Enumeration of signature flags from draft-miller-ssh-agent-02
|
||||
@ -775,16 +831,30 @@ struct ssh_compression_alg {
|
||||
const char *text_name;
|
||||
};
|
||||
|
||||
#define ssh_compressor_new(alg) ((alg)->compress_new())
|
||||
#define ssh_compressor_free(comp) ((comp)->vt->compress_free(comp))
|
||||
#define ssh_compressor_compress(comp, in, inlen, out, outlen, minlen) \
|
||||
((comp)->vt->compress(comp, in, inlen, out, outlen, minlen))
|
||||
#define ssh_compressor_alg(comp) ((comp)->vt)
|
||||
#define ssh_decompressor_new(alg) ((alg)->decompress_new())
|
||||
#define ssh_decompressor_free(comp) ((comp)->vt->decompress_free(comp))
|
||||
#define ssh_decompressor_decompress(comp, in, inlen, out, outlen) \
|
||||
((comp)->vt->decompress(comp, in, inlen, out, outlen))
|
||||
#define ssh_decompressor_alg(comp) ((comp)->vt)
|
||||
static inline ssh_compressor *ssh_compressor_new(
|
||||
const ssh_compression_alg *alg)
|
||||
{ return alg->compress_new(); }
|
||||
static inline ssh_decompressor *ssh_decompressor_new(
|
||||
const ssh_compression_alg *alg)
|
||||
{ return alg->decompress_new(); }
|
||||
static inline void ssh_compressor_free(ssh_compressor *c)
|
||||
{ c->vt->compress_free(c); }
|
||||
static inline void ssh_decompressor_free(ssh_decompressor *d)
|
||||
{ d->vt->decompress_free(d); }
|
||||
static inline void ssh_compressor_compress(
|
||||
ssh_compressor *c, const unsigned char *block, int len,
|
||||
unsigned char **outblock, int *outlen, int minlen)
|
||||
{ c->vt->compress(c, block, len, outblock, outlen, minlen); }
|
||||
static inline bool ssh_decompressor_decompress(
|
||||
ssh_decompressor *d, const unsigned char *block, int len,
|
||||
unsigned char **outblock, int *outlen)
|
||||
{ return d->vt->decompress(d, block, len, outblock, outlen); }
|
||||
static inline const ssh_compression_alg *ssh_compressor_alg(
|
||||
ssh_compressor *c)
|
||||
{ return c->vt; }
|
||||
static inline const ssh_compression_alg *ssh_decompressor_alg(
|
||||
ssh_decompressor *d)
|
||||
{ return d->vt; }
|
||||
|
||||
struct ssh2_userkey {
|
||||
ssh_key *key; /* the key itself */
|
||||
|
14
sshbpp.h
14
sshbpp.h
@ -42,11 +42,15 @@ struct BinaryPacketProtocol {
|
||||
bool expect_close;
|
||||
};
|
||||
|
||||
#define ssh_bpp_handle_input(bpp) ((bpp)->vt->handle_input(bpp))
|
||||
#define ssh_bpp_handle_output(bpp) ((bpp)->vt->handle_output(bpp))
|
||||
#define ssh_bpp_new_pktout(bpp, type) ((bpp)->vt->new_pktout(type))
|
||||
#define ssh_bpp_queue_disconnect(bpp, msg, cat) \
|
||||
((bpp)->vt->queue_disconnect(bpp, msg, cat))
|
||||
static inline void ssh_bpp_handle_input(BinaryPacketProtocol *bpp)
|
||||
{ bpp->vt->handle_input(bpp); }
|
||||
static inline void ssh_bpp_handle_output(BinaryPacketProtocol *bpp)
|
||||
{ bpp->vt->handle_output(bpp); }
|
||||
static inline PktOut *ssh_bpp_new_pktout(BinaryPacketProtocol *bpp, int type)
|
||||
{ return bpp->vt->new_pktout(type); }
|
||||
static inline void ssh_bpp_queue_disconnect(BinaryPacketProtocol *bpp,
|
||||
const char *msg, int category)
|
||||
{ bpp->vt->queue_disconnect(bpp, msg, category); }
|
||||
|
||||
/* ssh_bpp_free is more than just a macro wrapper on the vtable; it
|
||||
* does centralised parts of the freeing too. */
|
||||
|
188
sshchan.h
188
sshchan.h
@ -62,43 +62,57 @@ struct Channel {
|
||||
unsigned initial_fixed_window_size;
|
||||
};
|
||||
|
||||
#define chan_free(ch) ((ch)->vt->free(ch))
|
||||
#define chan_open_confirmation(ch) ((ch)->vt->open_confirmation(ch))
|
||||
#define chan_open_failed(ch, err) ((ch)->vt->open_failed(ch, err))
|
||||
#define chan_send(ch, err, buf, len) ((ch)->vt->send(ch, err, buf, len))
|
||||
#define chan_send_eof(ch) ((ch)->vt->send_eof(ch))
|
||||
#define chan_set_input_wanted(ch, wanted) \
|
||||
((ch)->vt->set_input_wanted(ch, wanted))
|
||||
#define chan_log_close_msg(ch) ((ch)->vt->log_close_msg(ch))
|
||||
#define chan_want_close(ch, leof, reof) ((ch)->vt->want_close(ch, leof, reof))
|
||||
#define chan_rcvd_exit_status(ch, status) \
|
||||
((ch)->vt->rcvd_exit_status(ch, status))
|
||||
#define chan_rcvd_exit_signal(ch, sig, core, msg) \
|
||||
((ch)->vt->rcvd_exit_signal(ch, sig, core, msg))
|
||||
#define chan_rcvd_exit_signal_numeric(ch, sig, core, msg) \
|
||||
((ch)->vt->rcvd_exit_signal_numeric(ch, sig, core, msg))
|
||||
#define chan_run_shell(ch) \
|
||||
((ch)->vt->run_shell(ch))
|
||||
#define chan_run_command(ch, cmd) \
|
||||
((ch)->vt->run_command(ch, cmd))
|
||||
#define chan_run_subsystem(ch, subsys) \
|
||||
((ch)->vt->run_subsystem(ch, subsys))
|
||||
#define chan_enable_x11_forwarding(ch, oneshot, ap, ad, scr) \
|
||||
((ch)->vt->enable_x11_forwarding(ch, oneshot, ap, ad, scr))
|
||||
#define chan_enable_agent_forwarding(ch) \
|
||||
((ch)->vt->enable_agent_forwarding(ch))
|
||||
#define chan_allocate_pty(ch, termtype, w, h, pw, ph, modes) \
|
||||
((ch)->vt->allocate_pty(ch, termtype, w, h, pw, ph, modes))
|
||||
#define chan_set_env(ch, var, value) \
|
||||
((ch)->vt->set_env(ch, var, value))
|
||||
#define chan_send_break(ch, length) \
|
||||
((ch)->vt->send_break(ch, length))
|
||||
#define chan_send_signal(ch, signame) \
|
||||
((ch)->vt->send_signal(ch, signame))
|
||||
#define chan_change_window_size(ch, w, h, pw, ph) \
|
||||
((ch)->vt->change_window_size(ch, w, h, pw, ph))
|
||||
#define chan_request_response(ch, success) \
|
||||
((ch)->vt->request_response(ch, success))
|
||||
static inline void chan_free(Channel *ch)
|
||||
{ ch->vt->free(ch); }
|
||||
static inline void chan_open_confirmation(Channel *ch)
|
||||
{ ch->vt->open_confirmation(ch); }
|
||||
static inline void chan_open_failed(Channel *ch, const char *err)
|
||||
{ ch->vt->open_failed(ch, err); }
|
||||
static inline size_t chan_send(
|
||||
Channel *ch, bool err, const void *buf, size_t len)
|
||||
{ return ch->vt->send(ch, err, buf, len); }
|
||||
static inline void chan_send_eof(Channel *ch)
|
||||
{ ch->vt->send_eof(ch); }
|
||||
static inline void chan_set_input_wanted(Channel *ch, bool wanted)
|
||||
{ ch->vt->set_input_wanted(ch, wanted); }
|
||||
static inline char *chan_log_close_msg(Channel *ch)
|
||||
{ return ch->vt->log_close_msg(ch); }
|
||||
static inline bool chan_want_close(Channel *ch, bool leof, bool reof)
|
||||
{ return ch->vt->want_close(ch, leof, reof); }
|
||||
static inline bool chan_rcvd_exit_status(Channel *ch, int status)
|
||||
{ return ch->vt->rcvd_exit_status(ch, status); }
|
||||
static inline bool chan_rcvd_exit_signal(
|
||||
Channel *ch, ptrlen sig, bool core, ptrlen msg)
|
||||
{ return ch->vt->rcvd_exit_signal(ch, sig, core, msg); }
|
||||
static inline bool chan_rcvd_exit_signal_numeric(
|
||||
Channel *ch, int sig, bool core, ptrlen msg)
|
||||
{ return ch->vt->rcvd_exit_signal_numeric(ch, sig, core, msg); }
|
||||
static inline bool chan_run_shell(Channel *ch)
|
||||
{ return ch->vt->run_shell(ch); }
|
||||
static inline bool chan_run_command(Channel *ch, ptrlen cmd)
|
||||
{ return ch->vt->run_command(ch, cmd); }
|
||||
static inline bool chan_run_subsystem(Channel *ch, ptrlen subsys)
|
||||
{ return ch->vt->run_subsystem(ch, subsys); }
|
||||
static inline bool chan_enable_x11_forwarding(
|
||||
Channel *ch, bool oneshot, ptrlen ap, ptrlen ad, unsigned scr)
|
||||
{ return ch->vt->enable_x11_forwarding(ch, oneshot, ap, ad, scr); }
|
||||
static inline bool chan_enable_agent_forwarding(Channel *ch)
|
||||
{ return ch->vt->enable_agent_forwarding(ch); }
|
||||
static inline bool chan_allocate_pty(
|
||||
Channel *ch, ptrlen termtype, unsigned w, unsigned h,
|
||||
unsigned pw, unsigned ph, struct ssh_ttymodes modes)
|
||||
{ return ch->vt->allocate_pty(ch, termtype, w, h, pw, ph, modes); }
|
||||
static inline bool chan_set_env(Channel *ch, ptrlen var, ptrlen value)
|
||||
{ return ch->vt->set_env(ch, var, value); }
|
||||
static inline bool chan_send_break(Channel *ch, unsigned length)
|
||||
{ return ch->vt->send_break(ch, length); }
|
||||
static inline bool chan_send_signal(Channel *ch, ptrlen signame)
|
||||
{ return ch->vt->send_signal(ch, signame); }
|
||||
static inline bool chan_change_window_size(
|
||||
Channel *ch, unsigned w, unsigned h, unsigned pw, unsigned ph)
|
||||
{ return ch->vt->change_window_size(ch, w, h, pw, ph); }
|
||||
static inline void chan_request_response(Channel *ch, bool success)
|
||||
{ ch->vt->request_response(ch, success); }
|
||||
|
||||
/*
|
||||
* Reusable methods you can put in vtables to give default handling of
|
||||
@ -217,44 +231,68 @@ struct SshChannel {
|
||||
ConnectionLayer *cl;
|
||||
};
|
||||
|
||||
#define sshfwd_write(c, buf, len) ((c)->vt->write(c, false, buf, len))
|
||||
#define sshfwd_write_ext(c, stderr, buf, len) \
|
||||
((c)->vt->write(c, stderr, buf, len))
|
||||
#define sshfwd_write_eof(c) ((c)->vt->write_eof(c))
|
||||
#define sshfwd_initiate_close(c, err) ((c)->vt->initiate_close(c, err))
|
||||
#define sshfwd_unthrottle(c, bufsize) ((c)->vt->unthrottle(c, bufsize))
|
||||
#define sshfwd_get_conf(c) ((c)->vt->get_conf(c))
|
||||
#define sshfwd_window_override_removed(c) ((c)->vt->window_override_removed(c))
|
||||
#define sshfwd_x11_sharing_handover(c, cs, ch, pa, pp, e, pmaj, pmin, d, l) \
|
||||
((c)->vt->x11_sharing_handover(c, cs, ch, pa, pp, e, pmaj, pmin, d, l))
|
||||
#define sshfwd_send_exit_status(c, status) \
|
||||
((c)->vt->send_exit_status(c, status))
|
||||
#define sshfwd_send_exit_signal(c, sig, core, msg) \
|
||||
((c)->vt->send_exit_signal(c, sig, core, msg))
|
||||
#define sshfwd_send_exit_signal_numeric(c, sig, core, msg) \
|
||||
((c)->vt->send_exit_signal_numeric(c, sig, core, msg))
|
||||
#define sshfwd_request_x11_forwarding(c, wr, ap, ad, scr, oneshot) \
|
||||
((c)->vt->request_x11_forwarding(c, wr, ap, ad, scr, oneshot))
|
||||
#define sshfwd_request_agent_forwarding(c, wr) \
|
||||
((c)->vt->request_agent_forwarding(c, wr))
|
||||
#define sshfwd_request_pty(c, wr, conf, w, h) \
|
||||
((c)->vt->request_pty(c, wr, conf, w, h))
|
||||
#define sshfwd_send_env_var(c, wr, var, value) \
|
||||
((c)->vt->send_env_var(c, wr, var, value))
|
||||
#define sshfwd_start_shell(c, wr) \
|
||||
((c)->vt->start_shell(c, wr))
|
||||
#define sshfwd_start_command(c, wr, cmd) \
|
||||
((c)->vt->start_command(c, wr, cmd))
|
||||
#define sshfwd_start_subsystem(c, wr, subsys) \
|
||||
((c)->vt->start_subsystem(c, wr, subsys))
|
||||
#define sshfwd_send_serial_break(c, wr, length) \
|
||||
((c)->vt->send_serial_break(c, wr, length))
|
||||
#define sshfwd_send_signal(c, wr, sig) \
|
||||
((c)->vt->send_signal(c, wr, sig))
|
||||
#define sshfwd_send_terminal_size_change(c, w, h) \
|
||||
((c)->vt->send_terminal_size_change(c, w, h))
|
||||
#define sshfwd_hint_channel_is_simple(c) \
|
||||
((c)->vt->hint_channel_is_simple(c))
|
||||
static inline size_t sshfwd_write_ext(
|
||||
SshChannel *c, bool is_stderr, const void *data, size_t len)
|
||||
{ return c->vt->write(c, is_stderr, data, len); }
|
||||
static inline size_t sshfwd_write(SshChannel *c, const void *data, size_t len)
|
||||
{ return sshfwd_write_ext(c, false, data, len); }
|
||||
static inline void sshfwd_write_eof(SshChannel *c)
|
||||
{ c->vt->write_eof(c); }
|
||||
static inline void sshfwd_initiate_close(SshChannel *c, const char *err)
|
||||
{ c->vt->initiate_close(c, err); }
|
||||
static inline void sshfwd_unthrottle(SshChannel *c, size_t bufsize)
|
||||
{ c->vt->unthrottle(c, bufsize); }
|
||||
static inline Conf *sshfwd_get_conf(SshChannel *c)
|
||||
{ return c->vt->get_conf(c); }
|
||||
static inline void sshfwd_window_override_removed(SshChannel *c)
|
||||
{ c->vt->window_override_removed(c); }
|
||||
static inline void sshfwd_x11_sharing_handover(
|
||||
SshChannel *c, ssh_sharing_connstate *cs, share_channel *sch,
|
||||
const char *addr, int port, int endian, int maj, int min,
|
||||
const void *idata, int ilen)
|
||||
{ return c->vt->x11_sharing_handover(c, cs, sch, addr, port, endian,
|
||||
maj, min, idata, ilen); }
|
||||
static inline void sshfwd_send_exit_status(SshChannel *c, int status)
|
||||
{ c->vt->send_exit_status(c, status); }
|
||||
static inline void sshfwd_send_exit_signal(
|
||||
SshChannel *c, ptrlen signame, bool core_dumped, ptrlen msg)
|
||||
{ c->vt->send_exit_signal(c, signame, core_dumped, msg); }
|
||||
static inline void sshfwd_send_exit_signal_numeric(
|
||||
SshChannel *c, int signum, bool core_dumped, ptrlen msg)
|
||||
{ c->vt->send_exit_signal_numeric(c, signum, core_dumped, msg); }
|
||||
static inline void sshfwd_request_x11_forwarding(
|
||||
SshChannel *c, bool want_reply, const char *proto,
|
||||
const char *data, int scr, bool once)
|
||||
{ c->vt->request_x11_forwarding(c, want_reply, proto, data, scr, once); }
|
||||
static inline void sshfwd_request_agent_forwarding(
|
||||
SshChannel *c, bool want_reply)
|
||||
{ c->vt->request_agent_forwarding(c, want_reply); }
|
||||
static inline void sshfwd_request_pty(
|
||||
SshChannel *c, bool want_reply, Conf *conf, int w, int h)
|
||||
{ c->vt->request_pty(c, want_reply, conf, w, h); }
|
||||
static inline bool sshfwd_send_env_var(
|
||||
SshChannel *c, bool want_reply, const char *var, const char *value)
|
||||
{ return c->vt->send_env_var(c, want_reply, var, value); }
|
||||
static inline void sshfwd_start_shell(
|
||||
SshChannel *c, bool want_reply)
|
||||
{ c->vt->start_shell(c, want_reply); }
|
||||
static inline void sshfwd_start_command(
|
||||
SshChannel *c, bool want_reply, const char *command)
|
||||
{ c->vt->start_command(c, want_reply, command); }
|
||||
static inline bool sshfwd_start_subsystem(
|
||||
SshChannel *c, bool want_reply, const char *subsystem)
|
||||
{ return c->vt->start_subsystem(c, want_reply, subsystem); }
|
||||
static inline bool sshfwd_send_serial_break(
|
||||
SshChannel *c, bool want_reply, int length)
|
||||
{ return c->vt->send_serial_break(c, want_reply, length); }
|
||||
static inline bool sshfwd_send_signal(
|
||||
SshChannel *c, bool want_reply, const char *signame)
|
||||
{ return c->vt->send_signal(c, want_reply, signame); }
|
||||
static inline void sshfwd_send_terminal_size_change(
|
||||
SshChannel *c, int w, int h)
|
||||
{ c->vt->send_terminal_size_change(c, w, h); }
|
||||
static inline void sshfwd_hint_channel_is_simple(SshChannel *c)
|
||||
{ c->vt->hint_channel_is_simple(c); }
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* The 'main' or primary channel of the SSH connection is special,
|
||||
|
22
sshppl.h
22
sshppl.h
@ -59,14 +59,20 @@ struct PacketProtocolLayer {
|
||||
unsigned remote_bugs;
|
||||
};
|
||||
|
||||
#define ssh_ppl_process_queue(ppl) ((ppl)->vt->process_queue(ppl))
|
||||
#define ssh_ppl_get_specials(ppl, add, ctx) \
|
||||
((ppl)->vt->get_specials(ppl, add, ctx))
|
||||
#define ssh_ppl_special_cmd(ppl, code, arg) \
|
||||
((ppl)->vt->special_cmd(ppl, code, arg))
|
||||
#define ssh_ppl_want_user_input(ppl) ((ppl)->vt->want_user_input(ppl))
|
||||
#define ssh_ppl_got_user_input(ppl) ((ppl)->vt->got_user_input(ppl))
|
||||
#define ssh_ppl_reconfigure(ppl, conf) ((ppl)->vt->reconfigure(ppl, conf))
|
||||
static inline void ssh_ppl_process_queue(PacketProtocolLayer *ppl)
|
||||
{ ppl->vt->process_queue(ppl); }
|
||||
static inline bool ssh_ppl_get_specials(
|
||||
PacketProtocolLayer *ppl, add_special_fn_t add_special, void *ctx)
|
||||
{ return ppl->vt->get_specials(ppl, add_special, ctx); }
|
||||
static inline void ssh_ppl_special_cmd(
|
||||
PacketProtocolLayer *ppl, SessionSpecialCode code, int arg)
|
||||
{ ppl->vt->special_cmd(ppl, code, arg); }
|
||||
static inline bool ssh_ppl_want_user_input(PacketProtocolLayer *ppl)
|
||||
{ return ppl->vt->want_user_input(ppl); }
|
||||
static inline void ssh_ppl_got_user_input(PacketProtocolLayer *ppl)
|
||||
{ ppl->vt->got_user_input(ppl); }
|
||||
static inline void ssh_ppl_reconfigure(PacketProtocolLayer *ppl, Conf *conf)
|
||||
{ ppl->vt->reconfigure(ppl, conf); }
|
||||
|
||||
/* ssh_ppl_free is more than just a macro wrapper on the vtable; it
|
||||
* does centralised parts of the freeing too. */
|
||||
|
Loading…
Reference in New Issue
Block a user