server.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605
  1. /*
  2. * Top-level code for SSH server implementation.
  3. */
  4. #include <assert.h>
  5. #include <stddef.h>
  6. #include "putty.h"
  7. #include "ssh.h"
  8. #include "bpp.h"
  9. #include "ppl.h"
  10. #include "channel.h"
  11. #include "server.h"
  12. #ifndef NO_GSSAPI
  13. #include "gssc.h"
  14. #include "gss.h"
  15. #endif
  16. struct Ssh { int dummy; };
  17. typedef struct server server;
  18. struct server {
  19. bufchain in_raw, out_raw;
  20. IdempotentCallback ic_out_raw;
  21. bool pending_close;
  22. bufchain dummy_user_input; /* we never put anything on this */
  23. PacketLogSettings pls;
  24. LogContext *logctx;
  25. struct DataTransferStats stats;
  26. int remote_bugs;
  27. Socket *socket;
  28. Plug plug;
  29. int conn_throttle_count;
  30. bool frozen;
  31. Conf *conf;
  32. const SshServerConfig *ssc;
  33. ssh_key *const *hostkeys;
  34. int nhostkeys;
  35. RSAKey *hostkey1;
  36. AuthPolicy *authpolicy;
  37. LogPolicy *logpolicy;
  38. const SftpServerVtable *sftpserver_vt;
  39. agentfwd *stunt_agentfwd;
  40. Seat seat;
  41. Ssh ssh;
  42. struct ssh_version_receiver version_receiver;
  43. BinaryPacketProtocol *bpp;
  44. PacketProtocolLayer *base_layer;
  45. ConnectionLayer *cl;
  46. #ifndef NO_GSSAPI
  47. struct ssh_connection_shared_gss_state gss_state;
  48. #endif
  49. };
  50. static void ssh_server_free_callback(void *vsrv);
  51. static void server_got_ssh_version(struct ssh_version_receiver *rcv,
  52. int major_version);
  53. static void server_connect_bpp(server *srv);
  54. static void server_bpp_output_raw_data_callback(void *vctx);
  55. void share_activate(ssh_sharing_state *sharestate,
  56. const char *server_verstring) {}
  57. void ssh_connshare_provide_connlayer(ssh_sharing_state *sharestate,
  58. ConnectionLayer *cl) {}
  59. int share_ndownstreams(ssh_sharing_state *sharestate) { return 0; }
  60. void share_got_pkt_from_server(ssh_sharing_connstate *cs, int type,
  61. const void *vpkt, int pktlen) {}
  62. void share_setup_x11_channel(ssh_sharing_connstate *cs, share_channel *chan,
  63. unsigned upstream_id, unsigned server_id,
  64. unsigned server_currwin, unsigned server_maxpkt,
  65. unsigned client_adjusted_window,
  66. const char *peer_addr, int peer_port, int endian,
  67. int protomajor, int protominor,
  68. const void *initial_data, int initial_len) {}
  69. Channel *agentf_new(SshChannel *c) { return NULL; }
  70. bool agent_exists(void) { return false; }
  71. void ssh_got_exitcode(Ssh *ssh, int exitcode) {}
  72. void ssh_check_frozen(Ssh *ssh) {}
  73. mainchan *mainchan_new(
  74. PacketProtocolLayer *ppl, ConnectionLayer *cl, Conf *conf,
  75. int term_width, int term_height, bool is_simple, SshChannel **sc_out)
  76. { return NULL; }
  77. void mainchan_get_specials(
  78. mainchan *mc, add_special_fn_t add_special, void *ctx) {}
  79. void mainchan_special_cmd(mainchan *mc, SessionSpecialCode code, int arg) {}
  80. void mainchan_terminal_size(mainchan *mc, int width, int height) {}
  81. /* Seat functions to ensure we don't get choosy about crypto - as the
  82. * server, it's not up to us to give user warnings */
  83. static SeatPromptResult server_confirm_weak_crypto_primitive(
  84. Seat *seat, SeatDialogText *text,
  85. void (*callback)(void *ctx, SeatPromptResult result), void *ctx)
  86. { return SPR_OK; }
  87. static SeatPromptResult server_confirm_weak_cached_hostkey(
  88. Seat *seat, SeatDialogText *text,
  89. void (*callback)(void *ctx, SeatPromptResult result), void *ctx)
  90. { return SPR_OK; }
  91. static const SeatVtable server_seat_vt = {
  92. .output = nullseat_output,
  93. .eof = nullseat_eof,
  94. .sent = nullseat_sent,
  95. .banner = nullseat_banner,
  96. .get_userpass_input = nullseat_get_userpass_input,
  97. .notify_session_started = nullseat_notify_session_started,
  98. .notify_remote_exit = nullseat_notify_remote_exit,
  99. .notify_remote_disconnect = nullseat_notify_remote_disconnect,
  100. .connection_fatal = nullseat_connection_fatal,
  101. .nonfatal = nullseat_nonfatal,
  102. .update_specials_menu = nullseat_update_specials_menu,
  103. .get_ttymode = nullseat_get_ttymode,
  104. .set_busy_status = nullseat_set_busy_status,
  105. .confirm_ssh_host_key = nullseat_confirm_ssh_host_key,
  106. .confirm_weak_crypto_primitive = server_confirm_weak_crypto_primitive,
  107. .confirm_weak_cached_hostkey = server_confirm_weak_cached_hostkey,
  108. .prompt_descriptions = nullseat_prompt_descriptions,
  109. .is_utf8 = nullseat_is_never_utf8,
  110. .echoedit_update = nullseat_echoedit_update,
  111. .get_x_display = nullseat_get_x_display,
  112. .get_windowid = nullseat_get_windowid,
  113. .get_window_pixel_size = nullseat_get_window_pixel_size,
  114. .stripctrl_new = nullseat_stripctrl_new,
  115. .set_trust_status = nullseat_set_trust_status,
  116. .can_set_trust_status = nullseat_can_set_trust_status_no,
  117. .has_mixed_input_stream = nullseat_has_mixed_input_stream_no,
  118. .verbose = nullseat_verbose_no,
  119. .interactive = nullseat_interactive_no,
  120. .get_cursor_position = nullseat_get_cursor_position,
  121. };
  122. static void server_closing(Plug *plug, PlugCloseType type,
  123. const char *error_msg)
  124. {
  125. server *srv = container_of(plug, server, plug);
  126. if (type != PLUGCLOSE_NORMAL) {
  127. ssh_remote_error(&srv->ssh, "%s", error_msg);
  128. } else if (srv->bpp) {
  129. srv->bpp->input_eof = true;
  130. queue_idempotent_callback(&srv->bpp->ic_in_raw);
  131. }
  132. }
  133. static void server_receive(
  134. Plug *plug, int urgent, const char *data, size_t len)
  135. {
  136. server *srv = container_of(plug, server, plug);
  137. /* Log raw data, if we're in that mode. */
  138. if (srv->logctx)
  139. log_packet(srv->logctx, PKT_INCOMING, -1, NULL, data, len,
  140. 0, NULL, NULL, 0, NULL);
  141. bufchain_add(&srv->in_raw, data, len);
  142. if (!srv->frozen && srv->bpp)
  143. queue_idempotent_callback(&srv->bpp->ic_in_raw);
  144. }
  145. static void server_sent(Plug *plug, size_t bufsize)
  146. {
  147. #ifdef FIXME
  148. server *srv = container_of(plug, server, plug);
  149. /*
  150. * If the send backlog on the SSH socket itself clears, we should
  151. * unthrottle the whole world if it was throttled. Also trigger an
  152. * extra call to the consumer of the BPP's output, to try to send
  153. * some more data off its bufchain.
  154. */
  155. if (bufsize < SSH_MAX_BACKLOG) {
  156. srv_throttle_all(srv, 0, bufsize);
  157. queue_idempotent_callback(&srv->ic_out_raw);
  158. }
  159. #endif
  160. }
  161. LogContext *ssh_get_logctx(Ssh *ssh)
  162. {
  163. server *srv = container_of(ssh, server, ssh);
  164. return srv->logctx;
  165. }
  166. void ssh_sendbuffer_changed(Ssh *ssh)
  167. {
  168. }
  169. void ssh_throttle_conn(Ssh *ssh, int adjust)
  170. {
  171. server *srv = container_of(ssh, server, ssh);
  172. int old_count = srv->conn_throttle_count;
  173. bool frozen;
  174. srv->conn_throttle_count += adjust;
  175. assert(srv->conn_throttle_count >= 0);
  176. if (srv->conn_throttle_count && !old_count) {
  177. frozen = true;
  178. } else if (!srv->conn_throttle_count && old_count) {
  179. frozen = false;
  180. } else {
  181. return; /* don't change current frozen state */
  182. }
  183. srv->frozen = frozen;
  184. if (srv->socket) {
  185. sk_set_frozen(srv->socket, frozen);
  186. /*
  187. * Now process any SSH connection data that was stashed in our
  188. * queue while we were frozen.
  189. */
  190. queue_idempotent_callback(&srv->bpp->ic_in_raw);
  191. }
  192. }
  193. void ssh_conn_processed_data(Ssh *ssh)
  194. {
  195. /* FIXME: we could add the same check_frozen_state system as we
  196. * have in ssh.c, but because that was originally added to work
  197. * around a peculiarity of the GUI event loop, I haven't yet. */
  198. }
  199. Conf *make_ssh_server_conf(void)
  200. {
  201. Conf *conf = conf_new();
  202. load_open_settings(NULL, conf);
  203. /* In Uppity, we support even the legacy des-cbc cipher by
  204. * default, so that it will be available if the user forces it by
  205. * overriding the KEXINIT strings. If the user wants it _not_
  206. * supported, of course, they can override KEXINIT in the other
  207. * direction. */
  208. conf_set_bool(conf, CONF_ssh2_des_cbc, true);
  209. return conf;
  210. }
  211. void ssh_check_sendok(Ssh *ssh) {}
  212. static const PlugVtable ssh_server_plugvt = {
  213. .log = nullplug_log,
  214. .closing = server_closing,
  215. .receive = server_receive,
  216. .sent = server_sent,
  217. };
  218. Plug *ssh_server_plug(
  219. Conf *conf, const SshServerConfig *ssc,
  220. ssh_key *const *hostkeys, int nhostkeys,
  221. RSAKey *hostkey1, AuthPolicy *authpolicy, LogPolicy *logpolicy,
  222. const SftpServerVtable *sftpserver_vt)
  223. {
  224. server *srv = snew(server);
  225. memset(srv, 0, sizeof(server));
  226. srv->plug.vt = &ssh_server_plugvt;
  227. srv->conf = conf_copy(conf);
  228. srv->ssc = ssc;
  229. srv->logctx = log_init(logpolicy, conf);
  230. conf_set_bool(srv->conf, CONF_ssh_no_shell, true);
  231. srv->nhostkeys = nhostkeys;
  232. srv->hostkeys = hostkeys;
  233. srv->hostkey1 = hostkey1;
  234. srv->authpolicy = authpolicy;
  235. srv->logpolicy = logpolicy;
  236. srv->sftpserver_vt = sftpserver_vt;
  237. srv->seat.vt = &server_seat_vt;
  238. bufchain_init(&srv->in_raw);
  239. bufchain_init(&srv->out_raw);
  240. bufchain_init(&srv->dummy_user_input);
  241. #ifndef NO_GSSAPI
  242. /* FIXME: replace with sensible */
  243. srv->gss_state.libs = snew(struct ssh_gss_liblist);
  244. srv->gss_state.libs->nlibraries = 0;
  245. #endif
  246. return &srv->plug;
  247. }
  248. void ssh_server_start(Plug *plug, Socket *socket)
  249. {
  250. server *srv = container_of(plug, server, plug);
  251. const char *our_protoversion;
  252. if (srv->ssc->bare_connection) {
  253. our_protoversion = "2.0"; /* SSH-2 only */
  254. } else if (srv->hostkey1 && srv->nhostkeys) {
  255. our_protoversion = "1.99"; /* offer both SSH-1 and SSH-2 */
  256. } else if (srv->hostkey1) {
  257. our_protoversion = "1.5"; /* SSH-1 only */
  258. } else {
  259. assert(srv->nhostkeys);
  260. our_protoversion = "2.0"; /* SSH-2 only */
  261. }
  262. srv->socket = socket;
  263. srv->ic_out_raw.fn = server_bpp_output_raw_data_callback;
  264. srv->ic_out_raw.ctx = srv;
  265. srv->version_receiver.got_ssh_version = server_got_ssh_version;
  266. srv->bpp = ssh_verstring_new(
  267. srv->conf, srv->logctx, srv->ssc->bare_connection,
  268. our_protoversion, &srv->version_receiver,
  269. true, srv->ssc->application_name);
  270. server_connect_bpp(srv);
  271. queue_idempotent_callback(&srv->bpp->ic_in_raw);
  272. }
  273. static void ssh_server_free_callback(void *vsrv)
  274. {
  275. server *srv = (server *)vsrv;
  276. logeventf(srv->logctx, "freeing server instance");
  277. bufchain_clear(&srv->in_raw);
  278. bufchain_clear(&srv->out_raw);
  279. bufchain_clear(&srv->dummy_user_input);
  280. if (srv->socket)
  281. sk_close(srv->socket);
  282. if (srv->stunt_agentfwd)
  283. agentfwd_free(srv->stunt_agentfwd);
  284. if (srv->base_layer)
  285. ssh_ppl_free(srv->base_layer);
  286. if (srv->bpp)
  287. ssh_bpp_free(srv->bpp);
  288. delete_callbacks_for_context(srv);
  289. conf_free(srv->conf);
  290. log_free(srv->logctx);
  291. #ifndef NO_GSSAPI
  292. sfree(srv->gss_state.libs); /* FIXME: replace with sensible */
  293. #endif
  294. LogPolicy *lp = srv->logpolicy;
  295. sfree(srv);
  296. server_instance_terminated(lp);
  297. }
  298. static void server_connect_bpp(server *srv)
  299. {
  300. srv->bpp->ssh = &srv->ssh;
  301. srv->bpp->in_raw = &srv->in_raw;
  302. srv->bpp->out_raw = &srv->out_raw;
  303. bufchain_set_callback(srv->bpp->out_raw, &srv->ic_out_raw);
  304. srv->bpp->pls = &srv->pls;
  305. srv->bpp->logctx = srv->logctx;
  306. srv->bpp->remote_bugs = srv->remote_bugs;
  307. /* Servers don't really have a notion of 'unexpected' connection
  308. * closure. The client is free to close if it likes. */
  309. srv->bpp->expect_close = true;
  310. }
  311. static void server_connect_ppl(server *srv, PacketProtocolLayer *ppl)
  312. {
  313. ppl->bpp = srv->bpp;
  314. ppl->logctx = srv->logctx;
  315. ppl->ssh = &srv->ssh;
  316. ppl->seat = &srv->seat;
  317. ppl->interactor = NULL;
  318. ppl->remote_bugs = srv->remote_bugs;
  319. }
  320. static void server_bpp_output_raw_data_callback(void *vctx)
  321. {
  322. server *srv = (server *)vctx;
  323. if (!srv->socket)
  324. return;
  325. while (bufchain_size(&srv->out_raw) > 0) {
  326. size_t backlog;
  327. ptrlen data = bufchain_prefix(&srv->out_raw);
  328. if (srv->logctx)
  329. log_packet(srv->logctx, PKT_OUTGOING, -1, NULL, data.ptr, data.len,
  330. 0, NULL, NULL, 0, NULL);
  331. backlog = sk_write(srv->socket, data.ptr, data.len);
  332. bufchain_consume(&srv->out_raw, data.len);
  333. if (backlog > SSH_MAX_BACKLOG) {
  334. #ifdef FIXME
  335. ssh_throttle_all(ssh, 1, backlog);
  336. #endif
  337. return;
  338. }
  339. }
  340. if (srv->pending_close) {
  341. sk_close(srv->socket);
  342. srv->socket = NULL;
  343. queue_toplevel_callback(ssh_server_free_callback, srv);
  344. }
  345. }
  346. static void server_shutdown_internal(server *srv)
  347. {
  348. /*
  349. * We only need to free the base PPL, which will free the others
  350. * (if any) transitively.
  351. */
  352. if (srv->base_layer) {
  353. ssh_ppl_free(srv->base_layer);
  354. srv->base_layer = NULL;
  355. }
  356. srv->cl = NULL;
  357. }
  358. static void server_initiate_connection_close(server *srv)
  359. {
  360. /* Wind up everything above the BPP. */
  361. server_shutdown_internal(srv);
  362. /* Force any remaining queued SSH packets through the BPP, and
  363. * schedule closing the network socket after they go out. */
  364. ssh_bpp_handle_output(srv->bpp);
  365. srv->pending_close = true;
  366. queue_idempotent_callback(&srv->ic_out_raw);
  367. /* Now we expect the other end to close the connection too in
  368. * response, so arrange that we'll receive notification of that
  369. * via ssh_remote_eof. */
  370. srv->bpp->expect_close = true;
  371. }
  372. #define GET_FORMATTED_MSG(fmt) \
  373. char *msg; \
  374. va_list ap; \
  375. va_start(ap, fmt); \
  376. msg = dupvprintf(fmt, ap); \
  377. va_end(ap);
  378. #define LOG_FORMATTED_MSG(logctx, fmt) do \
  379. { \
  380. va_list ap; \
  381. va_start(ap, fmt); \
  382. logeventvf(logctx, fmt, ap); \
  383. va_end(ap); \
  384. } while (0)
  385. void ssh_remote_error(Ssh *ssh, const char *fmt, ...)
  386. {
  387. server *srv = container_of(ssh, server, ssh);
  388. LOG_FORMATTED_MSG(srv->logctx, fmt);
  389. queue_toplevel_callback(ssh_server_free_callback, srv);
  390. }
  391. void ssh_remote_eof(Ssh *ssh, const char *fmt, ...)
  392. {
  393. server *srv = container_of(ssh, server, ssh);
  394. LOG_FORMATTED_MSG(srv->logctx, fmt);
  395. queue_toplevel_callback(ssh_server_free_callback, srv);
  396. }
  397. void ssh_proto_error(Ssh *ssh, const char *fmt, ...)
  398. {
  399. server *srv = container_of(ssh, server, ssh);
  400. if (srv->base_layer) {
  401. GET_FORMATTED_MSG(fmt);
  402. ssh_bpp_queue_disconnect(srv->bpp, msg,
  403. SSH2_DISCONNECT_PROTOCOL_ERROR);
  404. server_initiate_connection_close(srv);
  405. logeventf(srv->logctx, "Protocol error: %s", msg);
  406. sfree(msg);
  407. }
  408. }
  409. void ssh_sw_abort(Ssh *ssh, const char *fmt, ...)
  410. {
  411. server *srv = container_of(ssh, server, ssh);
  412. LOG_FORMATTED_MSG(srv->logctx, fmt);
  413. queue_toplevel_callback(ssh_server_free_callback, srv);
  414. }
  415. void ssh_user_close(Ssh *ssh, const char *fmt, ...)
  416. {
  417. server *srv = container_of(ssh, server, ssh);
  418. ssh_bpp_handle_output(srv->bpp);
  419. LOG_FORMATTED_MSG(srv->logctx, fmt);
  420. queue_toplevel_callback(ssh_server_free_callback, srv);
  421. }
  422. static void server_got_ssh_version(struct ssh_version_receiver *rcv,
  423. int major_version)
  424. {
  425. server *srv = container_of(rcv, server, version_receiver);
  426. BinaryPacketProtocol *old_bpp;
  427. PacketProtocolLayer *connection_layer;
  428. old_bpp = srv->bpp;
  429. srv->remote_bugs = ssh_verstring_get_bugs(old_bpp);
  430. if (srv->ssc->bare_connection) {
  431. srv->bpp = ssh2_bare_bpp_new(srv->logctx);
  432. server_connect_bpp(srv);
  433. connection_layer = ssh2_connection_new(
  434. &srv->ssh, NULL, false, srv->conf,
  435. ssh_verstring_get_local(old_bpp), &srv->dummy_user_input,
  436. &srv->cl);
  437. ssh2connection_server_configure(connection_layer,
  438. srv->sftpserver_vt, srv->ssc);
  439. server_connect_ppl(srv, connection_layer);
  440. srv->base_layer = connection_layer;
  441. } else if (major_version == 2) {
  442. PacketProtocolLayer *userauth_layer, *transport_child_layer;
  443. srv->bpp = ssh2_bpp_new(srv->logctx, &srv->stats, true);
  444. server_connect_bpp(srv);
  445. connection_layer = ssh2_connection_new(
  446. &srv->ssh, NULL, false, srv->conf,
  447. ssh_verstring_get_local(old_bpp), &srv->dummy_user_input,
  448. &srv->cl);
  449. ssh2connection_server_configure(connection_layer,
  450. srv->sftpserver_vt, srv->ssc);
  451. server_connect_ppl(srv, connection_layer);
  452. if (conf_get_bool(srv->conf, CONF_ssh_no_userauth)) {
  453. userauth_layer = NULL;
  454. transport_child_layer = connection_layer;
  455. } else {
  456. userauth_layer = ssh2_userauth_server_new(
  457. connection_layer, srv->authpolicy, srv->ssc);
  458. server_connect_ppl(srv, userauth_layer);
  459. transport_child_layer = userauth_layer;
  460. }
  461. srv->base_layer = ssh2_transport_new(
  462. srv->conf, NULL, 0, NULL,
  463. ssh_verstring_get_remote(old_bpp),
  464. ssh_verstring_get_local(old_bpp),
  465. #ifndef NO_GSSAPI
  466. &srv->gss_state,
  467. #else
  468. NULL,
  469. #endif
  470. &srv->stats, transport_child_layer, srv->ssc);
  471. ssh2_transport_provide_hostkeys(
  472. srv->base_layer, srv->hostkeys, srv->nhostkeys);
  473. if (userauth_layer)
  474. ssh2_userauth_server_set_transport_layer(
  475. userauth_layer, srv->base_layer);
  476. server_connect_ppl(srv, srv->base_layer);
  477. } else {
  478. srv->bpp = ssh1_bpp_new(srv->logctx);
  479. server_connect_bpp(srv);
  480. connection_layer = ssh1_connection_new(
  481. &srv->ssh, srv->conf, &srv->dummy_user_input, &srv->cl);
  482. ssh1connection_server_configure(connection_layer, srv->ssc);
  483. server_connect_ppl(srv, connection_layer);
  484. srv->base_layer = ssh1_login_server_new(
  485. connection_layer, srv->hostkey1, srv->authpolicy, srv->ssc);
  486. server_connect_ppl(srv, srv->base_layer);
  487. }
  488. /* Connect the base layer - whichever it is - to the BPP, and set
  489. * up its selfptr. */
  490. srv->base_layer->selfptr = &srv->base_layer;
  491. ssh_ppl_setup_queues(srv->base_layer, &srv->bpp->in_pq, &srv->bpp->out_pq);
  492. #ifdef FIXME // we probably will want one of these, in the end
  493. srv->pinger = pinger_new(srv->conf, &srv->backend);
  494. #endif
  495. if (srv->ssc->stunt_open_unconditional_agent_socket) {
  496. char *socketname;
  497. srv->stunt_agentfwd = agentfwd_new(srv->cl, &socketname);
  498. if (srv->stunt_agentfwd) {
  499. logeventf(srv->logctx, "opened unconditional agent socket at %s\n",
  500. socketname);
  501. sfree(socketname);
  502. }
  503. }
  504. queue_idempotent_callback(&srv->bpp->ic_in_raw);
  505. ssh_ppl_process_queue(srv->base_layer);
  506. ssh_bpp_free(old_bpp);
  507. }