aboutsummaryrefslogtreecommitdiff
path: root/svr-agentfwd.c
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-03-03 18:28:21 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-03-03 18:28:21 -0800
commit4992dc5127843624d3deb2d54af917a7ec50fb45 (patch)
tree0cbcf7d3a36648aec263dcd0744dc5231e7a6844 /svr-agentfwd.c
parent1abbfe5d373a44e7e0525fb7971ef0e00955f2e4 (diff)
downloaddropbear-4992dc5127843624d3deb2d54af917a7ec50fb45.tar.gz
auto import from //depot/cupcake/@135843
Diffstat (limited to 'svr-agentfwd.c')
-rw-r--r--svr-agentfwd.c266
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