When I flattened the dist tree, some files that had been removed in prior
vendor imports were inadvertantly resurrected. Re-remove them.
This commit is contained in:
parent
bf2dc2ac25
commit
7699430e48
@ -1,70 +0,0 @@
|
||||
This file is part of the ssh software, Copyright (c) 1995 Tatu Ylonen, Finland
|
||||
|
||||
|
||||
COPYING POLICY AND OTHER LEGAL ISSUES
|
||||
|
||||
As far as I am concerned, the code I have written for this software
|
||||
can be used freely for any purpose. Any derived versions of this
|
||||
software must be clearly marked as such, and if the derived work is
|
||||
incompatible with the protocol description in the RFC file, it must be
|
||||
called by a name other than "ssh" or "Secure Shell".
|
||||
|
||||
However, I am not implying to give any licenses to any patents or
|
||||
copyrights held by third parties, and the software includes parts that
|
||||
are not under my direct control. As far as I know, all included
|
||||
source code is used in accordance with the relevant license agreements
|
||||
and can be used freely for any purpose (the GNU license being the most
|
||||
restrictive); see below for details.
|
||||
|
||||
[ RSA is no longer included. ]
|
||||
[ IDEA is no longer included. ]
|
||||
[ DES is now external. ]
|
||||
[ GMP is now external. No more GNU licence. ]
|
||||
[ Zlib is now external. ]
|
||||
[ The make-ssh-known-hosts script is no longer included. ]
|
||||
[ TSS has been removed. ]
|
||||
[ MD5 is now external. ]
|
||||
[ RC4 support has been removed. ]
|
||||
[ Blowfish is now external. ]
|
||||
|
||||
The 32-bit CRC implementation in crc32.c is due to Gary S. Brown.
|
||||
Comments in the file indicate it may be used for any purpose without
|
||||
restrictions.
|
||||
|
||||
The 32-bit CRC compensation attack detector in deattack.c was
|
||||
contributed by CORE SDI S.A. under a BSD-style license. See
|
||||
http://www.core-sdi.com/english/ssh/ for details.
|
||||
|
||||
Note that any information and cryptographic algorithms used in this
|
||||
software are publicly available on the Internet and at any major
|
||||
bookstore, scientific library, and patent office worldwide. More
|
||||
information can be found e.g. at "http://www.cs.hut.fi/crypto".
|
||||
|
||||
The legal status of this program is some combination of all these
|
||||
permissions and restrictions. Use only at your own responsibility.
|
||||
You will be responsible for any legal consequences yourself; I am not
|
||||
making any claims whether possessing or using this is legal or not in
|
||||
your country, and I am not taking any responsibility on your behalf.
|
||||
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
14
Makefile
14
Makefile
@ -1,14 +0,0 @@
|
||||
# $OpenBSD: Makefile,v 1.11 2002/05/23 19:24:30 markus Exp $
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
SUBDIR= lib ssh sshd ssh-add ssh-keygen ssh-agent scp sftp-server \
|
||||
ssh-keysign ssh-keyscan sftp scard
|
||||
|
||||
distribution:
|
||||
install -C -o root -g wheel -m 0644 ${.CURDIR}/ssh_config \
|
||||
${DESTDIR}/etc/ssh/ssh_config
|
||||
install -C -o root -g wheel -m 0644 ${.CURDIR}/sshd_config \
|
||||
${DESTDIR}/etc/ssh/sshd_config
|
||||
|
||||
.include <bsd.subdir.mk>
|
26
Makefile.inc
26
Makefile.inc
@ -1,26 +0,0 @@
|
||||
# $OpenBSD: Makefile.inc,v 1.23 2002/03/06 00:23:27 markus Exp $
|
||||
|
||||
CFLAGS+= -I${.CURDIR}/..
|
||||
|
||||
CDIAGFLAGS= -Wall
|
||||
#CDIAGFLAGS+= -Werror
|
||||
CDIAGFLAGS+= -Wpointer-arith
|
||||
CDIAGFLAGS+= -Wno-uninitialized
|
||||
#CDIAGFLAGS+= -Wstrict-prototypes
|
||||
CDIAGFLAGS+= -Wmissing-prototypes
|
||||
CDIAGFLAGS+= -Wunused
|
||||
|
||||
#DEBUG=-g
|
||||
|
||||
#CFLAGS+= -DSMARTCARD
|
||||
#LDADD+= -lsectok
|
||||
|
||||
.include <bsd.obj.mk>
|
||||
|
||||
.if exists(${.CURDIR}/../lib/${__objdir})
|
||||
LDADD+= -L${.CURDIR}/../lib/${__objdir} -lssh
|
||||
DPADD+= ${.CURDIR}/../lib/${__objdir}/libssh.a
|
||||
.else
|
||||
LDADD+= -L${.CURDIR}/../lib -lssh
|
||||
DPADD+= ${.CURDIR}/../lib/libssh.a
|
||||
.endif
|
@ -1,44 +0,0 @@
|
||||
$Id: README.openssh2,v 1.8 2000/05/07 18:30:03 markus Exp $
|
||||
|
||||
howto:
|
||||
1) generate server key:
|
||||
$ ssh-keygen -d -f /etc/ssh_host_dsa_key -N ''
|
||||
2) enable ssh2:
|
||||
server: add 'Protocol 2,1' to /etc/sshd_config
|
||||
client: ssh -o 'Protocol 2,1', or add to .ssh/config
|
||||
3) DSA authentication similar to RSA (add keys to ~/.ssh/authorized_keys2)
|
||||
interop w/ ssh.com dsa-keys:
|
||||
ssh-keygen -f /key/from/ssh.com -X >> ~/.ssh/authorized_keys2
|
||||
and vice versa
|
||||
ssh-keygen -f /privatekey/from/openssh -x > ~/.ssh2/mykey.pub
|
||||
echo Key mykey.pub >> ~/.ssh2/authorization
|
||||
|
||||
works:
|
||||
secsh-transport: works w/o rekey
|
||||
proposal exchange, i.e. different enc/mac/comp per direction
|
||||
encryption: blowfish-cbc, 3des-cbc, arcfour, cast128-cbc
|
||||
mac: hmac-md5, hmac-sha1, (hmac-ripemd160)
|
||||
compression: zlib, none
|
||||
secsh-userauth: passwd and pubkey with DSA
|
||||
secsh-connection: pty+shell or command, flow control works (window adjust)
|
||||
tcp-forwarding: -L works, -R incomplete
|
||||
x11-fwd
|
||||
dss/dsa: host key database in ~/.ssh/known_hosts2
|
||||
client interops w/ sshd2, lshd
|
||||
server interops w/ ssh2, lsh, ssh.com's Windows client, SecureCRT, F-Secure SSH Client 4.0, SecureFX (secure ftp)
|
||||
server supports multiple concurrent sessions (e.g. with SSH.com Windows client)
|
||||
todo:
|
||||
re-keying
|
||||
secsh-connection features:
|
||||
tcp-forwarding, agent-fwd
|
||||
auth other than passwd, and DSA-pubkey:
|
||||
keyboard-interactive, (PGP-pubkey?)
|
||||
config
|
||||
server-auth w/ old host-keys
|
||||
cleanup
|
||||
advanced key storage?
|
||||
keynote
|
||||
sftp
|
||||
|
||||
-markus
|
||||
$Date: 2000/05/07 18:30:03 $
|
104
auth2-skey.c
104
auth2-skey.c
@ -1,104 +0,0 @@
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: auth2-skey.c,v 1.1 2000/10/11 20:14:38 markus Exp $");
|
||||
|
||||
#include "ssh.h"
|
||||
#include "ssh2.h"
|
||||
#include "auth.h"
|
||||
#include "packet.h"
|
||||
#include "xmalloc.h"
|
||||
#include "dispatch.h"
|
||||
|
||||
void send_userauth_into_request(Authctxt *authctxt, int echo);
|
||||
void input_userauth_info_response(int type, int plen, void *ctxt);
|
||||
|
||||
/*
|
||||
* try skey authentication, always return -1 (= postponed) since we have to
|
||||
* wait for the s/key response.
|
||||
*/
|
||||
int
|
||||
auth2_skey(Authctxt *authctxt)
|
||||
{
|
||||
send_userauth_into_request(authctxt, 0);
|
||||
dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, &input_userauth_info_response);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
send_userauth_into_request(Authctxt *authctxt, int echo)
|
||||
{
|
||||
int retval = -1;
|
||||
struct skey skey;
|
||||
char challenge[SKEY_MAX_CHALLENGE];
|
||||
char *fake;
|
||||
|
||||
if (authctxt->user == NULL)
|
||||
fatal("send_userauth_into_request: internal error: no user");
|
||||
|
||||
/* get skey challenge */
|
||||
if (authctxt->valid)
|
||||
retval = skeychallenge(&skey, authctxt->user, challenge);
|
||||
|
||||
if (retval == -1) {
|
||||
fake = skey_fake_keyinfo(authctxt->user);
|
||||
strlcpy(challenge, fake, sizeof challenge);
|
||||
}
|
||||
/* send our info request */
|
||||
packet_start(SSH2_MSG_USERAUTH_INFO_REQUEST);
|
||||
packet_put_cstring("S/Key Authentication"); /* Name */
|
||||
packet_put_cstring(challenge); /* Instruction */
|
||||
packet_put_cstring(""); /* Language */
|
||||
packet_put_int(1); /* Number of prompts */
|
||||
packet_put_cstring(echo ?
|
||||
"Response [Echo]: ": "Response: "); /* Prompt */
|
||||
packet_put_char(echo); /* Echo */
|
||||
packet_send();
|
||||
packet_write_wait();
|
||||
memset(challenge, 'c', sizeof challenge);
|
||||
}
|
||||
|
||||
void
|
||||
input_userauth_info_response(int type, int plen, void *ctxt)
|
||||
{
|
||||
Authctxt *authctxt = ctxt;
|
||||
int authenticated = 0;
|
||||
unsigned int nresp, rlen;
|
||||
char *resp, *method;
|
||||
|
||||
if (authctxt == NULL)
|
||||
fatal("input_userauth_info_response: no authentication context");
|
||||
|
||||
if (authctxt->attempt++ >= AUTH_FAIL_MAX)
|
||||
packet_disconnect("too many failed userauth_requests");
|
||||
|
||||
nresp = packet_get_int();
|
||||
if (nresp == 1) {
|
||||
/* we only support s/key and assume s/key for nresp == 1 */
|
||||
method = "s/key";
|
||||
resp = packet_get_string(&rlen);
|
||||
packet_done();
|
||||
if (strlen(resp) == 0) {
|
||||
/*
|
||||
* if we received a null response, resend prompt with
|
||||
* echo enabled
|
||||
*/
|
||||
authenticated = -1;
|
||||
userauth_log(authctxt, authenticated, method);
|
||||
send_userauth_into_request(authctxt, 1);
|
||||
} else {
|
||||
/* verify skey response */
|
||||
if (authctxt->valid &&
|
||||
skey_haskey(authctxt->pw->pw_name) == 0 &&
|
||||
skey_passcheck(authctxt->pw->pw_name, resp) != -1) {
|
||||
authenticated = 1;
|
||||
} else {
|
||||
authenticated = 0;
|
||||
}
|
||||
memset(resp, 'r', rlen);
|
||||
/* unregister callback */
|
||||
dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, NULL);
|
||||
userauth_log(authctxt, authenticated, method);
|
||||
userauth_reply(authctxt, authenticated);
|
||||
}
|
||||
xfree(resp);
|
||||
}
|
||||
}
|
36
aux.c
36
aux.c
@ -1,36 +0,0 @@
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: aux.c,v 1.2 2000/05/17 09:47:59 markus Exp $");
|
||||
|
||||
#include "ssh.h"
|
||||
|
||||
char *
|
||||
chop(char *s)
|
||||
{
|
||||
char *t = s;
|
||||
while (*t) {
|
||||
if(*t == '\n' || *t == '\r') {
|
||||
*t = '\0';
|
||||
return s;
|
||||
}
|
||||
t++;
|
||||
}
|
||||
return s;
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
set_nonblock(int fd)
|
||||
{
|
||||
int val;
|
||||
val = fcntl(fd, F_GETFL, 0);
|
||||
if (val < 0) {
|
||||
error("fcntl(%d, F_GETFL, 0): %s", fd, strerror(errno));
|
||||
return;
|
||||
}
|
||||
if (val & O_NONBLOCK)
|
||||
return;
|
||||
debug("fd %d setting O_NONBLOCK", fd);
|
||||
val |= O_NONBLOCK;
|
||||
if (fcntl(fd, F_SETFL, val) == -1)
|
||||
error("fcntl(%d, F_SETFL, O_NONBLOCK): %s", fd, strerror(errno));
|
||||
}
|
55
bufaux.h
55
bufaux.h
@ -1,55 +0,0 @@
|
||||
/* $OpenBSD: bufaux.h,v 1.22 2006/03/25 22:22:42 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
*
|
||||
* As far as I am concerned, the code I have written for this software
|
||||
* can be used freely for any purpose. Any derived versions of this
|
||||
* software must be clearly marked as such, and if the derived work is
|
||||
* incompatible with the protocol description in the RFC file, it must be
|
||||
* called by a name other than "ssh" or "Secure Shell".
|
||||
*/
|
||||
|
||||
#ifndef BUFAUX_H
|
||||
#define BUFAUX_H
|
||||
|
||||
#include "buffer.h"
|
||||
#include <openssl/bn.h>
|
||||
|
||||
void buffer_put_bignum(Buffer *, const BIGNUM *);
|
||||
void buffer_put_bignum2(Buffer *, const BIGNUM *);
|
||||
void buffer_get_bignum(Buffer *, BIGNUM *);
|
||||
void buffer_get_bignum2(Buffer *, BIGNUM *);
|
||||
|
||||
u_short buffer_get_short(Buffer *);
|
||||
void buffer_put_short(Buffer *, u_short);
|
||||
|
||||
u_int buffer_get_int(Buffer *);
|
||||
void buffer_put_int(Buffer *, u_int);
|
||||
|
||||
u_int64_t buffer_get_int64(Buffer *);
|
||||
void buffer_put_int64(Buffer *, u_int64_t);
|
||||
|
||||
int buffer_get_char(Buffer *);
|
||||
void buffer_put_char(Buffer *, int);
|
||||
|
||||
void *buffer_get_string(Buffer *, u_int *);
|
||||
void buffer_put_string(Buffer *, const void *, u_int);
|
||||
void buffer_put_cstring(Buffer *, const char *);
|
||||
|
||||
#define buffer_skip_string(b) \
|
||||
do { u_int l = buffer_get_int(b); buffer_consume(b, l); } while (0)
|
||||
|
||||
int buffer_put_bignum_ret(Buffer *, const BIGNUM *);
|
||||
int buffer_get_bignum_ret(Buffer *, BIGNUM *);
|
||||
int buffer_put_bignum2_ret(Buffer *, const BIGNUM *);
|
||||
int buffer_get_bignum2_ret(Buffer *, BIGNUM *);
|
||||
int buffer_get_short_ret(u_short *, Buffer *);
|
||||
int buffer_get_int_ret(u_int *, Buffer *);
|
||||
int buffer_get_int64_ret(u_int64_t *, Buffer *);
|
||||
void *buffer_get_string_ret(Buffer *, u_int *);
|
||||
int buffer_get_char_ret(char *, Buffer *);
|
||||
|
||||
#endif /* BUFAUX_H */
|
231
cli.c
231
cli.c
@ -1,231 +0,0 @@
|
||||
/* $OpenBSD: cli.c,v 1.11 2001/03/06 00:33:04 deraadt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: cli.c,v 1.11 2001/03/06 00:33:04 deraadt Exp $");
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "log.h"
|
||||
#include "cli.h"
|
||||
|
||||
#include <vis.h>
|
||||
|
||||
static int cli_input = -1;
|
||||
static int cli_output = -1;
|
||||
static int cli_from_stdin = 0;
|
||||
|
||||
sigset_t oset;
|
||||
sigset_t nset;
|
||||
struct sigaction nsa;
|
||||
struct sigaction osa;
|
||||
struct termios ntio;
|
||||
struct termios otio;
|
||||
int echo_modified;
|
||||
|
||||
volatile int intr;
|
||||
|
||||
static int
|
||||
cli_open(int from_stdin)
|
||||
{
|
||||
if (cli_input >= 0 && cli_output >= 0 && cli_from_stdin == from_stdin)
|
||||
return 1;
|
||||
|
||||
if (from_stdin) {
|
||||
if (!cli_from_stdin && cli_input >= 0) {
|
||||
(void)close(cli_input);
|
||||
}
|
||||
cli_input = STDIN_FILENO;
|
||||
cli_output = STDERR_FILENO;
|
||||
} else {
|
||||
cli_input = cli_output = open(_PATH_TTY, O_RDWR);
|
||||
if (cli_input < 0)
|
||||
fatal("You have no controlling tty. Cannot read passphrase.");
|
||||
}
|
||||
|
||||
cli_from_stdin = from_stdin;
|
||||
|
||||
return cli_input >= 0 && cli_output >= 0 && cli_from_stdin == from_stdin;
|
||||
}
|
||||
|
||||
static void
|
||||
cli_close(void)
|
||||
{
|
||||
if (!cli_from_stdin && cli_input >= 0)
|
||||
close(cli_input);
|
||||
cli_input = -1;
|
||||
cli_output = -1;
|
||||
cli_from_stdin = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
intrcatch(int sig)
|
||||
{
|
||||
intr = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
cli_echo_disable(void)
|
||||
{
|
||||
sigemptyset(&nset);
|
||||
sigaddset(&nset, SIGTSTP);
|
||||
(void) sigprocmask(SIG_BLOCK, &nset, &oset);
|
||||
|
||||
intr = 0;
|
||||
|
||||
memset(&nsa, 0, sizeof(nsa));
|
||||
nsa.sa_handler = intrcatch;
|
||||
(void) sigaction(SIGINT, &nsa, &osa);
|
||||
|
||||
echo_modified = 0;
|
||||
if (tcgetattr(cli_input, &otio) == 0 && (otio.c_lflag & ECHO)) {
|
||||
echo_modified = 1;
|
||||
ntio = otio;
|
||||
ntio.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
|
||||
(void) tcsetattr(cli_input, TCSANOW, &ntio);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
cli_echo_restore(void)
|
||||
{
|
||||
if (echo_modified != 0) {
|
||||
tcsetattr(cli_input, TCSANOW, &otio);
|
||||
echo_modified = 0;
|
||||
}
|
||||
|
||||
(void) sigprocmask(SIG_SETMASK, &oset, NULL);
|
||||
(void) sigaction(SIGINT, &osa, NULL);
|
||||
|
||||
if (intr != 0) {
|
||||
kill(getpid(), SIGINT);
|
||||
sigemptyset(&nset);
|
||||
/* XXX tty has not neccessarily drained by now? */
|
||||
sigsuspend(&nset);
|
||||
intr = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static int
|
||||
cli_read(char* buf, int size, int echo)
|
||||
{
|
||||
char ch = 0;
|
||||
int i = 0;
|
||||
int n;
|
||||
|
||||
if (!echo)
|
||||
cli_echo_disable();
|
||||
|
||||
while (ch != '\n') {
|
||||
n = read(cli_input, &ch, 1);
|
||||
if (n == -1 && (errno == EAGAIN || errno == EINTR))
|
||||
continue;
|
||||
if (n != 1)
|
||||
break;
|
||||
if (ch == '\n' || intr != 0)
|
||||
break;
|
||||
if (i < size)
|
||||
buf[i++] = ch;
|
||||
}
|
||||
buf[i] = '\0';
|
||||
|
||||
if (!echo)
|
||||
cli_echo_restore();
|
||||
if (!intr && !echo)
|
||||
(void) write(cli_output, "\n", 1);
|
||||
return i;
|
||||
}
|
||||
|
||||
static int
|
||||
cli_write(char* buf, int size)
|
||||
{
|
||||
int i, len, pos, ret = 0;
|
||||
char *output, *p;
|
||||
|
||||
output = xmalloc(4*size);
|
||||
for (p = output, i = 0; i < size; i++) {
|
||||
if (buf[i] == '\n' || buf[i] == '\r')
|
||||
*p++ = buf[i];
|
||||
else
|
||||
p = vis(p, buf[i], 0, 0);
|
||||
}
|
||||
len = p - output;
|
||||
|
||||
for (pos = 0; pos < len; pos += ret) {
|
||||
ret = write(cli_output, output + pos, len - pos);
|
||||
if (ret == -1) {
|
||||
xfree(output);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
xfree(output);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Presents a prompt and returns the response allocated with xmalloc().
|
||||
* Uses /dev/tty or stdin/out depending on arg. Optionally disables echo
|
||||
* of response depending on arg. Tries to ensure that no other userland
|
||||
* buffer is storing the response.
|
||||
*/
|
||||
char*
|
||||
cli_read_passphrase(char* prompt, int from_stdin, int echo_enable)
|
||||
{
|
||||
char buf[BUFSIZ];
|
||||
char* p;
|
||||
|
||||
if (!cli_open(from_stdin))
|
||||
fatal("Cannot read passphrase.");
|
||||
|
||||
fflush(stdout);
|
||||
|
||||
cli_write(prompt, strlen(prompt));
|
||||
cli_read(buf, sizeof buf, echo_enable);
|
||||
|
||||
cli_close();
|
||||
|
||||
p = xstrdup(buf);
|
||||
memset(buf, 0, sizeof(buf));
|
||||
return (p);
|
||||
}
|
||||
|
||||
char*
|
||||
cli_prompt(char* prompt, int echo_enable)
|
||||
{
|
||||
return cli_read_passphrase(prompt, 0, echo_enable);
|
||||
}
|
||||
|
||||
void
|
||||
cli_mesg(char* mesg)
|
||||
{
|
||||
cli_open(0);
|
||||
cli_write(mesg, strlen(mesg));
|
||||
cli_write("\n", strlen("\n"));
|
||||
cli_close();
|
||||
return;
|
||||
}
|
42
cli.h
42
cli.h
@ -1,42 +0,0 @@
|
||||
/* $OpenBSD: cli.h,v 1.4 2001/03/01 03:38:33 deraadt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* $OpenBSD: cli.h,v 1.4 2001/03/01 03:38:33 deraadt Exp $ */
|
||||
|
||||
#ifndef CLI_H
|
||||
#define CLI_H
|
||||
|
||||
/*
|
||||
* Presents a prompt and returns the response allocated with xmalloc().
|
||||
* Uses /dev/tty or stdin/out depending on arg. Optionally disables echo
|
||||
* of response depending on arg. Tries to ensure that no other userland
|
||||
* buffer is storing the response.
|
||||
*/
|
||||
char * cli_read_passphrase(char * prompt, int from_stdin, int echo_enable);
|
||||
char * cli_prompt(char * prompt, int echo_enable);
|
||||
void cli_mesg(char * mesg);
|
||||
|
||||
#endif /* CLI_H */
|
304
dsa.c
304
dsa.c
@ -1,304 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: dsa.c,v 1.11 2000/09/07 20:27:51 deraadt Exp $");
|
||||
|
||||
#include "ssh.h"
|
||||
#include "xmalloc.h"
|
||||
#include "buffer.h"
|
||||
#include "bufaux.h"
|
||||
#include "compat.h"
|
||||
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/dh.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/dsa.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/pem.h>
|
||||
|
||||
#include <openssl/hmac.h>
|
||||
#include "kex.h"
|
||||
#include "key.h"
|
||||
#include "uuencode.h"
|
||||
|
||||
#define INTBLOB_LEN 20
|
||||
#define SIGBLOB_LEN (2*INTBLOB_LEN)
|
||||
|
||||
Key *
|
||||
dsa_key_from_blob(char *blob, int blen)
|
||||
{
|
||||
Buffer b;
|
||||
char *ktype;
|
||||
int rlen;
|
||||
DSA *dsa;
|
||||
Key *key;
|
||||
|
||||
#ifdef DEBUG_DSS
|
||||
dump_base64(stderr, blob, blen);
|
||||
#endif
|
||||
/* fetch & parse DSA/DSS pubkey */
|
||||
buffer_init(&b);
|
||||
buffer_append(&b, blob, blen);
|
||||
ktype = buffer_get_string(&b, NULL);
|
||||
if (strcmp(KEX_DSS, ktype) != 0) {
|
||||
error("dsa_key_from_blob: cannot handle type %s", ktype);
|
||||
buffer_free(&b);
|
||||
xfree(ktype);
|
||||
return NULL;
|
||||
}
|
||||
key = key_new(KEY_DSA);
|
||||
dsa = key->dsa;
|
||||
buffer_get_bignum2(&b, dsa->p);
|
||||
buffer_get_bignum2(&b, dsa->q);
|
||||
buffer_get_bignum2(&b, dsa->g);
|
||||
buffer_get_bignum2(&b, dsa->pub_key);
|
||||
rlen = buffer_len(&b);
|
||||
if(rlen != 0)
|
||||
error("dsa_key_from_blob: remaining bytes in key blob %d", rlen);
|
||||
buffer_free(&b);
|
||||
xfree(ktype);
|
||||
|
||||
#ifdef DEBUG_DSS
|
||||
DSA_print_fp(stderr, dsa, 8);
|
||||
#endif
|
||||
return key;
|
||||
}
|
||||
int
|
||||
dsa_make_key_blob(Key *key, unsigned char **blobp, unsigned int *lenp)
|
||||
{
|
||||
Buffer b;
|
||||
int len;
|
||||
unsigned char *buf;
|
||||
|
||||
if (key == NULL || key->type != KEY_DSA)
|
||||
return 0;
|
||||
buffer_init(&b);
|
||||
buffer_put_cstring(&b, KEX_DSS);
|
||||
buffer_put_bignum2(&b, key->dsa->p);
|
||||
buffer_put_bignum2(&b, key->dsa->q);
|
||||
buffer_put_bignum2(&b, key->dsa->g);
|
||||
buffer_put_bignum2(&b, key->dsa->pub_key);
|
||||
len = buffer_len(&b);
|
||||
buf = xmalloc(len);
|
||||
memcpy(buf, buffer_ptr(&b), len);
|
||||
memset(buffer_ptr(&b), 0, len);
|
||||
buffer_free(&b);
|
||||
if (lenp != NULL)
|
||||
*lenp = len;
|
||||
if (blobp != NULL)
|
||||
*blobp = buf;
|
||||
return len;
|
||||
}
|
||||
int
|
||||
dsa_sign(
|
||||
Key *key,
|
||||
unsigned char **sigp, int *lenp,
|
||||
unsigned char *data, int datalen)
|
||||
{
|
||||
unsigned char *digest;
|
||||
unsigned char *ret;
|
||||
DSA_SIG *sig;
|
||||
EVP_MD *evp_md = EVP_sha1();
|
||||
EVP_MD_CTX md;
|
||||
unsigned int rlen;
|
||||
unsigned int slen;
|
||||
unsigned int len;
|
||||
unsigned char sigblob[SIGBLOB_LEN];
|
||||
Buffer b;
|
||||
|
||||
if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) {
|
||||
error("dsa_sign: no DSA key");
|
||||
return -1;
|
||||
}
|
||||
digest = xmalloc(evp_md->md_size);
|
||||
EVP_DigestInit(&md, evp_md);
|
||||
EVP_DigestUpdate(&md, data, datalen);
|
||||
EVP_DigestFinal(&md, digest, NULL);
|
||||
|
||||
sig = DSA_do_sign(digest, evp_md->md_size, key->dsa);
|
||||
if (sig == NULL) {
|
||||
fatal("dsa_sign: cannot sign");
|
||||
}
|
||||
|
||||
rlen = BN_num_bytes(sig->r);
|
||||
slen = BN_num_bytes(sig->s);
|
||||
if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) {
|
||||
error("bad sig size %d %d", rlen, slen);
|
||||
DSA_SIG_free(sig);
|
||||
return -1;
|
||||
}
|
||||
debug("sig size %d %d", rlen, slen);
|
||||
|
||||
memset(sigblob, 0, SIGBLOB_LEN);
|
||||
BN_bn2bin(sig->r, sigblob+ SIGBLOB_LEN - INTBLOB_LEN - rlen);
|
||||
BN_bn2bin(sig->s, sigblob+ SIGBLOB_LEN - slen);
|
||||
DSA_SIG_free(sig);
|
||||
|
||||
if (datafellows & SSH_BUG_SIGBLOB) {
|
||||
debug("datafellows");
|
||||
ret = xmalloc(SIGBLOB_LEN);
|
||||
memcpy(ret, sigblob, SIGBLOB_LEN);
|
||||
if (lenp != NULL)
|
||||
*lenp = SIGBLOB_LEN;
|
||||
if (sigp != NULL)
|
||||
*sigp = ret;
|
||||
} else {
|
||||
/* ietf-drafts */
|
||||
buffer_init(&b);
|
||||
buffer_put_cstring(&b, KEX_DSS);
|
||||
buffer_put_string(&b, sigblob, SIGBLOB_LEN);
|
||||
len = buffer_len(&b);
|
||||
ret = xmalloc(len);
|
||||
memcpy(ret, buffer_ptr(&b), len);
|
||||
buffer_free(&b);
|
||||
if (lenp != NULL)
|
||||
*lenp = len;
|
||||
if (sigp != NULL)
|
||||
*sigp = ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int
|
||||
dsa_verify(
|
||||
Key *key,
|
||||
unsigned char *signature, int signaturelen,
|
||||
unsigned char *data, int datalen)
|
||||
{
|
||||
Buffer b;
|
||||
unsigned char *digest;
|
||||
DSA_SIG *sig;
|
||||
EVP_MD *evp_md = EVP_sha1();
|
||||
EVP_MD_CTX md;
|
||||
unsigned char *sigblob;
|
||||
char *txt;
|
||||
unsigned int len;
|
||||
int rlen;
|
||||
int ret;
|
||||
|
||||
if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) {
|
||||
error("dsa_verify: no DSA key");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!(datafellows & SSH_BUG_SIGBLOB) &&
|
||||
signaturelen == SIGBLOB_LEN) {
|
||||
datafellows |= ~SSH_BUG_SIGBLOB;
|
||||
log("autodetect SSH_BUG_SIGBLOB");
|
||||
} else if ((datafellows & SSH_BUG_SIGBLOB) &&
|
||||
signaturelen != SIGBLOB_LEN) {
|
||||
log("autoremove SSH_BUG_SIGBLOB");
|
||||
datafellows &= ~SSH_BUG_SIGBLOB;
|
||||
}
|
||||
|
||||
debug("len %d datafellows %d", signaturelen, datafellows);
|
||||
|
||||
/* fetch signature */
|
||||
if (datafellows & SSH_BUG_SIGBLOB) {
|
||||
sigblob = signature;
|
||||
len = signaturelen;
|
||||
} else {
|
||||
/* ietf-drafts */
|
||||
char *ktype;
|
||||
buffer_init(&b);
|
||||
buffer_append(&b, (char *) signature, signaturelen);
|
||||
ktype = buffer_get_string(&b, NULL);
|
||||
if (strcmp(KEX_DSS, ktype) != 0) {
|
||||
error("dsa_verify: cannot handle type %s", ktype);
|
||||
buffer_free(&b);
|
||||
return -1;
|
||||
}
|
||||
sigblob = (unsigned char *)buffer_get_string(&b, &len);
|
||||
rlen = buffer_len(&b);
|
||||
if(rlen != 0) {
|
||||
error("remaining bytes in signature %d", rlen);
|
||||
buffer_free(&b);
|
||||
return -1;
|
||||
}
|
||||
buffer_free(&b);
|
||||
xfree(ktype);
|
||||
}
|
||||
|
||||
if (len != SIGBLOB_LEN) {
|
||||
fatal("bad sigbloblen %d != SIGBLOB_LEN", len);
|
||||
}
|
||||
|
||||
/* parse signature */
|
||||
sig = DSA_SIG_new();
|
||||
sig->r = BN_new();
|
||||
sig->s = BN_new();
|
||||
BN_bin2bn(sigblob, INTBLOB_LEN, sig->r);
|
||||
BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, sig->s);
|
||||
|
||||
if (!(datafellows & SSH_BUG_SIGBLOB)) {
|
||||
memset(sigblob, 0, len);
|
||||
xfree(sigblob);
|
||||
}
|
||||
|
||||
/* sha1 the data */
|
||||
digest = xmalloc(evp_md->md_size);
|
||||
EVP_DigestInit(&md, evp_md);
|
||||
EVP_DigestUpdate(&md, data, datalen);
|
||||
EVP_DigestFinal(&md, digest, NULL);
|
||||
|
||||
ret = DSA_do_verify(digest, evp_md->md_size, sig, key->dsa);
|
||||
|
||||
memset(digest, 0, evp_md->md_size);
|
||||
xfree(digest);
|
||||
DSA_SIG_free(sig);
|
||||
|
||||
switch (ret) {
|
||||
case 1:
|
||||
txt = "correct";
|
||||
break;
|
||||
case 0:
|
||||
txt = "incorrect";
|
||||
break;
|
||||
case -1:
|
||||
default:
|
||||
txt = "error";
|
||||
break;
|
||||
}
|
||||
debug("dsa_verify: signature %s", txt);
|
||||
return ret;
|
||||
}
|
||||
|
||||
Key *
|
||||
dsa_generate_key(unsigned int bits)
|
||||
{
|
||||
DSA *dsa = DSA_generate_parameters(bits, NULL, 0, NULL, NULL, NULL, NULL);
|
||||
Key *k;
|
||||
if (dsa == NULL) {
|
||||
fatal("DSA_generate_parameters failed");
|
||||
}
|
||||
if (!DSA_generate_key(dsa)) {
|
||||
fatal("DSA_generate_keys failed");
|
||||
}
|
||||
|
||||
k = key_new(KEY_EMPTY);
|
||||
k->type = KEY_DSA;
|
||||
k->dsa = dsa;
|
||||
return k;
|
||||
}
|
45
dsa.h
45
dsa.h
@ -1,45 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef DSA_H
|
||||
#define DSA_H
|
||||
|
||||
Key *dsa_key_from_blob(char *blob, int blen);
|
||||
int dsa_make_key_blob(Key *key, unsigned char **blobp, unsigned int *lenp);
|
||||
|
||||
int
|
||||
dsa_sign(
|
||||
Key *key,
|
||||
unsigned char **sigp, int *lenp,
|
||||
unsigned char *data, int datalen);
|
||||
|
||||
int
|
||||
dsa_verify(
|
||||
Key *key,
|
||||
unsigned char *signature, int signaturelen,
|
||||
unsigned char *data, int datalen);
|
||||
|
||||
Key *
|
||||
dsa_generate_key(unsigned int bits);
|
||||
|
||||
#endif
|
@ -1,69 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1999 Markus Friedl. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Markus Friedl.
|
||||
* 4. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$Id: fingerprint.c,v 1.6 2000/04/12 09:39:10 markus Exp $");
|
||||
|
||||
#include "ssh.h"
|
||||
#include "xmalloc.h"
|
||||
#include <openssl/md5.h>
|
||||
|
||||
#define FPRINT "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x"
|
||||
|
||||
/*
|
||||
* Generate key fingerprint in ascii format.
|
||||
* Based on ideas and code from Bjoern Groenvall <bg@sics.se>
|
||||
*/
|
||||
char *
|
||||
fingerprint(BIGNUM *e, BIGNUM *n)
|
||||
{
|
||||
static char retval[80];
|
||||
MD5_CTX md;
|
||||
unsigned char d[16];
|
||||
unsigned char *buf;
|
||||
int nlen, elen;
|
||||
|
||||
nlen = BN_num_bytes(n);
|
||||
elen = BN_num_bytes(e);
|
||||
|
||||
buf = xmalloc(nlen + elen);
|
||||
|
||||
BN_bn2bin(n, buf);
|
||||
BN_bn2bin(e, buf + nlen);
|
||||
|
||||
MD5_Init(&md);
|
||||
MD5_Update(&md, buf, nlen + elen);
|
||||
MD5_Final(d, &md);
|
||||
snprintf(retval, sizeof(retval), FPRINT,
|
||||
d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7],
|
||||
d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
|
||||
memset(buf, 0, nlen + elen);
|
||||
xfree(buf);
|
||||
return retval;
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1999 Markus Friedl. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Markus Friedl.
|
||||
* 4. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/* RCSID("$Id: fingerprint.h,v 1.3 1999/11/24 16:15:25 markus Exp $"); */
|
||||
|
||||
#ifndef FINGERPRINT_H
|
||||
#define FINGERPRINT_H
|
||||
char *fingerprint(BIGNUM * e, BIGNUM * n);
|
||||
#endif
|
54
hmac.c
54
hmac.c
@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: hmac.c,v 1.4 2000/09/07 20:27:51 deraadt Exp $");
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "ssh.h"
|
||||
#include "getput.h"
|
||||
|
||||
#include <openssl/hmac.h>
|
||||
|
||||
unsigned char *
|
||||
hmac(
|
||||
EVP_MD *evp_md,
|
||||
unsigned int seqno,
|
||||
unsigned char *data, int datalen,
|
||||
unsigned char *key, int keylen)
|
||||
{
|
||||
HMAC_CTX c;
|
||||
static unsigned char m[EVP_MAX_MD_SIZE];
|
||||
unsigned char b[4];
|
||||
|
||||
if (key == NULL)
|
||||
fatal("hmac: no key");
|
||||
HMAC_Init(&c, key, keylen, evp_md);
|
||||
PUT_32BIT(b, seqno);
|
||||
HMAC_Update(&c, b, sizeof b);
|
||||
HMAC_Update(&c, data, datalen);
|
||||
HMAC_Final(&c, m, NULL);
|
||||
HMAC_cleanup(&c);
|
||||
return(m);
|
||||
}
|
34
hmac.h
34
hmac.h
@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef HMAC_H
|
||||
#define HMAC_H
|
||||
|
||||
unsigned char *
|
||||
hmac(
|
||||
EVP_MD *evp_md,
|
||||
unsigned int seqno,
|
||||
unsigned char *data, int datalen,
|
||||
unsigned char *key, int len);
|
||||
|
||||
#endif
|
35
lib/Makefile
35
lib/Makefile
@ -1,35 +0,0 @@
|
||||
# $OpenBSD: Makefile,v 1.36 2002/06/11 15:23:29 hin Exp $
|
||||
|
||||
.PATH: ${.CURDIR}/..
|
||||
|
||||
LIB= ssh
|
||||
SRCS= authfd.c authfile.c bufaux.c buffer.c canohost.c channels.c \
|
||||
cipher.c compat.c compress.c crc32.c deattack.c fatal.c \
|
||||
hostfile.c log.c match.c mpaux.c nchan.c packet.c readpass.c \
|
||||
rsa.c tildexpand.c ttymodes.c xmalloc.c atomicio.c \
|
||||
key.c dispatch.c kex.c mac.c uuencode.c misc.c \
|
||||
rijndael.c ssh-dss.c ssh-rsa.c dh.c kexdh.c kexgex.c \
|
||||
scard.c monitor_wrap.c monitor_fdpass.c msg.c
|
||||
|
||||
DEBUGLIBS= no
|
||||
NOPROFILE= yes
|
||||
NOPIC= yes
|
||||
|
||||
install:
|
||||
@echo -n
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
.if (${KERBEROS5:L} == "yes")
|
||||
CFLAGS+= -DKRB5 -I${DESTDIR}/usr/include/kerberosV
|
||||
.endif # KERBEROS5
|
||||
|
||||
.if (${KERBEROS:L} == "yes")
|
||||
CFLAGS+= -DKRB4 -I${DESTDIR}/usr/include/kerberosIV
|
||||
.if (${AFS:L} == "yes")
|
||||
CFLAGS+= -DAFS
|
||||
SRCS+= radix.c
|
||||
.endif # AFS
|
||||
.endif # KERBEROS
|
||||
|
||||
.include <bsd.lib.mk>
|
84
log-client.c
84
log-client.c
@ -1,84 +0,0 @@
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
* Client-side versions of debug(), log(), etc. These print to stderr.
|
||||
* This is a stripped down version of log-server.c.
|
||||
*
|
||||
* As far as I am concerned, the code I have written for this software
|
||||
* can be used freely for any purpose. Any derived versions of this
|
||||
* software must be clearly marked as such, and if the derived work is
|
||||
* incompatible with the protocol description in the RFC file, it must be
|
||||
* called by a name other than "ssh" or "Secure Shell".
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: log-client.c,v 1.12 2000/09/12 20:53:10 markus Exp $");
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "ssh.h"
|
||||
|
||||
static LogLevel log_level = SYSLOG_LEVEL_INFO;
|
||||
|
||||
/* Initialize the log.
|
||||
* av0 program name (should be argv[0])
|
||||
* level logging level
|
||||
*/
|
||||
|
||||
void
|
||||
log_init(char *av0, LogLevel level, SyslogFacility ignored1, int ignored2)
|
||||
{
|
||||
switch (level) {
|
||||
case SYSLOG_LEVEL_QUIET:
|
||||
case SYSLOG_LEVEL_ERROR:
|
||||
case SYSLOG_LEVEL_FATAL:
|
||||
case SYSLOG_LEVEL_INFO:
|
||||
case SYSLOG_LEVEL_VERBOSE:
|
||||
case SYSLOG_LEVEL_DEBUG1:
|
||||
case SYSLOG_LEVEL_DEBUG2:
|
||||
case SYSLOG_LEVEL_DEBUG3:
|
||||
log_level = level;
|
||||
break;
|
||||
default:
|
||||
/* unchanged */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#define MSGBUFSIZ 1024
|
||||
|
||||
void
|
||||
do_log(LogLevel level, const char *fmt, va_list args)
|
||||
{
|
||||
char msgbuf[MSGBUFSIZ];
|
||||
|
||||
if (level > log_level)
|
||||
return;
|
||||
if (level >= SYSLOG_LEVEL_DEBUG1)
|
||||
fprintf(stderr, "debug: ");
|
||||
vsnprintf(msgbuf, sizeof(msgbuf), fmt, args);
|
||||
fprintf(stderr, "%s\r\n", msgbuf);
|
||||
}
|
173
log-server.c
173
log-server.c
@ -1,173 +0,0 @@
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
* Server-side versions of debug(), log(), etc. These normally send the output
|
||||
* to the system log.
|
||||
*
|
||||
* As far as I am concerned, the code I have written for this software
|
||||
* can be used freely for any purpose. Any derived versions of this
|
||||
* software must be clearly marked as such, and if the derived work is
|
||||
* incompatible with the protocol description in the RFC file, it must be
|
||||
* called by a name other than "ssh" or "Secure Shell".
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: log-server.c,v 1.17 2000/09/12 20:53:10 markus Exp $");
|
||||
|
||||
#include <syslog.h>
|
||||
#include "packet.h"
|
||||
#include "xmalloc.h"
|
||||
#include "ssh.h"
|
||||
|
||||
static LogLevel log_level = SYSLOG_LEVEL_INFO;
|
||||
static int log_on_stderr = 0;
|
||||
static int log_facility = LOG_AUTH;
|
||||
|
||||
/* Initialize the log.
|
||||
* av0 program name (should be argv[0])
|
||||
* on_stderr print also on stderr
|
||||
* level logging level
|
||||
*/
|
||||
|
||||
void
|
||||
log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr)
|
||||
{
|
||||
switch (level) {
|
||||
case SYSLOG_LEVEL_QUIET:
|
||||
case SYSLOG_LEVEL_ERROR:
|
||||
case SYSLOG_LEVEL_FATAL:
|
||||
case SYSLOG_LEVEL_INFO:
|
||||
case SYSLOG_LEVEL_VERBOSE:
|
||||
case SYSLOG_LEVEL_DEBUG1:
|
||||
case SYSLOG_LEVEL_DEBUG2:
|
||||
case SYSLOG_LEVEL_DEBUG3:
|
||||
log_level = level;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Unrecognized internal syslog level code %d\n",
|
||||
(int) level);
|
||||
exit(1);
|
||||
}
|
||||
switch (facility) {
|
||||
case SYSLOG_FACILITY_DAEMON:
|
||||
log_facility = LOG_DAEMON;
|
||||
break;
|
||||
case SYSLOG_FACILITY_USER:
|
||||
log_facility = LOG_USER;
|
||||
break;
|
||||
case SYSLOG_FACILITY_AUTH:
|
||||
log_facility = LOG_AUTH;
|
||||
break;
|
||||
case SYSLOG_FACILITY_LOCAL0:
|
||||
log_facility = LOG_LOCAL0;
|
||||
break;
|
||||
case SYSLOG_FACILITY_LOCAL1:
|
||||
log_facility = LOG_LOCAL1;
|
||||
break;
|
||||
case SYSLOG_FACILITY_LOCAL2:
|
||||
log_facility = LOG_LOCAL2;
|
||||
break;
|
||||
case SYSLOG_FACILITY_LOCAL3:
|
||||
log_facility = LOG_LOCAL3;
|
||||
break;
|
||||
case SYSLOG_FACILITY_LOCAL4:
|
||||
log_facility = LOG_LOCAL4;
|
||||
break;
|
||||
case SYSLOG_FACILITY_LOCAL5:
|
||||
log_facility = LOG_LOCAL5;
|
||||
break;
|
||||
case SYSLOG_FACILITY_LOCAL6:
|
||||
log_facility = LOG_LOCAL6;
|
||||
break;
|
||||
case SYSLOG_FACILITY_LOCAL7:
|
||||
log_facility = LOG_LOCAL7;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Unrecognized internal syslog facility code %d\n",
|
||||
(int) facility);
|
||||
exit(1);
|
||||
}
|
||||
log_on_stderr = on_stderr;
|
||||
}
|
||||
|
||||
#define MSGBUFSIZ 1024
|
||||
|
||||
void
|
||||
do_log(LogLevel level, const char *fmt, va_list args)
|
||||
{
|
||||
char msgbuf[MSGBUFSIZ];
|
||||
char fmtbuf[MSGBUFSIZ];
|
||||
char *txt = NULL;
|
||||
int pri = LOG_INFO;
|
||||
extern char *__progname;
|
||||
|
||||
if (level > log_level)
|
||||
return;
|
||||
switch (level) {
|
||||
case SYSLOG_LEVEL_ERROR:
|
||||
txt = "error";
|
||||
pri = LOG_ERR;
|
||||
break;
|
||||
case SYSLOG_LEVEL_FATAL:
|
||||
txt = "fatal";
|
||||
pri = LOG_ERR;
|
||||
break;
|
||||
case SYSLOG_LEVEL_INFO:
|
||||
case SYSLOG_LEVEL_VERBOSE:
|
||||
pri = LOG_INFO;
|
||||
break;
|
||||
case SYSLOG_LEVEL_DEBUG1:
|
||||
txt = "debug1";
|
||||
pri = LOG_DEBUG;
|
||||
break;
|
||||
case SYSLOG_LEVEL_DEBUG2:
|
||||
txt = "debug2";
|
||||
pri = LOG_DEBUG;
|
||||
break;
|
||||
case SYSLOG_LEVEL_DEBUG3:
|
||||
txt = "debug3";
|
||||
pri = LOG_DEBUG;
|
||||
break;
|
||||
default:
|
||||
txt = "internal error";
|
||||
pri = LOG_ERR;
|
||||
break;
|
||||
}
|
||||
if (txt != NULL) {
|
||||
snprintf(fmtbuf, sizeof(fmtbuf), "%s: %s", txt, fmt);
|
||||
vsnprintf(msgbuf, sizeof(msgbuf), fmtbuf, args);
|
||||
} else {
|
||||
vsnprintf(msgbuf, sizeof(msgbuf), fmt, args);
|
||||
}
|
||||
if (log_on_stderr) {
|
||||
fprintf(stderr, "%s\n", msgbuf);
|
||||
} else {
|
||||
openlog(__progname, LOG_PID, log_facility);
|
||||
syslog(pri, "%.500s", msgbuf);
|
||||
closelog();
|
||||
}
|
||||
}
|
145
login.c
145
login.c
@ -1,145 +0,0 @@
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
* This file performs some of the things login(1) normally does. We cannot
|
||||
* easily use something like login -p -h host -f user, because there are
|
||||
* several different logins around, and it is hard to determined what kind of
|
||||
* login the current system has. Also, we want to be able to execute commands
|
||||
* on a tty.
|
||||
*
|
||||
* As far as I am concerned, the code I have written for this software
|
||||
* can be used freely for any purpose. Any derived versions of this
|
||||
* software must be clearly marked as such, and if the derived work is
|
||||
* incompatible with the protocol description in the RFC file, it must be
|
||||
* called by a name other than "ssh" or "Secure Shell".
|
||||
*
|
||||
* Copyright (c) 1999 Theo de Raadt. All rights reserved.
|
||||
* Copyright (c) 1999 Markus Friedl. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: login.c,v 1.15 2000/09/07 20:27:52 deraadt Exp $");
|
||||
|
||||
#include <util.h>
|
||||
#include <utmp.h>
|
||||
#include "ssh.h"
|
||||
|
||||
/*
|
||||
* Returns the time when the user last logged in. Returns 0 if the
|
||||
* information is not available. This must be called before record_login.
|
||||
* The host the user logged in from will be returned in buf.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Returns the time when the user last logged in (or 0 if no previous login
|
||||
* is found). The name of the host used last time is returned in buf.
|
||||
*/
|
||||
|
||||
unsigned long
|
||||
get_last_login_time(uid_t uid, const char *logname,
|
||||
char *buf, unsigned int bufsize)
|
||||
{
|
||||
struct lastlog ll;
|
||||
char *lastlog;
|
||||
int fd;
|
||||
|
||||
lastlog = _PATH_LASTLOG;
|
||||
buf[0] = '\0';
|
||||
|
||||
fd = open(lastlog, O_RDONLY);
|
||||
if (fd < 0)
|
||||
return 0;
|
||||
lseek(fd, (off_t) ((long) uid * sizeof(ll)), SEEK_SET);
|
||||
if (read(fd, &ll, sizeof(ll)) != sizeof(ll)) {
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
close(fd);
|
||||
if (bufsize > sizeof(ll.ll_host) + 1)
|
||||
bufsize = sizeof(ll.ll_host) + 1;
|
||||
strncpy(buf, ll.ll_host, bufsize - 1);
|
||||
buf[bufsize - 1] = 0;
|
||||
return ll.ll_time;
|
||||
}
|
||||
|
||||
/*
|
||||
* Records that the user has logged in. I these parts of operating systems
|
||||
* were more standardized.
|
||||
*/
|
||||
|
||||
void
|
||||
record_login(pid_t pid, const char *ttyname, const char *user, uid_t uid,
|
||||
const char *host, struct sockaddr * addr)
|
||||
{
|
||||
int fd;
|
||||
struct lastlog ll;
|
||||
char *lastlog;
|
||||
struct utmp u;
|
||||
const char *utmp, *wtmp;
|
||||
|
||||
/* Construct an utmp/wtmp entry. */
|
||||
memset(&u, 0, sizeof(u));
|
||||
strncpy(u.ut_line, ttyname + 5, sizeof(u.ut_line));
|
||||
u.ut_time = time(NULL);
|
||||
strncpy(u.ut_name, user, sizeof(u.ut_name));
|
||||
strncpy(u.ut_host, host, sizeof(u.ut_host));
|
||||
|
||||
/* Figure out the file names. */
|
||||
utmp = _PATH_UTMP;
|
||||
wtmp = _PATH_WTMP;
|
||||
|
||||
login(&u);
|
||||
lastlog = _PATH_LASTLOG;
|
||||
|
||||
/* Update lastlog unless actually recording a logout. */
|
||||
if (strcmp(user, "") != 0) {
|
||||
/*
|
||||
* It is safer to bzero the lastlog structure first because
|
||||
* some systems might have some extra fields in it (e.g. SGI)
|
||||
*/
|
||||
memset(&ll, 0, sizeof(ll));
|
||||
|
||||
/* Update lastlog. */
|
||||
ll.ll_time = time(NULL);
|
||||
strncpy(ll.ll_line, ttyname + 5, sizeof(ll.ll_line));
|
||||
strncpy(ll.ll_host, host, sizeof(ll.ll_host));
|
||||
fd = open(lastlog, O_RDWR);
|
||||
if (fd >= 0) {
|
||||
lseek(fd, (off_t) ((long) uid * sizeof(ll)), SEEK_SET);
|
||||
if (write(fd, &ll, sizeof(ll)) != sizeof(ll))
|
||||
log("Could not write %.100s: %.100s", lastlog, strerror(errno));
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Records that the user has logged out. */
|
||||
|
||||
void
|
||||
record_logout(pid_t pid, const char *ttyname)
|
||||
{
|
||||
const char *line = ttyname + 5; /* /dev/ttyq8 -> ttyq8 */
|
||||
if (logout(line))
|
||||
logwtmp(line, "", "");
|
||||
}
|
91
nchan.h
91
nchan.h
@ -1,91 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1999 Markus Friedl. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* RCSID("$OpenBSD: nchan.h,v 1.10 2001/02/28 08:54:55 markus Exp $"); */
|
||||
|
||||
#ifndef NCHAN_H
|
||||
#define NCHAN_H
|
||||
|
||||
/*
|
||||
* SSH Protocol 1.5 aka New Channel Protocol
|
||||
* Thanks to Martina, Axel and everyone who left Erlangen, leaving me bored.
|
||||
* Written by Markus Friedl in October 1999
|
||||
*
|
||||
* Protocol versions 1.3 and 1.5 differ in the handshake protocol used for the
|
||||
* tear down of channels:
|
||||
*
|
||||
* 1.3: strict request-ack-protocol:
|
||||
* CLOSE ->
|
||||
* <- CLOSE_CONFIRM
|
||||
*
|
||||
* 1.5: uses variations of:
|
||||
* IEOF ->
|
||||
* <- OCLOSE
|
||||
* <- IEOF
|
||||
* OCLOSE ->
|
||||
* i.e. both sides have to close the channel
|
||||
*
|
||||
* See the debugging output from 'ssh -v' and 'sshd -d' of
|
||||
* ssh-1.2.27 as an example.
|
||||
*
|
||||
*/
|
||||
|
||||
/* ssh-proto-1.5 overloads prot-1.3-message-types */
|
||||
#define SSH_MSG_CHANNEL_INPUT_EOF SSH_MSG_CHANNEL_CLOSE
|
||||
#define SSH_MSG_CHANNEL_OUTPUT_CLOSE SSH_MSG_CHANNEL_CLOSE_CONFIRMATION
|
||||
|
||||
/* possible input states */
|
||||
#define CHAN_INPUT_OPEN 0x01
|
||||
#define CHAN_INPUT_WAIT_DRAIN 0x02
|
||||
#define CHAN_INPUT_WAIT_OCLOSE 0x04
|
||||
#define CHAN_INPUT_CLOSED 0x08
|
||||
|
||||
/* possible output states */
|
||||
#define CHAN_OUTPUT_OPEN 0x10
|
||||
#define CHAN_OUTPUT_WAIT_DRAIN 0x20
|
||||
#define CHAN_OUTPUT_WAIT_IEOF 0x40
|
||||
#define CHAN_OUTPUT_CLOSED 0x80
|
||||
|
||||
#define CHAN_CLOSE_SENT 0x01
|
||||
#define CHAN_CLOSE_RCVD 0x02
|
||||
|
||||
|
||||
/* Channel EVENTS */
|
||||
typedef void chan_event_fn(Channel * c);
|
||||
|
||||
/* for the input state */
|
||||
extern chan_event_fn *chan_rcvd_oclose;
|
||||
extern chan_event_fn *chan_read_failed;
|
||||
extern chan_event_fn *chan_ibuf_empty;
|
||||
|
||||
/* for the output state */
|
||||
extern chan_event_fn *chan_rcvd_ieof;
|
||||
extern chan_event_fn *chan_write_failed;
|
||||
extern chan_event_fn *chan_obuf_empty;
|
||||
|
||||
int chan_is_dead(Channel * c);
|
||||
|
||||
void chan_init_iostates(Channel * c);
|
||||
void chan_init(void);
|
||||
#endif
|
@ -1,584 +0,0 @@
|
||||
/* $OpenBSD: queue.h,v 1.22 2001/06/23 04:39:35 angelos Exp $ */
|
||||
/* $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)queue.h 8.5 (Berkeley) 8/20/94
|
||||
*/
|
||||
|
||||
#ifndef _FAKE_QUEUE_H_
|
||||
#define _FAKE_QUEUE_H_
|
||||
|
||||
/*
|
||||
* Ignore all <sys/queue.h> since older platforms have broken/incomplete
|
||||
* <sys/queue.h> that are too hard to work around.
|
||||
*/
|
||||
#undef SLIST_HEAD
|
||||
#undef SLIST_HEAD_INITIALIZER
|
||||
#undef SLIST_ENTRY
|
||||
#undef SLIST_FIRST
|
||||
#undef SLIST_END
|
||||
#undef SLIST_EMPTY
|
||||
#undef SLIST_NEXT
|
||||
#undef SLIST_FOREACH
|
||||
#undef SLIST_INIT
|
||||
#undef SLIST_INSERT_AFTER
|
||||
#undef SLIST_INSERT_HEAD
|
||||
#undef SLIST_REMOVE_HEAD
|
||||
#undef SLIST_REMOVE
|
||||
#undef LIST_HEAD
|
||||
#undef LIST_HEAD_INITIALIZER
|
||||
#undef LIST_ENTRY
|
||||
#undef LIST_FIRST
|
||||
#undef LIST_END
|
||||
#undef LIST_EMPTY
|
||||
#undef LIST_NEXT
|
||||
#undef LIST_FOREACH
|
||||
#undef LIST_INIT
|
||||
#undef LIST_INSERT_AFTER
|
||||
#undef LIST_INSERT_BEFORE
|
||||
#undef LIST_INSERT_HEAD
|
||||
#undef LIST_REMOVE
|
||||
#undef LIST_REPLACE
|
||||
#undef SIMPLEQ_HEAD
|
||||
#undef SIMPLEQ_HEAD_INITIALIZER
|
||||
#undef SIMPLEQ_ENTRY
|
||||
#undef SIMPLEQ_FIRST
|
||||
#undef SIMPLEQ_END
|
||||
#undef SIMPLEQ_EMPTY
|
||||
#undef SIMPLEQ_NEXT
|
||||
#undef SIMPLEQ_FOREACH
|
||||
#undef SIMPLEQ_INIT
|
||||
#undef SIMPLEQ_INSERT_HEAD
|
||||
#undef SIMPLEQ_INSERT_TAIL
|
||||
#undef SIMPLEQ_INSERT_AFTER
|
||||
#undef SIMPLEQ_REMOVE_HEAD
|
||||
#undef TAILQ_HEAD
|
||||
#undef TAILQ_HEAD_INITIALIZER
|
||||
#undef TAILQ_ENTRY
|
||||
#undef TAILQ_FIRST
|
||||
#undef TAILQ_END
|
||||
#undef TAILQ_NEXT
|
||||
#undef TAILQ_LAST
|
||||
#undef TAILQ_PREV
|
||||
#undef TAILQ_EMPTY
|
||||
#undef TAILQ_FOREACH
|
||||
#undef TAILQ_FOREACH_REVERSE
|
||||
#undef TAILQ_INIT
|
||||
#undef TAILQ_INSERT_HEAD
|
||||
#undef TAILQ_INSERT_TAIL
|
||||
#undef TAILQ_INSERT_AFTER
|
||||
#undef TAILQ_INSERT_BEFORE
|
||||
#undef TAILQ_REMOVE
|
||||
#undef TAILQ_REPLACE
|
||||
#undef CIRCLEQ_HEAD
|
||||
#undef CIRCLEQ_HEAD_INITIALIZER
|
||||
#undef CIRCLEQ_ENTRY
|
||||
#undef CIRCLEQ_FIRST
|
||||
#undef CIRCLEQ_LAST
|
||||
#undef CIRCLEQ_END
|
||||
#undef CIRCLEQ_NEXT
|
||||
#undef CIRCLEQ_PREV
|
||||
#undef CIRCLEQ_EMPTY
|
||||
#undef CIRCLEQ_FOREACH
|
||||
#undef CIRCLEQ_FOREACH_REVERSE
|
||||
#undef CIRCLEQ_INIT
|
||||
#undef CIRCLEQ_INSERT_AFTER
|
||||
#undef CIRCLEQ_INSERT_BEFORE
|
||||
#undef CIRCLEQ_INSERT_HEAD
|
||||
#undef CIRCLEQ_INSERT_TAIL
|
||||
#undef CIRCLEQ_REMOVE
|
||||
#undef CIRCLEQ_REPLACE
|
||||
|
||||
/*
|
||||
* This file defines five types of data structures: singly-linked lists,
|
||||
* lists, simple queues, tail queues, and circular queues.
|
||||
*
|
||||
*
|
||||
* A singly-linked list is headed by a single forward pointer. The elements
|
||||
* are singly linked for minimum space and pointer manipulation overhead at
|
||||
* the expense of O(n) removal for arbitrary elements. New elements can be
|
||||
* added to the list after an existing element or at the head of the list.
|
||||
* Elements being removed from the head of the list should use the explicit
|
||||
* macro for this purpose for optimum efficiency. A singly-linked list may
|
||||
* only be traversed in the forward direction. Singly-linked lists are ideal
|
||||
* for applications with large datasets and few or no removals or for
|
||||
* implementing a LIFO queue.
|
||||
*
|
||||
* A list is headed by a single forward pointer (or an array of forward
|
||||
* pointers for a hash table header). The elements are doubly linked
|
||||
* so that an arbitrary element can be removed without a need to
|
||||
* traverse the list. New elements can be added to the list before
|
||||
* or after an existing element or at the head of the list. A list
|
||||
* may only be traversed in the forward direction.
|
||||
*
|
||||
* A simple queue is headed by a pair of pointers, one the head of the
|
||||
* list and the other to the tail of the list. The elements are singly
|
||||
* linked to save space, so elements can only be removed from the
|
||||
* head of the list. New elements can be added to the list before or after
|
||||
* an existing element, at the head of the list, or at the end of the
|
||||
* list. A simple queue may only be traversed in the forward direction.
|
||||
*
|
||||
* A tail queue is headed by a pair of pointers, one to the head of the
|
||||
* list and the other to the tail of the list. The elements are doubly
|
||||
* linked so that an arbitrary element can be removed without a need to
|
||||
* traverse the list. New elements can be added to the list before or
|
||||
* after an existing element, at the head of the list, or at the end of
|
||||
* the list. A tail queue may be traversed in either direction.
|
||||
*
|
||||
* A circle queue is headed by a pair of pointers, one to the head of the
|
||||
* list and the other to the tail of the list. The elements are doubly
|
||||
* linked so that an arbitrary element can be removed without a need to
|
||||
* traverse the list. New elements can be added to the list before or after
|
||||
* an existing element, at the head of the list, or at the end of the list.
|
||||
* A circle queue may be traversed in either direction, but has a more
|
||||
* complex end of list detection.
|
||||
*
|
||||
* For details on the use of these macros, see the queue(3) manual page.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Singly-linked List definitions.
|
||||
*/
|
||||
#define SLIST_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *slh_first; /* first element */ \
|
||||
}
|
||||
|
||||
#define SLIST_HEAD_INITIALIZER(head) \
|
||||
{ NULL }
|
||||
|
||||
#define SLIST_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *sle_next; /* next element */ \
|
||||
}
|
||||
|
||||
/*
|
||||
* Singly-linked List access methods.
|
||||
*/
|
||||
#define SLIST_FIRST(head) ((head)->slh_first)
|
||||
#define SLIST_END(head) NULL
|
||||
#define SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head))
|
||||
#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
|
||||
|
||||
#define SLIST_FOREACH(var, head, field) \
|
||||
for((var) = SLIST_FIRST(head); \
|
||||
(var) != SLIST_END(head); \
|
||||
(var) = SLIST_NEXT(var, field))
|
||||
|
||||
/*
|
||||
* Singly-linked List functions.
|
||||
*/
|
||||
#define SLIST_INIT(head) { \
|
||||
SLIST_FIRST(head) = SLIST_END(head); \
|
||||
}
|
||||
|
||||
#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
|
||||
(elm)->field.sle_next = (slistelm)->field.sle_next; \
|
||||
(slistelm)->field.sle_next = (elm); \
|
||||
} while (0)
|
||||
|
||||
#define SLIST_INSERT_HEAD(head, elm, field) do { \
|
||||
(elm)->field.sle_next = (head)->slh_first; \
|
||||
(head)->slh_first = (elm); \
|
||||
} while (0)
|
||||
|
||||
#define SLIST_REMOVE_HEAD(head, field) do { \
|
||||
(head)->slh_first = (head)->slh_first->field.sle_next; \
|
||||
} while (0)
|
||||
|
||||
#define SLIST_REMOVE(head, elm, type, field) do { \
|
||||
if ((head)->slh_first == (elm)) { \
|
||||
SLIST_REMOVE_HEAD((head), field); \
|
||||
} \
|
||||
else { \
|
||||
struct type *curelm = (head)->slh_first; \
|
||||
while( curelm->field.sle_next != (elm) ) \
|
||||
curelm = curelm->field.sle_next; \
|
||||
curelm->field.sle_next = \
|
||||
curelm->field.sle_next->field.sle_next; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* List definitions.
|
||||
*/
|
||||
#define LIST_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *lh_first; /* first element */ \
|
||||
}
|
||||
|
||||
#define LIST_HEAD_INITIALIZER(head) \
|
||||
{ NULL }
|
||||
|
||||
#define LIST_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *le_next; /* next element */ \
|
||||
struct type **le_prev; /* address of previous next element */ \
|
||||
}
|
||||
|
||||
/*
|
||||
* List access methods
|
||||
*/
|
||||
#define LIST_FIRST(head) ((head)->lh_first)
|
||||
#define LIST_END(head) NULL
|
||||
#define LIST_EMPTY(head) (LIST_FIRST(head) == LIST_END(head))
|
||||
#define LIST_NEXT(elm, field) ((elm)->field.le_next)
|
||||
|
||||
#define LIST_FOREACH(var, head, field) \
|
||||
for((var) = LIST_FIRST(head); \
|
||||
(var)!= LIST_END(head); \
|
||||
(var) = LIST_NEXT(var, field))
|
||||
|
||||
/*
|
||||
* List functions.
|
||||
*/
|
||||
#define LIST_INIT(head) do { \
|
||||
LIST_FIRST(head) = LIST_END(head); \
|
||||
} while (0)
|
||||
|
||||
#define LIST_INSERT_AFTER(listelm, elm, field) do { \
|
||||
if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
|
||||
(listelm)->field.le_next->field.le_prev = \
|
||||
&(elm)->field.le_next; \
|
||||
(listelm)->field.le_next = (elm); \
|
||||
(elm)->field.le_prev = &(listelm)->field.le_next; \
|
||||
} while (0)
|
||||
|
||||
#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
|
||||
(elm)->field.le_prev = (listelm)->field.le_prev; \
|
||||
(elm)->field.le_next = (listelm); \
|
||||
*(listelm)->field.le_prev = (elm); \
|
||||
(listelm)->field.le_prev = &(elm)->field.le_next; \
|
||||
} while (0)
|
||||
|
||||
#define LIST_INSERT_HEAD(head, elm, field) do { \
|
||||
if (((elm)->field.le_next = (head)->lh_first) != NULL) \
|
||||
(head)->lh_first->field.le_prev = &(elm)->field.le_next;\
|
||||
(head)->lh_first = (elm); \
|
||||
(elm)->field.le_prev = &(head)->lh_first; \
|
||||
} while (0)
|
||||
|
||||
#define LIST_REMOVE(elm, field) do { \
|
||||
if ((elm)->field.le_next != NULL) \
|
||||
(elm)->field.le_next->field.le_prev = \
|
||||
(elm)->field.le_prev; \
|
||||
*(elm)->field.le_prev = (elm)->field.le_next; \
|
||||
} while (0)
|
||||
|
||||
#define LIST_REPLACE(elm, elm2, field) do { \
|
||||
if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \
|
||||
(elm2)->field.le_next->field.le_prev = \
|
||||
&(elm2)->field.le_next; \
|
||||
(elm2)->field.le_prev = (elm)->field.le_prev; \
|
||||
*(elm2)->field.le_prev = (elm2); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Simple queue definitions.
|
||||
*/
|
||||
#define SIMPLEQ_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *sqh_first; /* first element */ \
|
||||
struct type **sqh_last; /* addr of last next element */ \
|
||||
}
|
||||
|
||||
#define SIMPLEQ_HEAD_INITIALIZER(head) \
|
||||
{ NULL, &(head).sqh_first }
|
||||
|
||||
#define SIMPLEQ_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *sqe_next; /* next element */ \
|
||||
}
|
||||
|
||||
/*
|
||||
* Simple queue access methods.
|
||||
*/
|
||||
#define SIMPLEQ_FIRST(head) ((head)->sqh_first)
|
||||
#define SIMPLEQ_END(head) NULL
|
||||
#define SIMPLEQ_EMPTY(head) (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head))
|
||||
#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next)
|
||||
|
||||
#define SIMPLEQ_FOREACH(var, head, field) \
|
||||
for((var) = SIMPLEQ_FIRST(head); \
|
||||
(var) != SIMPLEQ_END(head); \
|
||||
(var) = SIMPLEQ_NEXT(var, field))
|
||||
|
||||
/*
|
||||
* Simple queue functions.
|
||||
*/
|
||||
#define SIMPLEQ_INIT(head) do { \
|
||||
(head)->sqh_first = NULL; \
|
||||
(head)->sqh_last = &(head)->sqh_first; \
|
||||
} while (0)
|
||||
|
||||
#define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \
|
||||
if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \
|
||||
(head)->sqh_last = &(elm)->field.sqe_next; \
|
||||
(head)->sqh_first = (elm); \
|
||||
} while (0)
|
||||
|
||||
#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \
|
||||
(elm)->field.sqe_next = NULL; \
|
||||
*(head)->sqh_last = (elm); \
|
||||
(head)->sqh_last = &(elm)->field.sqe_next; \
|
||||
} while (0)
|
||||
|
||||
#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
|
||||
if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
|
||||
(head)->sqh_last = &(elm)->field.sqe_next; \
|
||||
(listelm)->field.sqe_next = (elm); \
|
||||
} while (0)
|
||||
|
||||
#define SIMPLEQ_REMOVE_HEAD(head, elm, field) do { \
|
||||
if (((head)->sqh_first = (elm)->field.sqe_next) == NULL) \
|
||||
(head)->sqh_last = &(head)->sqh_first; \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Tail queue definitions.
|
||||
*/
|
||||
#define TAILQ_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *tqh_first; /* first element */ \
|
||||
struct type **tqh_last; /* addr of last next element */ \
|
||||
}
|
||||
|
||||
#define TAILQ_HEAD_INITIALIZER(head) \
|
||||
{ NULL, &(head).tqh_first }
|
||||
|
||||
#define TAILQ_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *tqe_next; /* next element */ \
|
||||
struct type **tqe_prev; /* address of previous next element */ \
|
||||
}
|
||||
|
||||
/*
|
||||
* tail queue access methods
|
||||
*/
|
||||
#define TAILQ_FIRST(head) ((head)->tqh_first)
|
||||
#define TAILQ_END(head) NULL
|
||||
#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
|
||||
#define TAILQ_LAST(head, headname) \
|
||||
(*(((struct headname *)((head)->tqh_last))->tqh_last))
|
||||
/* XXX */
|
||||
#define TAILQ_PREV(elm, headname, field) \
|
||||
(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
|
||||
#define TAILQ_EMPTY(head) \
|
||||
(TAILQ_FIRST(head) == TAILQ_END(head))
|
||||
|
||||
#define TAILQ_FOREACH(var, head, field) \
|
||||
for((var) = TAILQ_FIRST(head); \
|
||||
(var) != TAILQ_END(head); \
|
||||
(var) = TAILQ_NEXT(var, field))
|
||||
|
||||
#define TAILQ_FOREACH_REVERSE(var, head, field, headname) \
|
||||
for((var) = TAILQ_LAST(head, headname); \
|
||||
(var) != TAILQ_END(head); \
|
||||
(var) = TAILQ_PREV(var, headname, field))
|
||||
|
||||
/*
|
||||
* Tail queue functions.
|
||||
*/
|
||||
#define TAILQ_INIT(head) do { \
|
||||
(head)->tqh_first = NULL; \
|
||||
(head)->tqh_last = &(head)->tqh_first; \
|
||||
} while (0)
|
||||
|
||||
#define TAILQ_INSERT_HEAD(head, elm, field) do { \
|
||||
if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
|
||||
(head)->tqh_first->field.tqe_prev = \
|
||||
&(elm)->field.tqe_next; \
|
||||
else \
|
||||
(head)->tqh_last = &(elm)->field.tqe_next; \
|
||||
(head)->tqh_first = (elm); \
|
||||
(elm)->field.tqe_prev = &(head)->tqh_first; \
|
||||
} while (0)
|
||||
|
||||
#define TAILQ_INSERT_TAIL(head, elm, field) do { \
|
||||
(elm)->field.tqe_next = NULL; \
|
||||
(elm)->field.tqe_prev = (head)->tqh_last; \
|
||||
*(head)->tqh_last = (elm); \
|
||||
(head)->tqh_last = &(elm)->field.tqe_next; \
|
||||
} while (0)
|
||||
|
||||
#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
|
||||
if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
|
||||
(elm)->field.tqe_next->field.tqe_prev = \
|
||||
&(elm)->field.tqe_next; \
|
||||
else \
|
||||
(head)->tqh_last = &(elm)->field.tqe_next; \
|
||||
(listelm)->field.tqe_next = (elm); \
|
||||
(elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
|
||||
} while (0)
|
||||
|
||||
#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
|
||||
(elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
|
||||
(elm)->field.tqe_next = (listelm); \
|
||||
*(listelm)->field.tqe_prev = (elm); \
|
||||
(listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
|
||||
} while (0)
|
||||
|
||||
#define TAILQ_REMOVE(head, elm, field) do { \
|
||||
if (((elm)->field.tqe_next) != NULL) \
|
||||
(elm)->field.tqe_next->field.tqe_prev = \
|
||||
(elm)->field.tqe_prev; \
|
||||
else \
|
||||
(head)->tqh_last = (elm)->field.tqe_prev; \
|
||||
*(elm)->field.tqe_prev = (elm)->field.tqe_next; \
|
||||
} while (0)
|
||||
|
||||
#define TAILQ_REPLACE(head, elm, elm2, field) do { \
|
||||
if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \
|
||||
(elm2)->field.tqe_next->field.tqe_prev = \
|
||||
&(elm2)->field.tqe_next; \
|
||||
else \
|
||||
(head)->tqh_last = &(elm2)->field.tqe_next; \
|
||||
(elm2)->field.tqe_prev = (elm)->field.tqe_prev; \
|
||||
*(elm2)->field.tqe_prev = (elm2); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Circular queue definitions.
|
||||
*/
|
||||
#define CIRCLEQ_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *cqh_first; /* first element */ \
|
||||
struct type *cqh_last; /* last element */ \
|
||||
}
|
||||
|
||||
#define CIRCLEQ_HEAD_INITIALIZER(head) \
|
||||
{ CIRCLEQ_END(&head), CIRCLEQ_END(&head) }
|
||||
|
||||
#define CIRCLEQ_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *cqe_next; /* next element */ \
|
||||
struct type *cqe_prev; /* previous element */ \
|
||||
}
|
||||
|
||||
/*
|
||||
* Circular queue access methods
|
||||
*/
|
||||
#define CIRCLEQ_FIRST(head) ((head)->cqh_first)
|
||||
#define CIRCLEQ_LAST(head) ((head)->cqh_last)
|
||||
#define CIRCLEQ_END(head) ((void *)(head))
|
||||
#define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next)
|
||||
#define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev)
|
||||
#define CIRCLEQ_EMPTY(head) \
|
||||
(CIRCLEQ_FIRST(head) == CIRCLEQ_END(head))
|
||||
|
||||
#define CIRCLEQ_FOREACH(var, head, field) \
|
||||
for((var) = CIRCLEQ_FIRST(head); \
|
||||
(var) != CIRCLEQ_END(head); \
|
||||
(var) = CIRCLEQ_NEXT(var, field))
|
||||
|
||||
#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \
|
||||
for((var) = CIRCLEQ_LAST(head); \
|
||||
(var) != CIRCLEQ_END(head); \
|
||||
(var) = CIRCLEQ_PREV(var, field))
|
||||
|
||||
/*
|
||||
* Circular queue functions.
|
||||
*/
|
||||
#define CIRCLEQ_INIT(head) do { \
|
||||
(head)->cqh_first = CIRCLEQ_END(head); \
|
||||
(head)->cqh_last = CIRCLEQ_END(head); \
|
||||
} while (0)
|
||||
|
||||
#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
|
||||
(elm)->field.cqe_next = (listelm)->field.cqe_next; \
|
||||
(elm)->field.cqe_prev = (listelm); \
|
||||
if ((listelm)->field.cqe_next == CIRCLEQ_END(head)) \
|
||||
(head)->cqh_last = (elm); \
|
||||
else \
|
||||
(listelm)->field.cqe_next->field.cqe_prev = (elm); \
|
||||
(listelm)->field.cqe_next = (elm); \
|
||||
} while (0)
|
||||
|
||||
#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \
|
||||
(elm)->field.cqe_next = (listelm); \
|
||||
(elm)->field.cqe_prev = (listelm)->field.cqe_prev; \
|
||||
if ((listelm)->field.cqe_prev == CIRCLEQ_END(head)) \
|
||||
(head)->cqh_first = (elm); \
|
||||
else \
|
||||
(listelm)->field.cqe_prev->field.cqe_next = (elm); \
|
||||
(listelm)->field.cqe_prev = (elm); \
|
||||
} while (0)
|
||||
|
||||
#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \
|
||||
(elm)->field.cqe_next = (head)->cqh_first; \
|
||||
(elm)->field.cqe_prev = CIRCLEQ_END(head); \
|
||||
if ((head)->cqh_last == CIRCLEQ_END(head)) \
|
||||
(head)->cqh_last = (elm); \
|
||||
else \
|
||||
(head)->cqh_first->field.cqe_prev = (elm); \
|
||||
(head)->cqh_first = (elm); \
|
||||
} while (0)
|
||||
|
||||
#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \
|
||||
(elm)->field.cqe_next = CIRCLEQ_END(head); \
|
||||
(elm)->field.cqe_prev = (head)->cqh_last; \
|
||||
if ((head)->cqh_first == CIRCLEQ_END(head)) \
|
||||
(head)->cqh_first = (elm); \
|
||||
else \
|
||||
(head)->cqh_last->field.cqe_next = (elm); \
|
||||
(head)->cqh_last = (elm); \
|
||||
} while (0)
|
||||
|
||||
#define CIRCLEQ_REMOVE(head, elm, field) do { \
|
||||
if ((elm)->field.cqe_next == CIRCLEQ_END(head)) \
|
||||
(head)->cqh_last = (elm)->field.cqe_prev; \
|
||||
else \
|
||||
(elm)->field.cqe_next->field.cqe_prev = \
|
||||
(elm)->field.cqe_prev; \
|
||||
if ((elm)->field.cqe_prev == CIRCLEQ_END(head)) \
|
||||
(head)->cqh_first = (elm)->field.cqe_next; \
|
||||
else \
|
||||
(elm)->field.cqe_prev->field.cqe_next = \
|
||||
(elm)->field.cqe_next; \
|
||||
} while (0)
|
||||
|
||||
#define CIRCLEQ_REPLACE(head, elm, elm2, field) do { \
|
||||
if (((elm2)->field.cqe_next = (elm)->field.cqe_next) == \
|
||||
CIRCLEQ_END(head)) \
|
||||
(head).cqh_last = (elm2); \
|
||||
else \
|
||||
(elm2)->field.cqe_next->field.cqe_prev = (elm2); \
|
||||
if (((elm2)->field.cqe_prev = (elm)->field.cqe_prev) == \
|
||||
CIRCLEQ_END(head)) \
|
||||
(head).cqh_first = (elm2); \
|
||||
else \
|
||||
(elm2)->field.cqe_prev->field.cqe_next = (elm2); \
|
||||
} while (0)
|
||||
|
||||
#endif /* !_FAKE_QUEUE_H_ */
|
@ -1,667 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_TREE_H_
|
||||
#define _SYS_TREE_H_
|
||||
|
||||
/*
|
||||
* This file defines data structures for different types of trees:
|
||||
* splay trees and red-black trees.
|
||||
*
|
||||
* A splay tree is a self-organizing data structure. Every operation
|
||||
* on the tree causes a splay to happen. The splay moves the requested
|
||||
* node to the root of the tree and partly rebalances it.
|
||||
*
|
||||
* This has the benefit that request locality causes faster lookups as
|
||||
* the requested nodes move to the top of the tree. On the other hand,
|
||||
* every lookup causes memory writes.
|
||||
*
|
||||
* The Balance Theorem bounds the total access time for m operations
|
||||
* and n inserts on an initially empty tree as O((m + n)lg n). The
|
||||
* amortized cost for a sequence of m accesses to a splay tree is O(lg n);
|
||||
*
|
||||
* A red-black tree is a binary search tree with the node color as an
|
||||
* extra attribute. It fulfills a set of conditions:
|
||||
* - every search path from the root to a leaf consists of the
|
||||
* same number of black nodes,
|
||||
* - each red node (except for the root) has a black parent,
|
||||
* - each leaf node is black.
|
||||
*
|
||||
* Every operation on a red-black tree is bounded as O(lg n).
|
||||
* The maximum height of a red-black tree is 2lg (n+1).
|
||||
*/
|
||||
|
||||
#define SPLAY_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *sph_root; /* root of the tree */ \
|
||||
}
|
||||
|
||||
#define SPLAY_INITIALIZER(root) \
|
||||
{ NULL }
|
||||
|
||||
#define SPLAY_INIT(root) do { \
|
||||
(root)->sph_root = NULL; \
|
||||
} while (0)
|
||||
|
||||
#define SPLAY_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *spe_left; /* left element */ \
|
||||
struct type *spe_right; /* right element */ \
|
||||
}
|
||||
|
||||
#define SPLAY_LEFT(elm, field) (elm)->field.spe_left
|
||||
#define SPLAY_RIGHT(elm, field) (elm)->field.spe_right
|
||||
#define SPLAY_ROOT(head) (head)->sph_root
|
||||
#define SPLAY_EMPTY(head) (SPLAY_ROOT(head) == NULL)
|
||||
|
||||
/* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */
|
||||
#define SPLAY_ROTATE_RIGHT(head, tmp, field) do { \
|
||||
SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field); \
|
||||
SPLAY_RIGHT(tmp, field) = (head)->sph_root; \
|
||||
(head)->sph_root = tmp; \
|
||||
} while (0)
|
||||
|
||||
#define SPLAY_ROTATE_LEFT(head, tmp, field) do { \
|
||||
SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field); \
|
||||
SPLAY_LEFT(tmp, field) = (head)->sph_root; \
|
||||
(head)->sph_root = tmp; \
|
||||
} while (0)
|
||||
|
||||
#define SPLAY_LINKLEFT(head, tmp, field) do { \
|
||||
SPLAY_LEFT(tmp, field) = (head)->sph_root; \
|
||||
tmp = (head)->sph_root; \
|
||||
(head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \
|
||||
} while (0)
|
||||
|
||||
#define SPLAY_LINKRIGHT(head, tmp, field) do { \
|
||||
SPLAY_RIGHT(tmp, field) = (head)->sph_root; \
|
||||
tmp = (head)->sph_root; \
|
||||
(head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \
|
||||
} while (0)
|
||||
|
||||
#define SPLAY_ASSEMBLE(head, node, left, right, field) do { \
|
||||
SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field); \
|
||||
SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field);\
|
||||
SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field); \
|
||||
SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field); \
|
||||
} while (0)
|
||||
|
||||
/* Generates prototypes and inline functions */
|
||||
|
||||
#define SPLAY_PROTOTYPE(name, type, field, cmp) \
|
||||
void name##_SPLAY(struct name *, struct type *); \
|
||||
void name##_SPLAY_MINMAX(struct name *, int); \
|
||||
\
|
||||
static __inline void \
|
||||
name##_SPLAY_INSERT(struct name *head, struct type *elm) \
|
||||
{ \
|
||||
if (SPLAY_EMPTY(head)) { \
|
||||
SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL; \
|
||||
} else { \
|
||||
int __comp; \
|
||||
name##_SPLAY(head, elm); \
|
||||
__comp = (cmp)(elm, (head)->sph_root); \
|
||||
if(__comp < 0) { \
|
||||
SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field);\
|
||||
SPLAY_RIGHT(elm, field) = (head)->sph_root; \
|
||||
SPLAY_LEFT((head)->sph_root, field) = NULL; \
|
||||
} else if (__comp > 0) { \
|
||||
SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field);\
|
||||
SPLAY_LEFT(elm, field) = (head)->sph_root; \
|
||||
SPLAY_RIGHT((head)->sph_root, field) = NULL; \
|
||||
} else \
|
||||
return; \
|
||||
} \
|
||||
(head)->sph_root = (elm); \
|
||||
} \
|
||||
\
|
||||
static __inline void \
|
||||
name##_SPLAY_REMOVE(struct name *head, struct type *elm) \
|
||||
{ \
|
||||
struct type *__tmp; \
|
||||
if (SPLAY_EMPTY(head)) \
|
||||
return; \
|
||||
name##_SPLAY(head, elm); \
|
||||
if ((cmp)(elm, (head)->sph_root) == 0) { \
|
||||
if (SPLAY_LEFT((head)->sph_root, field) == NULL) { \
|
||||
(head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);\
|
||||
} else { \
|
||||
__tmp = SPLAY_RIGHT((head)->sph_root, field); \
|
||||
(head)->sph_root = SPLAY_LEFT((head)->sph_root, field);\
|
||||
name##_SPLAY(head, elm); \
|
||||
SPLAY_RIGHT((head)->sph_root, field) = __tmp; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
/* Finds the node with the same key as elm */ \
|
||||
static __inline struct type * \
|
||||
name##_SPLAY_FIND(struct name *head, struct type *elm) \
|
||||
{ \
|
||||
if (SPLAY_EMPTY(head)) \
|
||||
return(NULL); \
|
||||
name##_SPLAY(head, elm); \
|
||||
if ((cmp)(elm, (head)->sph_root) == 0) \
|
||||
return (head->sph_root); \
|
||||
return (NULL); \
|
||||
} \
|
||||
\
|
||||
static __inline struct type * \
|
||||
name##_SPLAY_NEXT(struct name *head, struct type *elm) \
|
||||
{ \
|
||||
name##_SPLAY(head, elm); \
|
||||
if (SPLAY_RIGHT(elm, field) != NULL) { \
|
||||
elm = SPLAY_RIGHT(elm, field); \
|
||||
while (SPLAY_LEFT(elm, field) != NULL) { \
|
||||
elm = SPLAY_LEFT(elm, field); \
|
||||
} \
|
||||
} else \
|
||||
elm = NULL; \
|
||||
return (elm); \
|
||||
} \
|
||||
\
|
||||
static __inline struct type * \
|
||||
name##_SPLAY_MIN_MAX(struct name *head, int val) \
|
||||
{ \
|
||||
name##_SPLAY_MINMAX(head, val); \
|
||||
return (SPLAY_ROOT(head)); \
|
||||
}
|
||||
|
||||
/* Main splay operation.
|
||||
* Moves node close to the key of elm to top
|
||||
*/
|
||||
#define SPLAY_GENERATE(name, type, field, cmp) \
|
||||
void name##_SPLAY(struct name *head, struct type *elm) \
|
||||
{ \
|
||||
struct type __node, *__left, *__right, *__tmp; \
|
||||
int __comp; \
|
||||
\
|
||||
SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\
|
||||
__left = __right = &__node; \
|
||||
\
|
||||
while ((__comp = (cmp)(elm, (head)->sph_root))) { \
|
||||
if (__comp < 0) { \
|
||||
__tmp = SPLAY_LEFT((head)->sph_root, field); \
|
||||
if (__tmp == NULL) \
|
||||
break; \
|
||||
if ((cmp)(elm, __tmp) < 0){ \
|
||||
SPLAY_ROTATE_RIGHT(head, __tmp, field); \
|
||||
if (SPLAY_LEFT((head)->sph_root, field) == NULL)\
|
||||
break; \
|
||||
} \
|
||||
SPLAY_LINKLEFT(head, __right, field); \
|
||||
} else if (__comp > 0) { \
|
||||
__tmp = SPLAY_RIGHT((head)->sph_root, field); \
|
||||
if (__tmp == NULL) \
|
||||
break; \
|
||||
if ((cmp)(elm, __tmp) > 0){ \
|
||||
SPLAY_ROTATE_LEFT(head, __tmp, field); \
|
||||
if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\
|
||||
break; \
|
||||
} \
|
||||
SPLAY_LINKRIGHT(head, __left, field); \
|
||||
} \
|
||||
} \
|
||||
SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \
|
||||
} \
|
||||
\
|
||||
/* Splay with either the minimum or the maximum element \
|
||||
* Used to find minimum or maximum element in tree. \
|
||||
*/ \
|
||||
void name##_SPLAY_MINMAX(struct name *head, int __comp) \
|
||||
{ \
|
||||
struct type __node, *__left, *__right, *__tmp; \
|
||||
\
|
||||
SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\
|
||||
__left = __right = &__node; \
|
||||
\
|
||||
while (1) { \
|
||||
if (__comp < 0) { \
|
||||
__tmp = SPLAY_LEFT((head)->sph_root, field); \
|
||||
if (__tmp == NULL) \
|
||||
break; \
|
||||
if (__comp < 0){ \
|
||||
SPLAY_ROTATE_RIGHT(head, __tmp, field); \
|
||||
if (SPLAY_LEFT((head)->sph_root, field) == NULL)\
|
||||
break; \
|
||||
} \
|
||||
SPLAY_LINKLEFT(head, __right, field); \
|
||||
} else if (__comp > 0) { \
|
||||
__tmp = SPLAY_RIGHT((head)->sph_root, field); \
|
||||
if (__tmp == NULL) \
|
||||
break; \
|
||||
if (__comp > 0) { \
|
||||
SPLAY_ROTATE_LEFT(head, __tmp, field); \
|
||||
if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\
|
||||
break; \
|
||||
} \
|
||||
SPLAY_LINKRIGHT(head, __left, field); \
|
||||
} \
|
||||
} \
|
||||
SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \
|
||||
}
|
||||
|
||||
#define SPLAY_NEGINF -1
|
||||
#define SPLAY_INF 1
|
||||
|
||||
#define SPLAY_INSERT(name, x, y) name##_SPLAY_INSERT(x, y)
|
||||
#define SPLAY_REMOVE(name, x, y) name##_SPLAY_REMOVE(x, y)
|
||||
#define SPLAY_FIND(name, x, y) name##_SPLAY_FIND(x, y)
|
||||
#define SPLAY_NEXT(name, x, y) name##_SPLAY_NEXT(x, y)
|
||||
#define SPLAY_MIN(name, x) (SPLAY_EMPTY(x) ? NULL \
|
||||
: name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF))
|
||||
#define SPLAY_MAX(name, x) (SPLAY_EMPTY(x) ? NULL \
|
||||
: name##_SPLAY_MIN_MAX(x, SPLAY_INF))
|
||||
|
||||
#define SPLAY_FOREACH(x, name, head) \
|
||||
for ((x) = SPLAY_MIN(name, head); \
|
||||
(x) != NULL; \
|
||||
(x) = SPLAY_NEXT(name, head, x))
|
||||
|
||||
/* Macros that define a red-back tree */
|
||||
#define RB_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *rbh_root; /* root of the tree */ \
|
||||
}
|
||||
|
||||
#define RB_INITIALIZER(root) \
|
||||
{ NULL }
|
||||
|
||||
#define RB_INIT(root) do { \
|
||||
(root)->rbh_root = NULL; \
|
||||
} while (0)
|
||||
|
||||
#define RB_BLACK 0
|
||||
#define RB_RED 1
|
||||
#define RB_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *rbe_left; /* left element */ \
|
||||
struct type *rbe_right; /* right element */ \
|
||||
struct type *rbe_parent; /* parent element */ \
|
||||
int rbe_color; /* node color */ \
|
||||
}
|
||||
|
||||
#define RB_LEFT(elm, field) (elm)->field.rbe_left
|
||||
#define RB_RIGHT(elm, field) (elm)->field.rbe_right
|
||||
#define RB_PARENT(elm, field) (elm)->field.rbe_parent
|
||||
#define RB_COLOR(elm, field) (elm)->field.rbe_color
|
||||
#define RB_ROOT(head) (head)->rbh_root
|
||||
#define RB_EMPTY(head) (RB_ROOT(head) == NULL)
|
||||
|
||||
#define RB_SET(elm, parent, field) do { \
|
||||
RB_PARENT(elm, field) = parent; \
|
||||
RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL; \
|
||||
RB_COLOR(elm, field) = RB_RED; \
|
||||
} while (0)
|
||||
|
||||
#define RB_SET_BLACKRED(black, red, field) do { \
|
||||
RB_COLOR(black, field) = RB_BLACK; \
|
||||
RB_COLOR(red, field) = RB_RED; \
|
||||
} while (0)
|
||||
|
||||
#ifndef RB_AUGMENT
|
||||
#define RB_AUGMENT(x)
|
||||
#endif
|
||||
|
||||
#define RB_ROTATE_LEFT(head, elm, tmp, field) do { \
|
||||
(tmp) = RB_RIGHT(elm, field); \
|
||||
if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field))) { \
|
||||
RB_PARENT(RB_LEFT(tmp, field), field) = (elm); \
|
||||
} \
|
||||
RB_AUGMENT(elm); \
|
||||
if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) { \
|
||||
if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \
|
||||
RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \
|
||||
else \
|
||||
RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \
|
||||
RB_AUGMENT(RB_PARENT(elm, field)); \
|
||||
} else \
|
||||
(head)->rbh_root = (tmp); \
|
||||
RB_LEFT(tmp, field) = (elm); \
|
||||
RB_PARENT(elm, field) = (tmp); \
|
||||
RB_AUGMENT(tmp); \
|
||||
} while (0)
|
||||
|
||||
#define RB_ROTATE_RIGHT(head, elm, tmp, field) do { \
|
||||
(tmp) = RB_LEFT(elm, field); \
|
||||
if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field))) { \
|
||||
RB_PARENT(RB_RIGHT(tmp, field), field) = (elm); \
|
||||
} \
|
||||
RB_AUGMENT(elm); \
|
||||
if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) { \
|
||||
if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \
|
||||
RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \
|
||||
else \
|
||||
RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \
|
||||
RB_AUGMENT(RB_PARENT(elm, field)); \
|
||||
} else \
|
||||
(head)->rbh_root = (tmp); \
|
||||
RB_RIGHT(tmp, field) = (elm); \
|
||||
RB_PARENT(elm, field) = (tmp); \
|
||||
RB_AUGMENT(tmp); \
|
||||
} while (0)
|
||||
|
||||
/* Generates prototypes and inline functions */
|
||||
#define RB_PROTOTYPE(name, type, field, cmp) \
|
||||
void name##_RB_INSERT_COLOR(struct name *, struct type *); \
|
||||
void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\
|
||||
void name##_RB_REMOVE(struct name *, struct type *); \
|
||||
struct type *name##_RB_INSERT(struct name *, struct type *); \
|
||||
struct type *name##_RB_FIND(struct name *, struct type *); \
|
||||
struct type *name##_RB_NEXT(struct name *, struct type *); \
|
||||
struct type *name##_RB_MINMAX(struct name *, int); \
|
||||
\
|
||||
|
||||
/* Main rb operation.
|
||||
* Moves node close to the key of elm to top
|
||||
*/
|
||||
#define RB_GENERATE(name, type, field, cmp) \
|
||||
void \
|
||||
name##_RB_INSERT_COLOR(struct name *head, struct type *elm) \
|
||||
{ \
|
||||
struct type *parent, *gparent, *tmp; \
|
||||
while ((parent = RB_PARENT(elm, field)) && \
|
||||
RB_COLOR(parent, field) == RB_RED) { \
|
||||
gparent = RB_PARENT(parent, field); \
|
||||
if (parent == RB_LEFT(gparent, field)) { \
|
||||
tmp = RB_RIGHT(gparent, field); \
|
||||
if (tmp && RB_COLOR(tmp, field) == RB_RED) { \
|
||||
RB_COLOR(tmp, field) = RB_BLACK; \
|
||||
RB_SET_BLACKRED(parent, gparent, field);\
|
||||
elm = gparent; \
|
||||
continue; \
|
||||
} \
|
||||
if (RB_RIGHT(parent, field) == elm) { \
|
||||
RB_ROTATE_LEFT(head, parent, tmp, field);\
|
||||
tmp = parent; \
|
||||
parent = elm; \
|
||||
elm = tmp; \
|
||||
} \
|
||||
RB_SET_BLACKRED(parent, gparent, field); \
|
||||
RB_ROTATE_RIGHT(head, gparent, tmp, field); \
|
||||
} else { \
|
||||
tmp = RB_LEFT(gparent, field); \
|
||||
if (tmp && RB_COLOR(tmp, field) == RB_RED) { \
|
||||
RB_COLOR(tmp, field) = RB_BLACK; \
|
||||
RB_SET_BLACKRED(parent, gparent, field);\
|
||||
elm = gparent; \
|
||||
continue; \
|
||||
} \
|
||||
if (RB_LEFT(parent, field) == elm) { \
|
||||
RB_ROTATE_RIGHT(head, parent, tmp, field);\
|
||||
tmp = parent; \
|
||||
parent = elm; \
|
||||
elm = tmp; \
|
||||
} \
|
||||
RB_SET_BLACKRED(parent, gparent, field); \
|
||||
RB_ROTATE_LEFT(head, gparent, tmp, field); \
|
||||
} \
|
||||
} \
|
||||
RB_COLOR(head->rbh_root, field) = RB_BLACK; \
|
||||
} \
|
||||
\
|
||||
void \
|
||||
name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) \
|
||||
{ \
|
||||
struct type *tmp; \
|
||||
while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) && \
|
||||
elm != RB_ROOT(head)) { \
|
||||
if (RB_LEFT(parent, field) == elm) { \
|
||||
tmp = RB_RIGHT(parent, field); \
|
||||
if (RB_COLOR(tmp, field) == RB_RED) { \
|
||||
RB_SET_BLACKRED(tmp, parent, field); \
|
||||
RB_ROTATE_LEFT(head, parent, tmp, field);\
|
||||
tmp = RB_RIGHT(parent, field); \
|
||||
} \
|
||||
if ((RB_LEFT(tmp, field) == NULL || \
|
||||
RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\
|
||||
(RB_RIGHT(tmp, field) == NULL || \
|
||||
RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\
|
||||
RB_COLOR(tmp, field) = RB_RED; \
|
||||
elm = parent; \
|
||||
parent = RB_PARENT(elm, field); \
|
||||
} else { \
|
||||
if (RB_RIGHT(tmp, field) == NULL || \
|
||||
RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) {\
|
||||
struct type *oleft; \
|
||||
if ((oleft = RB_LEFT(tmp, field)))\
|
||||
RB_COLOR(oleft, field) = RB_BLACK;\
|
||||
RB_COLOR(tmp, field) = RB_RED; \
|
||||
RB_ROTATE_RIGHT(head, tmp, oleft, field);\
|
||||
tmp = RB_RIGHT(parent, field); \
|
||||
} \
|
||||
RB_COLOR(tmp, field) = RB_COLOR(parent, field);\
|
||||
RB_COLOR(parent, field) = RB_BLACK; \
|
||||
if (RB_RIGHT(tmp, field)) \
|
||||
RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK;\
|
||||
RB_ROTATE_LEFT(head, parent, tmp, field);\
|
||||
elm = RB_ROOT(head); \
|
||||
break; \
|
||||
} \
|
||||
} else { \
|
||||
tmp = RB_LEFT(parent, field); \
|
||||
if (RB_COLOR(tmp, field) == RB_RED) { \
|
||||
RB_SET_BLACKRED(tmp, parent, field); \
|
||||
RB_ROTATE_RIGHT(head, parent, tmp, field);\
|
||||
tmp = RB_LEFT(parent, field); \
|
||||
} \
|
||||
if ((RB_LEFT(tmp, field) == NULL || \
|
||||
RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\
|
||||
(RB_RIGHT(tmp, field) == NULL || \
|
||||
RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\
|
||||
RB_COLOR(tmp, field) = RB_RED; \
|
||||
elm = parent; \
|
||||
parent = RB_PARENT(elm, field); \
|
||||
} else { \
|
||||
if (RB_LEFT(tmp, field) == NULL || \
|
||||
RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) {\
|
||||
struct type *oright; \
|
||||
if ((oright = RB_RIGHT(tmp, field)))\
|
||||
RB_COLOR(oright, field) = RB_BLACK;\
|
||||
RB_COLOR(tmp, field) = RB_RED; \
|
||||
RB_ROTATE_LEFT(head, tmp, oright, field);\
|
||||
tmp = RB_LEFT(parent, field); \
|
||||
} \
|
||||
RB_COLOR(tmp, field) = RB_COLOR(parent, field);\
|
||||
RB_COLOR(parent, field) = RB_BLACK; \
|
||||
if (RB_LEFT(tmp, field)) \
|
||||
RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK;\
|
||||
RB_ROTATE_RIGHT(head, parent, tmp, field);\
|
||||
elm = RB_ROOT(head); \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
if (elm) \
|
||||
RB_COLOR(elm, field) = RB_BLACK; \
|
||||
} \
|
||||
\
|
||||
void \
|
||||
name##_RB_REMOVE(struct name *head, struct type *elm) \
|
||||
{ \
|
||||
struct type *child, *parent; \
|
||||
int color; \
|
||||
if (RB_LEFT(elm, field) == NULL) \
|
||||
child = RB_RIGHT(elm, field); \
|
||||
else if (RB_RIGHT(elm, field) == NULL) \
|
||||
child = RB_LEFT(elm, field); \
|
||||
else { \
|
||||
struct type *old = elm, *left; \
|
||||
elm = RB_RIGHT(elm, field); \
|
||||
while ((left = RB_LEFT(elm, field))) \
|
||||
elm = left; \
|
||||
child = RB_RIGHT(elm, field); \
|
||||
parent = RB_PARENT(elm, field); \
|
||||
color = RB_COLOR(elm, field); \
|
||||
if (child) \
|
||||
RB_PARENT(child, field) = parent; \
|
||||
if (parent) { \
|
||||
if (RB_LEFT(parent, field) == elm) \
|
||||
RB_LEFT(parent, field) = child; \
|
||||
else \
|
||||
RB_RIGHT(parent, field) = child; \
|
||||
RB_AUGMENT(parent); \
|
||||
} else \
|
||||
RB_ROOT(head) = child; \
|
||||
if (RB_PARENT(elm, field) == old) \
|
||||
parent = elm; \
|
||||
(elm)->field = (old)->field; \
|
||||
if (RB_PARENT(old, field)) { \
|
||||
if (RB_LEFT(RB_PARENT(old, field), field) == old)\
|
||||
RB_LEFT(RB_PARENT(old, field), field) = elm;\
|
||||
else \
|
||||
RB_RIGHT(RB_PARENT(old, field), field) = elm;\
|
||||
RB_AUGMENT(RB_PARENT(old, field)); \
|
||||
} else \
|
||||
RB_ROOT(head) = elm; \
|
||||
RB_PARENT(RB_LEFT(old, field), field) = elm; \
|
||||
if (RB_RIGHT(old, field)) \
|
||||
RB_PARENT(RB_RIGHT(old, field), field) = elm; \
|
||||
if (parent) { \
|
||||
left = parent; \
|
||||
do { \
|
||||
RB_AUGMENT(left); \
|
||||
} while ((left = RB_PARENT(left, field))); \
|
||||
} \
|
||||
goto color; \
|
||||
} \
|
||||
parent = RB_PARENT(elm, field); \
|
||||
color = RB_COLOR(elm, field); \
|
||||
if (child) \
|
||||
RB_PARENT(child, field) = parent; \
|
||||
if (parent) { \
|
||||
if (RB_LEFT(parent, field) == elm) \
|
||||
RB_LEFT(parent, field) = child; \
|
||||
else \
|
||||
RB_RIGHT(parent, field) = child; \
|
||||
RB_AUGMENT(parent); \
|
||||
} else \
|
||||
RB_ROOT(head) = child; \
|
||||
color: \
|
||||
if (color == RB_BLACK) \
|
||||
name##_RB_REMOVE_COLOR(head, parent, child); \
|
||||
} \
|
||||
\
|
||||
/* Inserts a node into the RB tree */ \
|
||||
struct type * \
|
||||
name##_RB_INSERT(struct name *head, struct type *elm) \
|
||||
{ \
|
||||
struct type *tmp; \
|
||||
struct type *parent = NULL; \
|
||||
int comp = 0; \
|
||||
tmp = RB_ROOT(head); \
|
||||
while (tmp) { \
|
||||
parent = tmp; \
|
||||
comp = (cmp)(elm, parent); \
|
||||
if (comp < 0) \
|
||||
tmp = RB_LEFT(tmp, field); \
|
||||
else if (comp > 0) \
|
||||
tmp = RB_RIGHT(tmp, field); \
|
||||
else \
|
||||
return (tmp); \
|
||||
} \
|
||||
RB_SET(elm, parent, field); \
|
||||
if (parent != NULL) { \
|
||||
if (comp < 0) \
|
||||
RB_LEFT(parent, field) = elm; \
|
||||
else \
|
||||
RB_RIGHT(parent, field) = elm; \
|
||||
RB_AUGMENT(parent); \
|
||||
} else \
|
||||
RB_ROOT(head) = elm; \
|
||||
name##_RB_INSERT_COLOR(head, elm); \
|
||||
return (NULL); \
|
||||
} \
|
||||
\
|
||||
/* Finds the node with the same key as elm */ \
|
||||
struct type * \
|
||||
name##_RB_FIND(struct name *head, struct type *elm) \
|
||||
{ \
|
||||
struct type *tmp = RB_ROOT(head); \
|
||||
int comp; \
|
||||
while (tmp) { \
|
||||
comp = cmp(elm, tmp); \
|
||||
if (comp < 0) \
|
||||
tmp = RB_LEFT(tmp, field); \
|
||||
else if (comp > 0) \
|
||||
tmp = RB_RIGHT(tmp, field); \
|
||||
else \
|
||||
return (tmp); \
|
||||
} \
|
||||
return (NULL); \
|
||||
} \
|
||||
\
|
||||
struct type * \
|
||||
name##_RB_NEXT(struct name *head, struct type *elm) \
|
||||
{ \
|
||||
if (RB_RIGHT(elm, field)) { \
|
||||
elm = RB_RIGHT(elm, field); \
|
||||
while (RB_LEFT(elm, field)) \
|
||||
elm = RB_LEFT(elm, field); \
|
||||
} else { \
|
||||
if (RB_PARENT(elm, field) && \
|
||||
(elm == RB_LEFT(RB_PARENT(elm, field), field))) \
|
||||
elm = RB_PARENT(elm, field); \
|
||||
else { \
|
||||
while (RB_PARENT(elm, field) && \
|
||||
(elm == RB_RIGHT(RB_PARENT(elm, field), field)))\
|
||||
elm = RB_PARENT(elm, field); \
|
||||
elm = RB_PARENT(elm, field); \
|
||||
} \
|
||||
} \
|
||||
return (elm); \
|
||||
} \
|
||||
\
|
||||
struct type * \
|
||||
name##_RB_MINMAX(struct name *head, int val) \
|
||||
{ \
|
||||
struct type *tmp = RB_ROOT(head); \
|
||||
struct type *parent = NULL; \
|
||||
while (tmp) { \
|
||||
parent = tmp; \
|
||||
if (val < 0) \
|
||||
tmp = RB_LEFT(tmp, field); \
|
||||
else \
|
||||
tmp = RB_RIGHT(tmp, field); \
|
||||
} \
|
||||
return (parent); \
|
||||
}
|
||||
|
||||
#define RB_NEGINF -1
|
||||
#define RB_INF 1
|
||||
|
||||
#define RB_INSERT(name, x, y) name##_RB_INSERT(x, y)
|
||||
#define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y)
|
||||
#define RB_FIND(name, x, y) name##_RB_FIND(x, y)
|
||||
#define RB_NEXT(name, x, y) name##_RB_NEXT(x, y)
|
||||
#define RB_MIN(name, x) name##_RB_MINMAX(x, RB_NEGINF)
|
||||
#define RB_MAX(name, x) name##_RB_MINMAX(x, RB_INF)
|
||||
|
||||
#define RB_FOREACH(x, name, head) \
|
||||
for ((x) = RB_MIN(name, head); \
|
||||
(x) != NULL; \
|
||||
(x) = name##_RB_NEXT(head, x))
|
||||
|
||||
#endif /* _SYS_TREE_H_ */
|
275
pty.c
275
pty.c
@ -1,275 +0,0 @@
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
* Allocating a pseudo-terminal, and making it the controlling tty.
|
||||
*
|
||||
* As far as I am concerned, the code I have written for this software
|
||||
* can be used freely for any purpose. Any derived versions of this
|
||||
* software must be clearly marked as such, and if the derived work is
|
||||
* incompatible with the protocol description in the RFC file, it must be
|
||||
* called by a name other than "ssh" or "Secure Shell".
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: pty.c,v 1.16 2000/09/07 21:13:37 markus Exp $");
|
||||
|
||||
#include <util.h>
|
||||
#include "pty.h"
|
||||
#include "ssh.h"
|
||||
|
||||
/* Pty allocated with _getpty gets broken if we do I_PUSH:es to it. */
|
||||
#if defined(HAVE__GETPTY) || defined(HAVE_OPENPTY)
|
||||
#undef HAVE_DEV_PTMX
|
||||
#endif
|
||||
|
||||
#ifndef O_NOCTTY
|
||||
#define O_NOCTTY 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Allocates and opens a pty. Returns 0 if no pty could be allocated, or
|
||||
* nonzero if a pty was successfully allocated. On success, open file
|
||||
* descriptors for the pty and tty sides and the name of the tty side are
|
||||
* returned (the buffer must be able to hold at least 64 characters).
|
||||
*/
|
||||
|
||||
int
|
||||
pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen)
|
||||
{
|
||||
#if defined(HAVE_OPENPTY) || defined(BSD4_4)
|
||||
/* openpty(3) exists in OSF/1 and some other os'es */
|
||||
char buf[64];
|
||||
int i;
|
||||
|
||||
i = openpty(ptyfd, ttyfd, buf, NULL, NULL);
|
||||
if (i < 0) {
|
||||
error("openpty: %.100s", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
strlcpy(namebuf, buf, namebuflen); /* possible truncation */
|
||||
return 1;
|
||||
#else /* HAVE_OPENPTY */
|
||||
#ifdef HAVE__GETPTY
|
||||
/*
|
||||
* _getpty(3) exists in SGI Irix 4.x, 5.x & 6.x -- it generates more
|
||||
* pty's automagically when needed
|
||||
*/
|
||||
char *slave;
|
||||
|
||||
slave = _getpty(ptyfd, O_RDWR, 0622, 0);
|
||||
if (slave == NULL) {
|
||||
error("_getpty: %.100s", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
strlcpy(namebuf, slave, namebuflen);
|
||||
/* Open the slave side. */
|
||||
*ttyfd = open(namebuf, O_RDWR | O_NOCTTY);
|
||||
if (*ttyfd < 0) {
|
||||
error("%.200s: %.100s", namebuf, strerror(errno));
|
||||
close(*ptyfd);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
#else /* HAVE__GETPTY */
|
||||
#ifdef HAVE_DEV_PTMX
|
||||
/*
|
||||
* This code is used e.g. on Solaris 2.x. (Note that Solaris 2.3
|
||||
* also has bsd-style ptys, but they simply do not work.)
|
||||
*/
|
||||
int ptm;
|
||||
char *pts;
|
||||
|
||||
ptm = open("/dev/ptmx", O_RDWR | O_NOCTTY);
|
||||
if (ptm < 0) {
|
||||
error("/dev/ptmx: %.100s", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
if (grantpt(ptm) < 0) {
|
||||
error("grantpt: %.100s", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
if (unlockpt(ptm) < 0) {
|
||||
error("unlockpt: %.100s", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
pts = ptsname(ptm);
|
||||
if (pts == NULL)
|
||||
error("Slave pty side name could not be obtained.");
|
||||
strlcpy(namebuf, pts, namebuflen);
|
||||
*ptyfd = ptm;
|
||||
|
||||
/* Open the slave side. */
|
||||
*ttyfd = open(namebuf, O_RDWR | O_NOCTTY);
|
||||
if (*ttyfd < 0) {
|
||||
error("%.100s: %.100s", namebuf, strerror(errno));
|
||||
close(*ptyfd);
|
||||
return 0;
|
||||
}
|
||||
/* Push the appropriate streams modules, as described in Solaris pts(7). */
|
||||
if (ioctl(*ttyfd, I_PUSH, "ptem") < 0)
|
||||
error("ioctl I_PUSH ptem: %.100s", strerror(errno));
|
||||
if (ioctl(*ttyfd, I_PUSH, "ldterm") < 0)
|
||||
error("ioctl I_PUSH ldterm: %.100s", strerror(errno));
|
||||
if (ioctl(*ttyfd, I_PUSH, "ttcompat") < 0)
|
||||
error("ioctl I_PUSH ttcompat: %.100s", strerror(errno));
|
||||
return 1;
|
||||
#else /* HAVE_DEV_PTMX */
|
||||
#ifdef HAVE_DEV_PTS_AND_PTC
|
||||
/* AIX-style pty code. */
|
||||
const char *name;
|
||||
|
||||
*ptyfd = open("/dev/ptc", O_RDWR | O_NOCTTY);
|
||||
if (*ptyfd < 0) {
|
||||
error("Could not open /dev/ptc: %.100s", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
name = ttyname(*ptyfd);
|
||||
if (!name)
|
||||
fatal("Open of /dev/ptc returns device for which ttyname fails.");
|
||||
strlcpy(namebuf, name, namebuflen);
|
||||
*ttyfd = open(name, O_RDWR | O_NOCTTY);
|
||||
if (*ttyfd < 0) {
|
||||
error("Could not open pty slave side %.100s: %.100s",
|
||||
name, strerror(errno));
|
||||
close(*ptyfd);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
#else /* HAVE_DEV_PTS_AND_PTC */
|
||||
/* BSD-style pty code. */
|
||||
char buf[64];
|
||||
int i;
|
||||
const char *ptymajors = "pqrstuvwxyzabcdefghijklmnoABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
const char *ptyminors = "0123456789abcdef";
|
||||
int num_minors = strlen(ptyminors);
|
||||
int num_ptys = strlen(ptymajors) * num_minors;
|
||||
|
||||
for (i = 0; i < num_ptys; i++) {
|
||||
snprintf(buf, sizeof buf, "/dev/pty%c%c", ptymajors[i / num_minors],
|
||||
ptyminors[i % num_minors]);
|
||||
*ptyfd = open(buf, O_RDWR | O_NOCTTY);
|
||||
if (*ptyfd < 0)
|
||||
continue;
|
||||
snprintf(namebuf, namebuflen, "/dev/tty%c%c",
|
||||
ptymajors[i / num_minors], ptyminors[i % num_minors]);
|
||||
|
||||
/* Open the slave side. */
|
||||
*ttyfd = open(namebuf, O_RDWR | O_NOCTTY);
|
||||
if (*ttyfd < 0) {
|
||||
error("%.100s: %.100s", namebuf, strerror(errno));
|
||||
close(*ptyfd);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
#endif /* HAVE_DEV_PTS_AND_PTC */
|
||||
#endif /* HAVE_DEV_PTMX */
|
||||
#endif /* HAVE__GETPTY */
|
||||
#endif /* HAVE_OPENPTY */
|
||||
}
|
||||
|
||||
/* Releases the tty. Its ownership is returned to root, and permissions to 0666. */
|
||||
|
||||
void
|
||||
pty_release(const char *ttyname)
|
||||
{
|
||||
if (chown(ttyname, (uid_t) 0, (gid_t) 0) < 0)
|
||||
error("chown %.100s 0 0 failed: %.100s", ttyname, strerror(errno));
|
||||
if (chmod(ttyname, (mode_t) 0666) < 0)
|
||||
error("chmod %.100s 0666 failed: %.100s", ttyname, strerror(errno));
|
||||
}
|
||||
|
||||
/* Makes the tty the processes controlling tty and sets it to sane modes. */
|
||||
|
||||
void
|
||||
pty_make_controlling_tty(int *ttyfd, const char *ttyname)
|
||||
{
|
||||
int fd;
|
||||
|
||||
/* First disconnect from the old controlling tty. */
|
||||
#ifdef TIOCNOTTY
|
||||
fd = open("/dev/tty", O_RDWR | O_NOCTTY);
|
||||
if (fd >= 0) {
|
||||
(void) ioctl(fd, TIOCNOTTY, NULL);
|
||||
close(fd);
|
||||
}
|
||||
#endif /* TIOCNOTTY */
|
||||
if (setsid() < 0)
|
||||
error("setsid: %.100s", strerror(errno));
|
||||
|
||||
/*
|
||||
* Verify that we are successfully disconnected from the controlling
|
||||
* tty.
|
||||
*/
|
||||
fd = open("/dev/tty", O_RDWR | O_NOCTTY);
|
||||
if (fd >= 0) {
|
||||
error("Failed to disconnect from controlling tty.");
|
||||
close(fd);
|
||||
}
|
||||
/* Make it our controlling tty. */
|
||||
#ifdef TIOCSCTTY
|
||||
debug("Setting controlling tty using TIOCSCTTY.");
|
||||
/*
|
||||
* We ignore errors from this, because HPSUX defines TIOCSCTTY, but
|
||||
* returns EINVAL with these arguments, and there is absolutely no
|
||||
* documentation.
|
||||
*/
|
||||
ioctl(*ttyfd, TIOCSCTTY, NULL);
|
||||
#endif /* TIOCSCTTY */
|
||||
fd = open(ttyname, O_RDWR);
|
||||
if (fd < 0)
|
||||
error("%.100s: %.100s", ttyname, strerror(errno));
|
||||
else
|
||||
close(fd);
|
||||
|
||||
/* Verify that we now have a controlling tty. */
|
||||
fd = open("/dev/tty", O_WRONLY);
|
||||
if (fd < 0)
|
||||
error("open /dev/tty failed - could not set controlling tty: %.100s",
|
||||
strerror(errno));
|
||||
else {
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
/* Changes the window size associated with the pty. */
|
||||
|
||||
void
|
||||
pty_change_window_size(int ptyfd, int row, int col,
|
||||
int xpixel, int ypixel)
|
||||
{
|
||||
struct winsize w;
|
||||
w.ws_row = row;
|
||||
w.ws_col = col;
|
||||
w.ws_xpixel = xpixel;
|
||||
w.ws_ypixel = ypixel;
|
||||
(void) ioctl(ptyfd, TIOCSWINSZ, &w);
|
||||
}
|
||||
|
||||
void
|
||||
pty_setowner(struct passwd *pw, const char *ttyname)
|
||||
{
|
||||
struct group *grp;
|
||||
gid_t gid;
|
||||
mode_t mode;
|
||||
|
||||
/* Determine the group to make the owner of the tty. */
|
||||
grp = getgrnam("tty");
|
||||
if (grp) {
|
||||
gid = grp->gr_gid;
|
||||
mode = S_IRUSR | S_IWUSR | S_IWGRP;
|
||||
} else {
|
||||
gid = pw->pw_gid;
|
||||
mode = S_IRUSR | S_IWUSR | S_IWGRP | S_IWOTH;
|
||||
}
|
||||
|
||||
/* Change ownership of the tty. */
|
||||
if (chown(ttyname, pw->pw_uid, gid) < 0)
|
||||
fatal("chown(%.100s, %d, %d) failed: %.100s",
|
||||
ttyname, pw->pw_uid, gid, strerror(errno));
|
||||
if (chmod(ttyname, mode) < 0)
|
||||
fatal("chmod(%.100s, 0%o) failed: %.100s",
|
||||
ttyname, mode, strerror(errno));
|
||||
}
|
47
pty.h
47
pty.h
@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
* All rights reserved
|
||||
* Functions for allocating a pseudo-terminal and making it the controlling
|
||||
* tty.
|
||||
*
|
||||
* As far as I am concerned, the code I have written for this software
|
||||
* can be used freely for any purpose. Any derived versions of this
|
||||
* software must be clearly marked as such, and if the derived work is
|
||||
* incompatible with the protocol description in the RFC file, it must be
|
||||
* called by a name other than "ssh" or "Secure Shell".
|
||||
*/
|
||||
|
||||
/* RCSID("$OpenBSD: pty.h,v 1.8 2000/09/07 20:27:52 deraadt Exp $"); */
|
||||
|
||||
#ifndef PTY_H
|
||||
#define PTY_H
|
||||
|
||||
/*
|
||||
* Allocates and opens a pty. Returns 0 if no pty could be allocated, or
|
||||
* nonzero if a pty was successfully allocated. On success, open file
|
||||
* descriptors for the pty and tty sides and the name of the tty side are
|
||||
* returned (the buffer must be able to hold at least 64 characters).
|
||||
*/
|
||||
int pty_allocate(int *ptyfd, int *ttyfd, char *ttyname, int ttynamelen);
|
||||
|
||||
/*
|
||||
* Releases the tty. Its ownership is returned to root, and permissions to
|
||||
* 0666.
|
||||
*/
|
||||
void pty_release(const char *ttyname);
|
||||
|
||||
/*
|
||||
* Makes the tty the processes controlling tty and sets it to sane modes.
|
||||
* This may need to reopen the tty to get rid of possible eavesdroppers.
|
||||
*/
|
||||
void pty_make_controlling_tty(int *ttyfd, const char *ttyname);
|
||||
|
||||
/* Changes the window size associated with the pty. */
|
||||
void
|
||||
pty_change_window_size(int ptyfd, int row, int col,
|
||||
int xpixel, int ypixel);
|
||||
|
||||
void pty_setowner(struct passwd *pw, const char *ttyname);
|
||||
|
||||
#endif /* PTY_H */
|
BIN
regress/copy.1
BIN
regress/copy.1
Binary file not shown.
BIN
regress/copy.2
BIN
regress/copy.2
Binary file not shown.
@ -1,20 +0,0 @@
|
||||
# $OpenBSD: Makefile,v 1.2 2001/06/29 07:02:09 markus Exp $
|
||||
|
||||
.PATH: ${.CURDIR}/..
|
||||
|
||||
CARDLET= Ssh.bin
|
||||
DATADIR= /usr/libdata/ssh
|
||||
|
||||
all: ${CARDLET}
|
||||
|
||||
clean:
|
||||
rm -f ${CARDLET}
|
||||
|
||||
install: ${CARDLET}
|
||||
install -c -m ${LIBMODE} -o ${LIBOWN} -g ${LIBGRP} \
|
||||
${CARDLET} ${DESTDIR}${DATADIR}
|
||||
|
||||
Ssh.bin: ${.CURDIR}/Ssh.bin.uu
|
||||
uudecode ${.CURDIR}/$@.uu
|
||||
|
||||
.include <bsd.prog.mk>
|
98
scp-common.c
98
scp-common.c
@ -1,98 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1999 Theo de Raadt. All rights reserved.
|
||||
* Copyright (c) 1999 Aaron Campbell. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Parts from:
|
||||
*
|
||||
* Copyright (c) 1983, 1990, 1992, 1993, 1995
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: scp-common.c,v 1.1 2001/04/16 02:31:43 mouring Exp $");
|
||||
|
||||
char *
|
||||
cleanhostname(host)
|
||||
char *host;
|
||||
{
|
||||
if (*host == '[' && host[strlen(host) - 1] == ']') {
|
||||
host[strlen(host) - 1] = '\0';
|
||||
return (host + 1);
|
||||
} else
|
||||
return host;
|
||||
}
|
||||
|
||||
char *
|
||||
colon(cp)
|
||||
char *cp;
|
||||
{
|
||||
int flag = 0;
|
||||
|
||||
if (*cp == ':') /* Leading colon is part of file name. */
|
||||
return (0);
|
||||
if (*cp == '[')
|
||||
flag = 1;
|
||||
|
||||
for (; *cp; ++cp) {
|
||||
if (*cp == '@' && *(cp+1) == '[')
|
||||
flag = 1;
|
||||
if (*cp == ']' && *(cp+1) == ':' && flag)
|
||||
return (cp+1);
|
||||
if (*cp == ':' && !flag)
|
||||
return (cp);
|
||||
if (*cp == '/')
|
||||
return (0);
|
||||
}
|
||||
return (0);
|
||||
}
|
64
scp-common.h
64
scp-common.h
@ -1,64 +0,0 @@
|
||||
/* $OpenBSD: scp-common.h,v 1.1 2001/04/16 02:31:43 mouring Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1999 Theo de Raadt. All rights reserved.
|
||||
* Copyright (c) 1999 Aaron Campbell. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Parts from:
|
||||
*
|
||||
* Copyright (c) 1983, 1990, 1992, 1993, 1995
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
char *cleanhostname(char *host);
|
||||
char *colon(char *cp);
|
15
scp/Makefile
15
scp/Makefile
@ -1,15 +0,0 @@
|
||||
# $OpenBSD: Makefile,v 1.13 2001/05/03 23:09:55 mouring Exp $
|
||||
|
||||
.PATH: ${.CURDIR}/..
|
||||
|
||||
PROG= scp
|
||||
BINOWN= root
|
||||
|
||||
BINMODE?=555
|
||||
|
||||
BINDIR= /usr/bin
|
||||
MAN= scp.1
|
||||
|
||||
SRCS= scp.c misc.c
|
||||
|
||||
.include <bsd.prog.mk>
|
@ -1,18 +0,0 @@
|
||||
# $OpenBSD: Makefile,v 1.5 2001/03/03 23:59:36 markus Exp $
|
||||
|
||||
.PATH: ${.CURDIR}/..
|
||||
|
||||
PROG= sftp-server
|
||||
BINOWN= root
|
||||
|
||||
BINMODE?=555
|
||||
|
||||
BINDIR= /usr/libexec
|
||||
MAN= sftp-server.8
|
||||
|
||||
SRCS= sftp-server.c sftp-common.c
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
LDADD+= -lcrypto
|
||||
DPADD+= ${LIBCRYPTO}
|
@ -1,19 +0,0 @@
|
||||
# $OpenBSD: Makefile,v 1.5 2001/05/03 23:09:57 mouring Exp $
|
||||
|
||||
.PATH: ${.CURDIR}/..
|
||||
|
||||
PROG= sftp
|
||||
BINOWN= root
|
||||
|
||||
BINMODE?=555
|
||||
|
||||
BINDIR= /usr/bin
|
||||
MAN= sftp.1
|
||||
|
||||
SRCS= sftp.c sftp-client.c sftp-int.c sftp-common.c sftp-glob.c misc.c
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
LDADD+= -lcrypto
|
||||
DPADD+= ${LIBCRYPTO}
|
||||
|
@ -1,18 +0,0 @@
|
||||
# $OpenBSD: Makefile,v 1.20 2001/03/04 00:51:25 markus Exp $
|
||||
|
||||
.PATH: ${.CURDIR}/..
|
||||
|
||||
PROG= ssh-add
|
||||
BINOWN= root
|
||||
|
||||
BINMODE?=555
|
||||
|
||||
BINDIR= /usr/bin
|
||||
MAN= ssh-add.1
|
||||
|
||||
SRCS= ssh-add.c
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
LDADD+= -lcrypto
|
||||
DPADD+= ${LIBCRYPTO}
|
@ -1,18 +0,0 @@
|
||||
# $OpenBSD: Makefile,v 1.21 2001/06/27 19:29:16 markus Exp $
|
||||
|
||||
.PATH: ${.CURDIR}/..
|
||||
|
||||
PROG= ssh-agent
|
||||
BINOWN= root
|
||||
|
||||
BINMODE?=555
|
||||
|
||||
BINDIR= /usr/bin
|
||||
MAN= ssh-agent.1
|
||||
|
||||
SRCS= ssh-agent.c
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
LDADD+= -lcrypto
|
||||
DPADD+= ${LIBCRYPTO}
|
@ -1,18 +0,0 @@
|
||||
# $OpenBSD: Makefile,v 1.21 2001/06/27 19:29:16 markus Exp $
|
||||
|
||||
.PATH: ${.CURDIR}/..
|
||||
|
||||
PROG= ssh-keygen
|
||||
BINOWN= root
|
||||
|
||||
BINMODE?=555
|
||||
|
||||
BINDIR= /usr/bin
|
||||
MAN= ssh-keygen.1
|
||||
|
||||
SRCS= ssh-keygen.c
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
LDADD+= -lcrypto
|
||||
DPADD+= ${LIBCRYPTO}
|
@ -1,18 +0,0 @@
|
||||
# $OpenBSD: Makefile,v 1.4 2001/08/05 23:18:20 markus Exp $
|
||||
|
||||
.PATH: ${.CURDIR}/..
|
||||
|
||||
PROG= ssh-keyscan
|
||||
BINOWN= root
|
||||
|
||||
BINMODE?=555
|
||||
|
||||
BINDIR= /usr/bin
|
||||
MAN= ssh-keyscan.1
|
||||
|
||||
SRCS= ssh-keyscan.c
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
LDADD+= -lcrypto -lz
|
||||
DPADD+= ${LIBCRYPTO} ${LIBZ}
|
@ -1,18 +0,0 @@
|
||||
# $OpenBSD: Makefile,v 1.3 2002/05/31 10:30:33 markus Exp $
|
||||
|
||||
.PATH: ${.CURDIR}/..
|
||||
|
||||
PROG= ssh-keysign
|
||||
BINOWN= root
|
||||
|
||||
BINMODE?=4555
|
||||
|
||||
BINDIR= /usr/libexec
|
||||
MAN= ssh-keysign.8
|
||||
|
||||
SRCS= ssh-keysign.c
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
LDADD+= -lcrypto -lz
|
||||
DPADD+= ${LIBCRYPTO} ${LIBZ}
|
40
ssh/Makefile
40
ssh/Makefile
@ -1,40 +0,0 @@
|
||||
# $OpenBSD: Makefile,v 1.42 2002/06/20 19:56:07 stevesk Exp $
|
||||
|
||||
.PATH: ${.CURDIR}/..
|
||||
|
||||
PROG= ssh
|
||||
BINOWN= root
|
||||
|
||||
#BINMODE?=4555
|
||||
|
||||
BINDIR= /usr/bin
|
||||
MAN= ssh.1 ssh_config.5
|
||||
LINKS= ${BINDIR}/ssh ${BINDIR}/slogin
|
||||
MLINKS= ssh.1 slogin.1
|
||||
|
||||
SRCS= ssh.c readconf.c clientloop.c sshtty.c \
|
||||
sshconnect.c sshconnect1.c sshconnect2.c
|
||||
|
||||
.include <bsd.own.mk> # for AFS
|
||||
|
||||
.if (${KERBEROS5:L} == "yes")
|
||||
CFLAGS+= -DKRB5 -I${DESTDIR}/usr/include/kerberosV
|
||||
LDADD+= -lkrb5 -lasn1 -lcom_err
|
||||
DPADD+= ${LIBKRB5} ${LIBASN1} ${LIBCOM_ERR}
|
||||
.endif # KERBEROS5
|
||||
|
||||
.if (${KERBEROS:L} == "yes")
|
||||
CFLAGS+= -DKRB4 -I${DESTDIR}/usr/include/kerberosIV
|
||||
LDADD+= -lkrb
|
||||
DPADD+= ${LIBKRB}
|
||||
.if (${AFS:L} == "yes")
|
||||
CFLAGS+= -DAFS
|
||||
LDADD+= -lkafs
|
||||
DPADD+= ${LIBKAFS}
|
||||
.endif # AFS
|
||||
.endif # KERBEROS
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
LDADD+= -lcrypto -lz -ldes
|
||||
DPADD+= ${LIBCRYPTO} ${LIBZ} ${LIBDES}
|
@ -1,56 +0,0 @@
|
||||
# $OpenBSD: Makefile,v 1.51 2002/06/20 19:56:07 stevesk Exp $
|
||||
|
||||
.PATH: ${.CURDIR}/..
|
||||
|
||||
PROG= sshd
|
||||
BINOWN= root
|
||||
BINMODE=555
|
||||
BINDIR= /usr/sbin
|
||||
MAN= sshd.8 sshd_config.5
|
||||
CFLAGS+=-DHAVE_LOGIN_CAP -DBSD_AUTH
|
||||
|
||||
SRCS= sshd.c auth-rhosts.c auth-passwd.c auth-rsa.c auth-rh-rsa.c \
|
||||
sshpty.c sshlogin.c servconf.c serverloop.c uidswap.c \
|
||||
auth.c auth1.c auth2.c auth-options.c session.c \
|
||||
auth-chall.c auth2-chall.c groupaccess.c \
|
||||
auth-skey.c auth-bsdauth.c monitor_mm.c monitor.c \
|
||||
auth2-none.c auth2-passwd.c auth2-pubkey.c \
|
||||
auth2-hostbased.c auth2-kbdint.c
|
||||
|
||||
.include <bsd.own.mk> # for KERBEROS and AFS
|
||||
|
||||
.if (${KERBEROS5:L} == "yes")
|
||||
CFLAGS+=-DKRB5 -I${DESTDIR}/usr/include/kerberosV
|
||||
SRCS+= auth-krb5.c
|
||||
LDADD+= -lkrb5 -lkafs -lasn1 -lcom_err
|
||||
DPADD+= ${LIBKRB5} ${LIBKAFS} ${LIBASN1} ${LIBCOM_ERR}
|
||||
.endif # KERBEROS5
|
||||
|
||||
.if (${KERBEROS:L} == "yes")
|
||||
.if (${AFS:L} == "yes")
|
||||
CFLAGS+= -DAFS
|
||||
LDADD+= -lkafs
|
||||
DPADD+= ${LIBKAFS}
|
||||
.endif # AFS
|
||||
CFLAGS+= -DKRB4 -I${DESTDIR}/usr/include/kerberosIV
|
||||
SRCS+= auth-krb4.c
|
||||
LDADD+= -lkrb
|
||||
DPADD+= ${LIBKRB}
|
||||
.endif # KERBEROS
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
LDADD+= -lcrypto -lutil -lz -ldes
|
||||
DPADD+= ${LIBCRYPTO} ${LIBUTIL} ${LIBZ} ${LIBDES}
|
||||
|
||||
.if (${TCP_WRAPPERS:L} == "yes")
|
||||
CFLAGS+= -DLIBWRAP
|
||||
LDADD+= -lwrap
|
||||
DPADD+= ${LIBWRAP}
|
||||
.endif
|
||||
|
||||
#.if (${SKEY:L} == "yes")
|
||||
#CFLAGS+= -DSKEY
|
||||
#LDADD+= -lskey
|
||||
#DPADD+= ${SKEY}
|
||||
#.endif
|
96
util.c
96
util.c
@ -1,96 +0,0 @@
|
||||
/* $OpenBSD: util.c,v 1.6 2000/10/27 07:32:19 markus Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 Markus Friedl. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
RCSID("$OpenBSD: util.c,v 1.6 2000/10/27 07:32:19 markus Exp $");
|
||||
|
||||
#include "ssh.h"
|
||||
|
||||
char *
|
||||
chop(char *s)
|
||||
{
|
||||
char *t = s;
|
||||
while (*t) {
|
||||
if(*t == '\n' || *t == '\r') {
|
||||
*t = '\0';
|
||||
return s;
|
||||
}
|
||||
t++;
|
||||
}
|
||||
return s;
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
set_nonblock(int fd)
|
||||
{
|
||||
int val;
|
||||
val = fcntl(fd, F_GETFL, 0);
|
||||
if (val < 0) {
|
||||
error("fcntl(%d, F_GETFL, 0): %s", fd, strerror(errno));
|
||||
return;
|
||||
}
|
||||
if (val & O_NONBLOCK) {
|
||||
debug("fd %d IS O_NONBLOCK", fd);
|
||||
return;
|
||||
}
|
||||
debug("fd %d setting O_NONBLOCK", fd);
|
||||
val |= O_NONBLOCK;
|
||||
if (fcntl(fd, F_SETFL, val) == -1)
|
||||
if (errno != ENODEV)
|
||||
error("fcntl(%d, F_SETFL, O_NONBLOCK): %s",
|
||||
fd, strerror(errno));
|
||||
}
|
||||
|
||||
/* Characters considered whitespace in strsep calls. */
|
||||
#define WHITESPACE " \t\r\n"
|
||||
|
||||
char *
|
||||
strdelim(char **s)
|
||||
{
|
||||
char *old;
|
||||
int wspace = 0;
|
||||
|
||||
if (*s == NULL)
|
||||
return NULL;
|
||||
|
||||
old = *s;
|
||||
|
||||
*s = strpbrk(*s, WHITESPACE "=");
|
||||
if (*s == NULL)
|
||||
return (old);
|
||||
|
||||
/* Allow only one '=' to be skipped */
|
||||
if (*s[0] == '=')
|
||||
wspace = 1;
|
||||
*s[0] = '\0';
|
||||
|
||||
*s += strspn(*s + 1, WHITESPACE) + 1;
|
||||
if (*s[0] == '=' && !wspace)
|
||||
*s += strspn(*s + 1, WHITESPACE) + 1;
|
||||
|
||||
return (old);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user