diff options
author | Colin Watson <cjwatson@debian.org> | 2011-01-24 12:43:25 +0000 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2011-01-24 12:43:25 +0000 |
commit | 626f1d986ff72aa514da63e34744e1de9cf21b9a (patch) | |
tree | d215a5280bc2e57251e4a9e08bfd3674ad824a94 /misc.c | |
parent | 6ed622cb6fe8f71bbe0d998cdd12280410bfb420 (diff) | |
parent | 0970072c89b079b022538e3c366fbfa2c53fc821 (diff) |
* New upstream release (http://www.openssh.org/txt/release-5.7):
- Implement Elliptic Curve Cryptography modes for key exchange (ECDH)
and host/user keys (ECDSA) as specified by RFC5656. ECDH and ECDSA
offer better performance than plain DH and DSA at the same equivalent
symmetric key length, as well as much shorter keys.
- sftp(1)/sftp-server(8): add a protocol extension to support a hard
link operation. It is available through the "ln" command in the
client. The old "ln" behaviour of creating a symlink is available
using its "-s" option or through the preexisting "symlink" command.
- scp(1): Add a new -3 option to scp: Copies between two remote hosts
are transferred through the local host (closes: #508613).
- ssh(1): "atomically" create the listening mux socket by binding it on
a temporary name and then linking it into position after listen() has
succeeded. This allows the mux clients to determine that the server
socket is either ready or stale without races (closes: #454784).
Stale server sockets are now automatically removed (closes: #523250).
- ssh(1): install a SIGCHLD handler to reap expired child process
(closes: #594687).
- ssh(1)/ssh-agent(1): honour $TMPDIR for client xauth and ssh-agent
temporary directories (closes: #357469, although only if you arrange
for ssh-agent to actually see $TMPDIR since the setgid bit will cause
it to be stripped off).
Diffstat (limited to 'misc.c')
-rw-r--r-- | misc.c | 139 |
1 files changed, 132 insertions, 7 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: misc.c,v 1.80 2010/07/21 02:10:58 djm Exp $ */ | 1 | /* $OpenBSD: misc.c,v 1.84 2010/11/21 01:01:13 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | * Copyright (c) 2005,2006 Damien Miller. All rights reserved. | 4 | * Copyright (c) 2005,2006 Damien Miller. All rights reserved. |
@@ -35,9 +35,12 @@ | |||
35 | #include <stdio.h> | 35 | #include <stdio.h> |
36 | #include <stdlib.h> | 36 | #include <stdlib.h> |
37 | #include <string.h> | 37 | #include <string.h> |
38 | #include <time.h> | ||
38 | #include <unistd.h> | 39 | #include <unistd.h> |
39 | 40 | ||
40 | #include <netinet/in.h> | 41 | #include <netinet/in.h> |
42 | #include <netinet/in_systm.h> | ||
43 | #include <netinet/ip.h> | ||
41 | #include <netinet/tcp.h> | 44 | #include <netinet/tcp.h> |
42 | 45 | ||
43 | #include <errno.h> | 46 | #include <errno.h> |
@@ -900,16 +903,138 @@ ms_to_timeval(struct timeval *tv, int ms) | |||
900 | tv->tv_usec = (ms % 1000) * 1000; | 903 | tv->tv_usec = (ms % 1000) * 1000; |
901 | } | 904 | } |
902 | 905 | ||
906 | void | ||
907 | bandwidth_limit_init(struct bwlimit *bw, u_int64_t kbps, size_t buflen) | ||
908 | { | ||
909 | bw->buflen = buflen; | ||
910 | bw->rate = kbps; | ||
911 | bw->thresh = bw->rate; | ||
912 | bw->lamt = 0; | ||
913 | timerclear(&bw->bwstart); | ||
914 | timerclear(&bw->bwend); | ||
915 | } | ||
916 | |||
917 | /* Callback from read/write loop to insert bandwidth-limiting delays */ | ||
918 | void | ||
919 | bandwidth_limit(struct bwlimit *bw, size_t read_len) | ||
920 | { | ||
921 | u_int64_t waitlen; | ||
922 | struct timespec ts, rm; | ||
923 | |||
924 | if (!timerisset(&bw->bwstart)) { | ||
925 | gettimeofday(&bw->bwstart, NULL); | ||
926 | return; | ||
927 | } | ||
928 | |||
929 | bw->lamt += read_len; | ||
930 | if (bw->lamt < bw->thresh) | ||
931 | return; | ||
932 | |||
933 | gettimeofday(&bw->bwend, NULL); | ||
934 | timersub(&bw->bwend, &bw->bwstart, &bw->bwend); | ||
935 | if (!timerisset(&bw->bwend)) | ||
936 | return; | ||
937 | |||
938 | bw->lamt *= 8; | ||
939 | waitlen = (double)1000000L * bw->lamt / bw->rate; | ||
940 | |||
941 | bw->bwstart.tv_sec = waitlen / 1000000L; | ||
942 | bw->bwstart.tv_usec = waitlen % 1000000L; | ||
943 | |||
944 | if (timercmp(&bw->bwstart, &bw->bwend, >)) { | ||
945 | timersub(&bw->bwstart, &bw->bwend, &bw->bwend); | ||
946 | |||
947 | /* Adjust the wait time */ | ||
948 | if (bw->bwend.tv_sec) { | ||
949 | bw->thresh /= 2; | ||
950 | if (bw->thresh < bw->buflen / 4) | ||
951 | bw->thresh = bw->buflen / 4; | ||
952 | } else if (bw->bwend.tv_usec < 10000) { | ||
953 | bw->thresh *= 2; | ||
954 | if (bw->thresh > bw->buflen * 8) | ||
955 | bw->thresh = bw->buflen * 8; | ||
956 | } | ||
957 | |||
958 | TIMEVAL_TO_TIMESPEC(&bw->bwend, &ts); | ||
959 | while (nanosleep(&ts, &rm) == -1) { | ||
960 | if (errno != EINTR) | ||
961 | break; | ||
962 | ts = rm; | ||
963 | } | ||
964 | } | ||
965 | |||
966 | bw->lamt = 0; | ||
967 | gettimeofday(&bw->bwstart, NULL); | ||
968 | } | ||
969 | |||
970 | /* Make a template filename for mk[sd]temp() */ | ||
971 | void | ||
972 | mktemp_proto(char *s, size_t len) | ||
973 | { | ||
974 | const char *tmpdir; | ||
975 | int r; | ||
976 | |||
977 | if ((tmpdir = getenv("TMPDIR")) != NULL) { | ||
978 | r = snprintf(s, len, "%s/ssh-XXXXXXXXXXXX", tmpdir); | ||
979 | if (r > 0 && (size_t)r < len) | ||
980 | return; | ||
981 | } | ||
982 | r = snprintf(s, len, "/tmp/ssh-XXXXXXXXXXXX"); | ||
983 | if (r < 0 || (size_t)r >= len) | ||
984 | fatal("%s: template string too short", __func__); | ||
985 | } | ||
986 | |||
987 | static const struct { | ||
988 | const char *name; | ||
989 | int value; | ||
990 | } ipqos[] = { | ||
991 | { "af11", IPTOS_DSCP_AF11 }, | ||
992 | { "af12", IPTOS_DSCP_AF12 }, | ||
993 | { "af13", IPTOS_DSCP_AF13 }, | ||
994 | { "af14", IPTOS_DSCP_AF21 }, | ||
995 | { "af22", IPTOS_DSCP_AF22 }, | ||
996 | { "af23", IPTOS_DSCP_AF23 }, | ||
997 | { "af31", IPTOS_DSCP_AF31 }, | ||
998 | { "af32", IPTOS_DSCP_AF32 }, | ||
999 | { "af33", IPTOS_DSCP_AF33 }, | ||
1000 | { "af41", IPTOS_DSCP_AF41 }, | ||
1001 | { "af42", IPTOS_DSCP_AF42 }, | ||
1002 | { "af43", IPTOS_DSCP_AF43 }, | ||
1003 | { "cs0", IPTOS_DSCP_CS0 }, | ||
1004 | { "cs1", IPTOS_DSCP_CS1 }, | ||
1005 | { "cs2", IPTOS_DSCP_CS2 }, | ||
1006 | { "cs3", IPTOS_DSCP_CS3 }, | ||
1007 | { "cs4", IPTOS_DSCP_CS4 }, | ||
1008 | { "cs5", IPTOS_DSCP_CS5 }, | ||
1009 | { "cs6", IPTOS_DSCP_CS6 }, | ||
1010 | { "cs7", IPTOS_DSCP_CS7 }, | ||
1011 | { "ef", IPTOS_DSCP_EF }, | ||
1012 | { "lowdelay", IPTOS_LOWDELAY }, | ||
1013 | { "throughput", IPTOS_THROUGHPUT }, | ||
1014 | { "reliability", IPTOS_RELIABILITY }, | ||
1015 | { NULL, -1 } | ||
1016 | }; | ||
1017 | |||
903 | int | 1018 | int |
904 | timingsafe_bcmp(const void *b1, const void *b2, size_t n) | 1019 | parse_ipqos(const char *cp) |
905 | { | 1020 | { |
906 | const unsigned char *p1 = b1, *p2 = b2; | 1021 | u_int i; |
907 | int ret = 0; | 1022 | char *ep; |
1023 | long val; | ||
908 | 1024 | ||
909 | for (; n > 0; n--) | 1025 | if (cp == NULL) |
910 | ret |= *p1++ ^ *p2++; | 1026 | return -1; |
911 | return (ret != 0); | 1027 | for (i = 0; ipqos[i].name != NULL; i++) { |
1028 | if (strcasecmp(cp, ipqos[i].name) == 0) | ||
1029 | return ipqos[i].value; | ||
1030 | } | ||
1031 | /* Try parsing as an integer */ | ||
1032 | val = strtol(cp, &ep, 0); | ||
1033 | if (*cp == '\0' || *ep != '\0' || val < 0 || val > 255) | ||
1034 | return -1; | ||
1035 | return val; | ||
912 | } | 1036 | } |
1037 | |||
913 | void | 1038 | void |
914 | sock_set_v6only(int s) | 1039 | sock_set_v6only(int s) |
915 | { | 1040 | { |