diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 18:28:21 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 18:28:21 -0800 |
commit | 4992dc5127843624d3deb2d54af917a7ec50fb45 (patch) | |
tree | 0cbcf7d3a36648aec263dcd0744dc5231e7a6844 /svr-agentfwd.c | |
parent | 1abbfe5d373a44e7e0525fb7971ef0e00955f2e4 (diff) | |
download | dropbear-4992dc5127843624d3deb2d54af917a7ec50fb45.tar.gz |
auto import from //depot/cupcake/@135843
Diffstat (limited to 'svr-agentfwd.c')
-rw-r--r-- | svr-agentfwd.c | 266 |
1 files changed, 0 insertions, 266 deletions
diff --git a/svr-agentfwd.c b/svr-agentfwd.c deleted file mode 100644 index 5127158..0000000 --- a/svr-agentfwd.c +++ /dev/null @@ -1,266 +0,0 @@ -/* - * Dropbear - a SSH2 server - * - * Copyright (c) 2002,2003 Matt Johnston - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. */ - -/* This file (agentfwd.c) handles authentication agent forwarding, for OpenSSH - * style agents. */ - -#include "includes.h" - -#ifndef DISABLE_AGENTFWD - -#include "agentfwd.h" -#include "session.h" -#include "ssh.h" -#include "dbutil.h" -#include "chansession.h" -#include "channel.h" -#include "packet.h" -#include "buffer.h" -#include "random.h" -#include "listener.h" - -#define AGENTDIRPREFIX "/tmp/dropbear-" - -static int send_msg_channel_open_agent(int fd); -static int bindagent(int fd, struct ChanSess * chansess); -static void agentaccept(struct Listener * listener, int sock); - -/* Handles client requests to start agent forwarding, sets up listening socket. - * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ -int agentreq(struct ChanSess * chansess) { - - int fd; - - if (chansess->agentlistener != NULL) { - return DROPBEAR_FAILURE; - } - - /* create listening socket */ - fd = socket(PF_UNIX, SOCK_STREAM, 0); - if (fd < 0) { - goto fail; - } - - /* create the unix socket dir and file */ - if (bindagent(fd, chansess) == DROPBEAR_FAILURE) { - goto fail; - } - - /* listen */ - if (listen(fd, 20) < 0) { - goto fail; - } - - /* set non-blocking */ - setnonblocking(fd); - - /* pass if off to listener */ - chansess->agentlistener = new_listener( &fd, 1, 0, chansess, - agentaccept, NULL); - - if (chansess->agentlistener == NULL) { - goto fail; - } - - return DROPBEAR_SUCCESS; - -fail: - /* cleanup */ - agentcleanup(chansess); - - return DROPBEAR_FAILURE; -} - -/* accepts a connection on the forwarded socket and opens a new channel for it - * back to the client */ -/* returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ -static void agentaccept(struct Listener *UNUSED(listener), int sock) { - - int fd; - - fd = accept(sock, NULL, NULL); - if (fd < 0) { - TRACE(("accept failed")) - return; - } - - if (send_msg_channel_open_agent(fd) != DROPBEAR_SUCCESS) { - close(fd); - } - -} - -/* set up the environment variable pointing to the socket. This is called - * just before command/shell execution, after dropping priveleges */ -void agentset(struct ChanSess * chansess) { - - char *path = NULL; - int len; - - if (chansess->agentlistener == NULL) { - return; - } - - /* 2 for "/" and "\0" */ - len = strlen(chansess->agentdir) + strlen(chansess->agentfile) + 2; - - path = m_malloc(len); - snprintf(path, len, "%s/%s", chansess->agentdir, chansess->agentfile); - addnewvar("SSH_AUTH_SOCK", path); - m_free(path); -} - -/* close the socket, remove the socket-file */ -void agentcleanup(struct ChanSess * chansess) { - - char *path = NULL; - uid_t uid; - gid_t gid; - int len; - - if (chansess->agentlistener != NULL) { - remove_listener(chansess->agentlistener); - chansess->agentlistener = NULL; - } - - if (chansess->agentfile != NULL && chansess->agentdir != NULL) { - - /* Remove the dir as the user. That way they can't cause problems except - * for themselves */ - uid = getuid(); - gid = getgid(); - if ((setegid(ses.authstate.pw->pw_gid)) < 0 || - (seteuid(ses.authstate.pw->pw_uid)) < 0) { - dropbear_exit("failed to set euid"); - } - - /* 2 for "/" and "\0" */ - len = strlen(chansess->agentdir) + strlen(chansess->agentfile) + 2; - - path = m_malloc(len); - snprintf(path, len, "%s/%s", chansess->agentdir, chansess->agentfile); - unlink(path); - m_free(path); - - rmdir(chansess->agentdir); - - if ((seteuid(uid)) < 0 || - (setegid(gid)) < 0) { - dropbear_exit("failed to revert euid"); - } - - m_free(chansess->agentfile); - m_free(chansess->agentdir); - } - -} - -static const struct ChanType chan_agent = { - 0, /* sepfds */ - "auth-agent@openssh.com", - NULL, - NULL, - NULL, - NULL -}; - - -/* helper for accepting an agent request */ -static int send_msg_channel_open_agent(int fd) { - - if (send_msg_channel_open_init(fd, &chan_agent) == DROPBEAR_SUCCESS) { - encrypt_packet(); - return DROPBEAR_SUCCESS; - } else { - return DROPBEAR_FAILURE; - } -} - -/* helper for creating the agent socket-file - returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ -static int bindagent(int fd, struct ChanSess * chansess) { - - struct sockaddr_un addr; - unsigned int prefix; - char path[sizeof(addr.sun_path)], sockfile[sizeof(addr.sun_path)]; - mode_t mode; - int i; - uid_t uid; - gid_t gid; - int ret = DROPBEAR_FAILURE; - - /* drop to user privs to make the dir/file */ - uid = getuid(); - gid = getgid(); - if ((setegid(ses.authstate.pw->pw_gid)) < 0 || - (seteuid(ses.authstate.pw->pw_uid)) < 0) { - dropbear_exit("failed to set euid"); - } - - memset((void*)&addr, 0x0, sizeof(addr)); - addr.sun_family = AF_UNIX; - - mode = S_IRWXU; - - for (i = 0; i < 20; i++) { - genrandom((unsigned char*)&prefix, sizeof(prefix)); - /* we want 32 bits (8 hex digits) - "/tmp/dropbear-f19c62c0" */ - snprintf(path, sizeof(path), AGENTDIRPREFIX "%.8x", prefix); - - if (mkdir(path, mode) == 0) { - goto bindsocket; - } - if (errno != EEXIST) { - break; - } - } - /* couldn't make a dir */ - goto out; - -bindsocket: - /* Format is "/tmp/dropbear-0246dead/auth-d00f7654-23". - * The "23" is the file desc, the random data is to avoid collisions - * between subsequent user processes reusing socket fds (odds are now - * 1/(2^64) */ - genrandom((unsigned char*)&prefix, sizeof(prefix)); - snprintf(sockfile, sizeof(sockfile), "auth-%.8x-%d", prefix, fd); - - snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/%s", path, sockfile); - - if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) == 0) { - chansess->agentdir = m_strdup(path); - chansess->agentfile = m_strdup(sockfile); - ret = DROPBEAR_SUCCESS; - } - - -out: - if ((seteuid(uid)) < 0 || - (setegid(gid)) < 0) { - dropbear_exit("failed to revert euid"); - } - return ret; -} - -#endif |