diff options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | session.c | 37 | ||||
-rw-r--r-- | sftp-server.c | 44 | ||||
-rw-r--r-- | sftp.h | 5 |
4 files changed, 67 insertions, 24 deletions
@@ -68,6 +68,9 @@ | |||
68 | explain how to handle local file names containing colons; | 68 | explain how to handle local file names containing colons; |
69 | requested by Tamas TEVESZ | 69 | requested by Tamas TEVESZ |
70 | ok dtucker | 70 | ok dtucker |
71 | - markus@cvs.openbsd.org 2008/02/04 21:53:00 | ||
72 | [session.c sftp-server.c sftp.h] | ||
73 | link sftp-server into sshd; feedback and ok djm@ | ||
71 | 74 | ||
72 | 20080119 | 75 | 20080119 |
73 | - (djm) Silence noice from expr in ssh-copy-id; patch from | 76 | - (djm) Silence noice from expr in ssh-copy-id; patch from |
@@ -3596,4 +3599,4 @@ | |||
3596 | OpenServer 6 and add osr5bigcrypt support so when someone migrates | 3599 | OpenServer 6 and add osr5bigcrypt support so when someone migrates |
3597 | passwords between UnixWare and OpenServer they will still work. OK dtucker@ | 3600 | passwords between UnixWare and OpenServer they will still work. OK dtucker@ |
3598 | 3601 | ||
3599 | $Id: ChangeLog,v 1.4833 2008/02/10 11:28:45 djm Exp $ | 3602 | $Id: ChangeLog,v 1.4834 2008/02/10 11:29:40 djm Exp $ |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: session.c,v 1.224 2007/09/11 15:47:17 gilles Exp $ */ | 1 | /* $OpenBSD: session.c,v 1.225 2008/02/04 21:53:00 markus Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 3 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
4 | * All rights reserved | 4 | * All rights reserved |
@@ -87,6 +87,7 @@ | |||
87 | #include "session.h" | 87 | #include "session.h" |
88 | #include "kex.h" | 88 | #include "kex.h" |
89 | #include "monitor_wrap.h" | 89 | #include "monitor_wrap.h" |
90 | #include "sftp.h" | ||
90 | 91 | ||
91 | #if defined(KRB5) && defined(USE_AFS) | 92 | #if defined(KRB5) && defined(USE_AFS) |
92 | #include <kafs.h> | 93 | #include <kafs.h> |
@@ -132,6 +133,10 @@ const char *original_command = NULL; | |||
132 | #define MAX_SESSIONS 10 | 133 | #define MAX_SESSIONS 10 |
133 | Session sessions[MAX_SESSIONS]; | 134 | Session sessions[MAX_SESSIONS]; |
134 | 135 | ||
136 | #define SUBSYSTEM_NONE 0 | ||
137 | #define SUBSYSTEM_EXT 1 | ||
138 | #define SUBSYSTEM_INT_SFTP 2 | ||
139 | |||
135 | #ifdef HAVE_LOGIN_CAP | 140 | #ifdef HAVE_LOGIN_CAP |
136 | login_cap_t *lc; | 141 | login_cap_t *lc; |
137 | #endif | 142 | #endif |
@@ -683,10 +688,14 @@ do_exec(Session *s, const char *command) | |||
683 | if (options.adm_forced_command) { | 688 | if (options.adm_forced_command) { |
684 | original_command = command; | 689 | original_command = command; |
685 | command = options.adm_forced_command; | 690 | command = options.adm_forced_command; |
691 | if (s->is_subsystem) | ||
692 | s->is_subsystem = SUBSYSTEM_EXT; | ||
686 | debug("Forced command (config) '%.900s'", command); | 693 | debug("Forced command (config) '%.900s'", command); |
687 | } else if (forced_command) { | 694 | } else if (forced_command) { |
688 | original_command = command; | 695 | original_command = command; |
689 | command = forced_command; | 696 | command = forced_command; |
697 | if (s->is_subsystem) | ||
698 | s->is_subsystem = SUBSYSTEM_EXT; | ||
690 | debug("Forced command (key option) '%.900s'", command); | 699 | debug("Forced command (key option) '%.900s'", command); |
691 | } | 700 | } |
692 | 701 | ||
@@ -1465,12 +1474,13 @@ child_close_fds(void) | |||
1465 | * environment, closing extra file descriptors, setting the user and group | 1474 | * environment, closing extra file descriptors, setting the user and group |
1466 | * ids, and executing the command or shell. | 1475 | * ids, and executing the command or shell. |
1467 | */ | 1476 | */ |
1477 | #define ARGV_MAX 10 | ||
1468 | void | 1478 | void |
1469 | do_child(Session *s, const char *command) | 1479 | do_child(Session *s, const char *command) |
1470 | { | 1480 | { |
1471 | extern char **environ; | 1481 | extern char **environ; |
1472 | char **env; | 1482 | char **env; |
1473 | char *argv[10]; | 1483 | char *argv[ARGV_MAX]; |
1474 | const char *shell, *shell0, *hostname = NULL; | 1484 | const char *shell, *shell0, *hostname = NULL; |
1475 | struct passwd *pw = s->pw; | 1485 | struct passwd *pw = s->pw; |
1476 | 1486 | ||
@@ -1602,6 +1612,22 @@ do_child(Session *s, const char *command) | |||
1602 | /* restore SIGPIPE for child */ | 1612 | /* restore SIGPIPE for child */ |
1603 | signal(SIGPIPE, SIG_DFL); | 1613 | signal(SIGPIPE, SIG_DFL); |
1604 | 1614 | ||
1615 | if (s->is_subsystem == SUBSYSTEM_INT_SFTP) { | ||
1616 | extern int optind, optreset; | ||
1617 | int i; | ||
1618 | char *p, *args; | ||
1619 | |||
1620 | setproctitle("%s@internal-sftp-server", s->pw->pw_name); | ||
1621 | args = strdup(command ? command : "sftp-server"); | ||
1622 | for (i = 0, (p = strtok(args, " ")); p; (p = strtok(NULL, " "))) | ||
1623 | if (i < ARGV_MAX - 1) | ||
1624 | argv[i++] = p; | ||
1625 | argv[i] = NULL; | ||
1626 | optind = optreset = 1; | ||
1627 | __progname = argv[0]; | ||
1628 | exit(sftp_server_main(i, argv)); | ||
1629 | } | ||
1630 | |||
1605 | if (options.use_login) { | 1631 | if (options.use_login) { |
1606 | launch_login(pw, hostname); | 1632 | launch_login(pw, hostname); |
1607 | /* NEVERREACHED */ | 1633 | /* NEVERREACHED */ |
@@ -1874,13 +1900,16 @@ session_subsystem_req(Session *s) | |||
1874 | if (strcmp(subsys, options.subsystem_name[i]) == 0) { | 1900 | if (strcmp(subsys, options.subsystem_name[i]) == 0) { |
1875 | prog = options.subsystem_command[i]; | 1901 | prog = options.subsystem_command[i]; |
1876 | cmd = options.subsystem_args[i]; | 1902 | cmd = options.subsystem_args[i]; |
1877 | if (stat(prog, &st) < 0) { | 1903 | if (!strcmp("internal-sftp", prog)) { |
1904 | s->is_subsystem = SUBSYSTEM_INT_SFTP; | ||
1905 | } else if (stat(prog, &st) < 0) { | ||
1878 | error("subsystem: cannot stat %s: %s", prog, | 1906 | error("subsystem: cannot stat %s: %s", prog, |
1879 | strerror(errno)); | 1907 | strerror(errno)); |
1880 | break; | 1908 | break; |
1909 | } else { | ||
1910 | s->is_subsystem = SUBSYSTEM_EXT; | ||
1881 | } | 1911 | } |
1882 | debug("subsystem: exec() %s", cmd); | 1912 | debug("subsystem: exec() %s", cmd); |
1883 | s->is_subsystem = 1; | ||
1884 | do_exec(s, cmd); | 1913 | do_exec(s, cmd); |
1885 | success = 1; | 1914 | success = 1; |
1886 | break; | 1915 | break; |
diff --git a/sftp-server.c b/sftp-server.c index 5c84c728c..373bd5eda 100644 --- a/sftp-server.c +++ b/sftp-server.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sftp-server.c,v 1.75 2008/01/21 17:24:30 djm Exp $ */ | 1 | /* $OpenBSD: sftp-server.c,v 1.76 2008/02/04 21:53:00 markus Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000-2004 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000-2004 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -1110,7 +1110,7 @@ process(void) | |||
1110 | if (msg_len > SFTP_MAX_MSG_LENGTH) { | 1110 | if (msg_len > SFTP_MAX_MSG_LENGTH) { |
1111 | error("bad message from %s local user %s", | 1111 | error("bad message from %s local user %s", |
1112 | client_addr, pw->pw_name); | 1112 | client_addr, pw->pw_name); |
1113 | cleanup_exit(11); | 1113 | sftp_server_cleanup_exit(11); |
1114 | } | 1114 | } |
1115 | if (buf_len < msg_len + 4) | 1115 | if (buf_len < msg_len + 4) |
1116 | return; | 1116 | return; |
@@ -1183,18 +1183,22 @@ process(void) | |||
1183 | break; | 1183 | break; |
1184 | } | 1184 | } |
1185 | /* discard the remaining bytes from the current packet */ | 1185 | /* discard the remaining bytes from the current packet */ |
1186 | if (buf_len < buffer_len(&iqueue)) | 1186 | if (buf_len < buffer_len(&iqueue)) { |
1187 | fatal("iqueue grew unexpectedly"); | 1187 | error("iqueue grew unexpectedly"); |
1188 | sftp_server_cleanup_exit(255); | ||
1189 | } | ||
1188 | consumed = buf_len - buffer_len(&iqueue); | 1190 | consumed = buf_len - buffer_len(&iqueue); |
1189 | if (msg_len < consumed) | 1191 | if (msg_len < consumed) { |
1190 | fatal("msg_len %d < consumed %d", msg_len, consumed); | 1192 | error("msg_len %d < consumed %d", msg_len, consumed); |
1193 | sftp_server_cleanup_exit(255); | ||
1194 | } | ||
1191 | if (msg_len > consumed) | 1195 | if (msg_len > consumed) |
1192 | buffer_consume(&iqueue, msg_len - consumed); | 1196 | buffer_consume(&iqueue, msg_len - consumed); |
1193 | } | 1197 | } |
1194 | 1198 | ||
1195 | /* Cleanup handler that logs active handles upon normal exit */ | 1199 | /* Cleanup handler that logs active handles upon normal exit */ |
1196 | void | 1200 | void |
1197 | cleanup_exit(int i) | 1201 | sftp_server_cleanup_exit(int i) |
1198 | { | 1202 | { |
1199 | if (pw != NULL && client_addr != NULL) { | 1203 | if (pw != NULL && client_addr != NULL) { |
1200 | handle_log_exit(); | 1204 | handle_log_exit(); |
@@ -1205,7 +1209,7 @@ cleanup_exit(int i) | |||
1205 | } | 1209 | } |
1206 | 1210 | ||
1207 | static void | 1211 | static void |
1208 | usage(void) | 1212 | sftp_server_usage(void) |
1209 | { | 1213 | { |
1210 | extern char *__progname; | 1214 | extern char *__progname; |
1211 | 1215 | ||
@@ -1215,7 +1219,7 @@ usage(void) | |||
1215 | } | 1219 | } |
1216 | 1220 | ||
1217 | int | 1221 | int |
1218 | main(int argc, char **argv) | 1222 | sftp_server_main(int argc, char **argv) |
1219 | { | 1223 | { |
1220 | fd_set *rset, *wset; | 1224 | fd_set *rset, *wset; |
1221 | int in, out, max, ch, skipargs = 0, log_stderr = 0; | 1225 | int in, out, max, ch, skipargs = 0, log_stderr = 0; |
@@ -1256,7 +1260,7 @@ main(int argc, char **argv) | |||
1256 | break; | 1260 | break; |
1257 | case 'h': | 1261 | case 'h': |
1258 | default: | 1262 | default: |
1259 | usage(); | 1263 | sftp_server_usage(); |
1260 | } | 1264 | } |
1261 | } | 1265 | } |
1262 | 1266 | ||
@@ -1264,15 +1268,19 @@ main(int argc, char **argv) | |||
1264 | 1268 | ||
1265 | if ((cp = getenv("SSH_CONNECTION")) != NULL) { | 1269 | if ((cp = getenv("SSH_CONNECTION")) != NULL) { |
1266 | client_addr = xstrdup(cp); | 1270 | client_addr = xstrdup(cp); |
1267 | if ((cp = strchr(client_addr, ' ')) == NULL) | 1271 | if ((cp = strchr(client_addr, ' ')) == NULL) { |
1268 | fatal("Malformed SSH_CONNECTION variable: \"%s\"", | 1272 | error("Malformed SSH_CONNECTION variable: \"%s\"", |
1269 | getenv("SSH_CONNECTION")); | 1273 | getenv("SSH_CONNECTION")); |
1274 | sftp_server_cleanup_exit(255); | ||
1275 | } | ||
1270 | *cp = '\0'; | 1276 | *cp = '\0'; |
1271 | } else | 1277 | } else |
1272 | client_addr = xstrdup("UNKNOWN"); | 1278 | client_addr = xstrdup("UNKNOWN"); |
1273 | 1279 | ||
1274 | if ((pw = getpwuid(getuid())) == NULL) | 1280 | if ((pw = getpwuid(getuid())) == NULL) { |
1275 | fatal("No user found for uid %lu", (u_long)getuid()); | 1281 | error("No user found for uid %lu", (u_long)getuid()); |
1282 | sftp_server_cleanup_exit(255); | ||
1283 | } | ||
1276 | pw = pwcopy(pw); | 1284 | pw = pwcopy(pw); |
1277 | 1285 | ||
1278 | logit("session opened for local user %s from [%s]", | 1286 | logit("session opened for local user %s from [%s]", |
@@ -1320,7 +1328,7 @@ main(int argc, char **argv) | |||
1320 | if (errno == EINTR) | 1328 | if (errno == EINTR) |
1321 | continue; | 1329 | continue; |
1322 | error("select: %s", strerror(errno)); | 1330 | error("select: %s", strerror(errno)); |
1323 | cleanup_exit(2); | 1331 | sftp_server_cleanup_exit(2); |
1324 | } | 1332 | } |
1325 | 1333 | ||
1326 | /* copy stdin to iqueue */ | 1334 | /* copy stdin to iqueue */ |
@@ -1328,10 +1336,10 @@ main(int argc, char **argv) | |||
1328 | len = read(in, buf, sizeof buf); | 1336 | len = read(in, buf, sizeof buf); |
1329 | if (len == 0) { | 1337 | if (len == 0) { |
1330 | debug("read eof"); | 1338 | debug("read eof"); |
1331 | cleanup_exit(0); | 1339 | sftp_server_cleanup_exit(0); |
1332 | } else if (len < 0) { | 1340 | } else if (len < 0) { |
1333 | error("read: %s", strerror(errno)); | 1341 | error("read: %s", strerror(errno)); |
1334 | cleanup_exit(1); | 1342 | sftp_server_cleanup_exit(1); |
1335 | } else { | 1343 | } else { |
1336 | buffer_append(&iqueue, buf, len); | 1344 | buffer_append(&iqueue, buf, len); |
1337 | } | 1345 | } |
@@ -1341,7 +1349,7 @@ main(int argc, char **argv) | |||
1341 | len = write(out, buffer_ptr(&oqueue), olen); | 1349 | len = write(out, buffer_ptr(&oqueue), olen); |
1342 | if (len < 0) { | 1350 | if (len < 0) { |
1343 | error("write: %s", strerror(errno)); | 1351 | error("write: %s", strerror(errno)); |
1344 | cleanup_exit(1); | 1352 | sftp_server_cleanup_exit(1); |
1345 | } else { | 1353 | } else { |
1346 | buffer_consume(&oqueue, len); | 1354 | buffer_consume(&oqueue, len); |
1347 | } | 1355 | } |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sftp.h,v 1.5 2006/03/25 22:22:43 djm Exp $ */ | 1 | /* $OpenBSD: sftp.h,v 1.6 2008/02/04 21:53:00 markus Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright (c) 2001 Markus Friedl. All rights reserved. | 4 | * Copyright (c) 2001 Markus Friedl. All rights reserved. |
@@ -90,3 +90,6 @@ | |||
90 | #define SSH2_FX_CONNECTION_LOST 7 | 90 | #define SSH2_FX_CONNECTION_LOST 7 |
91 | #define SSH2_FX_OP_UNSUPPORTED 8 | 91 | #define SSH2_FX_OP_UNSUPPORTED 8 |
92 | #define SSH2_FX_MAX 8 | 92 | #define SSH2_FX_MAX 8 |
93 | |||
94 | int sftp_server_main(int, char **); | ||
95 | void sftp_server_cleanup_exit(int) __dead; | ||