+int
+session_subsystem_req(Session *s)
+{
+ unsigned int len;
+ int success = 0;
+ char *subsys = packet_get_string(&len);
+ int i;
+
+ packet_done();
+ log("subsystem request for %s", subsys);
+
+ for (i = 0; i < options.num_subsystems; i++) {
+ if(strcmp(subsys, options.subsystem_name[i]) == 0) {
+ debug("subsystem: exec() %s", options.subsystem_command[i]);
+ do_exec_no_pty(s, options.subsystem_command[i], s->pw);
+ success = 1;
+ }
+ }
+
+ if (!success)
+ log("subsystem request for %s failed, subsystem not found", subsys);
+
+ xfree(subsys);
+ return success;
+}
+
+int
+session_x11_req(Session *s)
+{
+ if (!no_port_forwarding_flag) {
+ debug("X11 forwarding disabled in user configuration file.");
+ return 0;
+ }
+ if (!options.x11_forwarding) {
+ debug("X11 forwarding disabled in server configuration file.");
+ return 0;
+ }
+ if (xauthfile != NULL) {
+ debug("X11 fwd already started.");
+ return 0;
+ }
+
+ debug("Received request for X11 forwarding with auth spoofing.");
+ if (s->display != NULL)
+ packet_disconnect("Protocol error: X11 display already set.");
+
+ s->single_connection = packet_get_char();
+ s->auth_proto = packet_get_string(NULL);
+ s->auth_data = packet_get_string(NULL);
+ s->screen = packet_get_int();
+ packet_done();
+
+ s->display = x11_create_display_inet(s->screen, options.x11_display_offset);
+ if (s->display == NULL) {
+ xfree(s->auth_proto);
+ xfree(s->auth_data);
+ return 0;
+ }
+ xauthfile = xmalloc(MAXPATHLEN);
+ strlcpy(xauthfile, "/tmp/ssh-XXXXXXXX", MAXPATHLEN);
+ temporarily_use_uid(s->pw->pw_uid);
+ if (mkdtemp(xauthfile) == NULL) {
+ restore_uid();
+ error("private X11 dir: mkdtemp %s failed: %s",
+ xauthfile, strerror(errno));
+ xfree(xauthfile);
+ xauthfile = NULL;
+ xfree(s->auth_proto);
+ xfree(s->auth_data);
+ /* XXXX remove listening channels */
+ return 0;
+ }
+ strlcat(xauthfile, "/cookies", MAXPATHLEN);
+ open(xauthfile, O_RDWR|O_CREAT|O_EXCL, 0600);
+ restore_uid();
+ fatal_add_cleanup(xauthfile_cleanup_proc, s);
+ return 1;
+}
+
+int
+session_shell_req(Session *s)
+{
+ /* if forced_command == NULL, the shell is execed */
+ char *shell = forced_command;
+ packet_done();
+ s->extended = 1;
+ if (s->ttyfd == -1)
+ do_exec_no_pty(s, shell, s->pw);
+ else
+ do_exec_pty(s, shell, s->pw);
+ return 1;
+}
+
+int
+session_exec_req(Session *s)
+{
+ unsigned int len;
+ char *command = packet_get_string(&len);
+ packet_done();
+ if (forced_command) {
+ xfree(command);
+ command = forced_command;
+ debug("Forced command '%.500s'", forced_command);
+ }
+ s->extended = 1;
+ if (s->ttyfd == -1)
+ do_exec_no_pty(s, command, s->pw);
+ else
+ do_exec_pty(s, command, s->pw);
+ if (forced_command == NULL)
+ xfree(command);
+ return 1;
+}
+