version 1.129.2.2, 2006/11/08 00:17:14 |
version 1.130, 2006/03/19 18:51:18 |
|
|
/* $OpenBSD$ */ |
|
/* |
/* |
* Author: Tatu Ylonen <ylo@cs.hut.fi> |
* Author: Tatu Ylonen <ylo@cs.hut.fi> |
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
|
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
*/ |
|
|
#include <sys/types.h> |
#include "includes.h" |
#include <sys/time.h> |
|
#include <sys/queue.h> |
#include <sys/queue.h> |
#include <sys/resource.h> |
#include <sys/resource.h> |
#include <sys/types.h> |
#include <sys/types.h> |
#include <sys/socket.h> |
|
#include <sys/un.h> |
#include <sys/un.h> |
#include <sys/param.h> |
|
|
|
#include <openssl/evp.h> |
|
#include <openssl/md5.h> |
|
|
|
#include <errno.h> |
|
#include <fcntl.h> |
|
#include <paths.h> |
#include <paths.h> |
#include <signal.h> |
#include <signal.h> |
#include <stdlib.h> |
|
#include <stdio.h> |
|
#include <string.h> |
|
#include <time.h> |
|
#include <unistd.h> |
|
|
|
#include "xmalloc.h" |
#include <openssl/evp.h> |
|
#include <openssl/md5.h> |
|
|
#include "ssh.h" |
#include "ssh.h" |
#include "rsa.h" |
#include "rsa.h" |
#include "buffer.h" |
#include "buffer.h" |
|
#include "bufaux.h" |
|
#include "xmalloc.h" |
|
#include "getput.h" |
#include "key.h" |
#include "key.h" |
#include "authfd.h" |
#include "authfd.h" |
#include "compat.h" |
#include "compat.h" |
|
|
pid_t parent_pid = -1; |
pid_t parent_pid = -1; |
|
|
/* pathname and directory for AUTH_SOCKET */ |
/* pathname and directory for AUTH_SOCKET */ |
char socket_name[MAXPATHLEN]; |
char socket_name[1024]; |
char socket_dir[MAXPATHLEN]; |
char socket_dir[1024]; |
|
|
/* locking */ |
/* locking */ |
int locked = 0; |
int locked = 0; |
|
|
Identity *id = lookup_identity(key, 2); |
Identity *id = lookup_identity(key, 2); |
if (id != NULL && (!id->confirm || confirm_key(id) == 0)) |
if (id != NULL && (!id->confirm || confirm_key(id) == 0)) |
ok = key_sign(id->key, &signature, &slen, data, dlen); |
ok = key_sign(id->key, &signature, &slen, data, dlen); |
key_free(key); |
|
} |
} |
|
key_free(key); |
buffer_init(&msg); |
buffer_init(&msg); |
if (ok == 0) { |
if (ok == 0) { |
buffer_put_char(&msg, SSH2_AGENT_SIGN_RESPONSE); |
buffer_put_char(&msg, SSH2_AGENT_SIGN_RESPONSE); |
|
|
if (buffer_len(&e->input) < 5) |
if (buffer_len(&e->input) < 5) |
return; /* Incomplete message. */ |
return; /* Incomplete message. */ |
cp = buffer_ptr(&e->input); |
cp = buffer_ptr(&e->input); |
msg_len = get_u32(cp); |
msg_len = GET_32BIT(cp); |
if (msg_len > 256 * 1024) { |
if (msg_len > 256 * 1024) { |
close_socket(e); |
close_socket(e); |
return; |
return; |
|
|
} |
} |
old_alloc = sockets_alloc; |
old_alloc = sockets_alloc; |
new_alloc = sockets_alloc + 10; |
new_alloc = sockets_alloc + 10; |
sockets = xrealloc(sockets, new_alloc, sizeof(sockets[0])); |
if (sockets) |
|
sockets = xrealloc(sockets, new_alloc * sizeof(sockets[0])); |
|
else |
|
sockets = xmalloc(new_alloc * sizeof(sockets[0])); |
for (i = old_alloc; i < new_alloc; i++) |
for (i = old_alloc; i < new_alloc; i++) |
sockets[i].type = AUTH_UNUSED; |
sockets[i].type = AUTH_UNUSED; |
sockets_alloc = new_alloc; |
sockets_alloc = new_alloc; |
|
|
if (FD_ISSET(sockets[i].fd, readset)) { |
if (FD_ISSET(sockets[i].fd, readset)) { |
slen = sizeof(sunaddr); |
slen = sizeof(sunaddr); |
sock = accept(sockets[i].fd, |
sock = accept(sockets[i].fd, |
(struct sockaddr *)&sunaddr, &slen); |
(struct sockaddr *) &sunaddr, &slen); |
if (sock < 0) { |
if (sock < 0) { |
error("accept from AUTH_SOCKET: %s", |
error("accept from AUTH_SOCKET: %s", |
strerror(errno)); |
strerror(errno)); |
|
|
_exit(i); |
_exit(i); |
} |
} |
|
|
/*ARGSUSED*/ |
|
static void |
static void |
cleanup_handler(int sig) |
cleanup_handler(int sig) |
{ |
{ |
|
|
_exit(2); |
_exit(2); |
} |
} |
|
|
/*ARGSUSED*/ |
|
static void |
static void |
check_parent_exists(int sig) |
check_parent_exists(int sig) |
{ |
{ |
|
|
main(int ac, char **av) |
main(int ac, char **av) |
{ |
{ |
int c_flag = 0, d_flag = 0, k_flag = 0, s_flag = 0; |
int c_flag = 0, d_flag = 0, k_flag = 0, s_flag = 0; |
int sock, fd, ch; |
int sock, fd, ch; |
u_int nalloc; |
u_int nalloc; |
char *shell, *format, *pidstr, *agentsocket = NULL; |
char *shell, *format, *pidstr, *agentsocket = NULL; |
fd_set *readsetp = NULL, *writesetp = NULL; |
fd_set *readsetp = NULL, *writesetp = NULL; |
|
|
|
|
if (ac == 0 && !c_flag && !s_flag) { |
if (ac == 0 && !c_flag && !s_flag) { |
shell = getenv("SHELL"); |
shell = getenv("SHELL"); |
if (shell != NULL && |
if (shell != NULL && strncmp(shell + strlen(shell) - 3, "csh", 3) == 0) |
strncmp(shell + strlen(shell) - 3, "csh", 3) == 0) |
|
c_flag = 1; |
c_flag = 1; |
} |
} |
if (k_flag) { |
if (k_flag) { |
const char *errstr = NULL; |
|
|
|
pidstr = getenv(SSH_AGENTPID_ENV_NAME); |
pidstr = getenv(SSH_AGENTPID_ENV_NAME); |
if (pidstr == NULL) { |
if (pidstr == NULL) { |
fprintf(stderr, "%s not set, cannot kill agent\n", |
fprintf(stderr, "%s not set, cannot kill agent\n", |
SSH_AGENTPID_ENV_NAME); |
SSH_AGENTPID_ENV_NAME); |
exit(1); |
exit(1); |
} |
} |
pid = (int)strtonum(pidstr, 2, INT_MAX, &errstr); |
pid = atoi(pidstr); |
if (errstr) { |
if (pid < 1) { |
fprintf(stderr, |
fprintf(stderr, "%s=\"%s\", which is not a good PID\n", |
"%s=\"%s\", which is not a good PID: %s\n", |
SSH_AGENTPID_ENV_NAME, pidstr); |
SSH_AGENTPID_ENV_NAME, pidstr, errstr); |
|
exit(1); |
exit(1); |
} |
} |
if (kill(pid, SIGTERM) == -1) { |
if (kill(pid, SIGTERM) == -1) { |
|
|
memset(&sunaddr, 0, sizeof(sunaddr)); |
memset(&sunaddr, 0, sizeof(sunaddr)); |
sunaddr.sun_family = AF_UNIX; |
sunaddr.sun_family = AF_UNIX; |
strlcpy(sunaddr.sun_path, socket_name, sizeof(sunaddr.sun_path)); |
strlcpy(sunaddr.sun_path, socket_name, sizeof(sunaddr.sun_path)); |
if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) < 0) { |
if (bind(sock, (struct sockaddr *) & sunaddr, sizeof(sunaddr)) < 0) { |
perror("bind"); |
perror("bind"); |
*socket_name = '\0'; /* Don't unlink any existing file */ |
*socket_name = '\0'; /* Don't unlink any existing file */ |
cleanup_exit(1); |
cleanup_exit(1); |