Exemple #1
0
/* abort routine originally from Cftp by Dieter Baron
 */
int ftp_abort(Socket* fp)
{
	char buf[4096];

#ifdef HAVE_LIBSSH
	if(ftp->session)
		/* FIXME: what? */
		return 0;
#endif

	if(!ftp_connected())
		return -1;

	ftp_set_close_handler();

	if (sock_check_pending(fp, false) == 1) {
		ftp_trace("There is data on the control channel, won't send ABOR\n");
		/* read remaining bytes from connection */
		while(fp && sock_read(fp, buf, sizeof(buf)) > 0)
			/* LOOP */ ;
		return 0;
	}

	ftp->ti.interrupted = true;
	ftp_err(_("Waiting for remote to finish abort...\n"));

	ftp_trace("--> telnet interrupt\n");
	if(sock_telnet_interrupt(ftp->ctrl) != 0)
		ftp_err("telnet interrupt: %s\n", strerror(errno));

	/* ftp_cmd("ABOR") won't work here,
	 * we must flush data between the ABOR command and ftp_read_reply()
	 */
	sock_krb_printf(ftp->ctrl, "ABOR");
	sock_printf(ftp->ctrl, "\r\n");
	sock_flush(ftp->ctrl);
	if(ftp_get_verbosity() == vbDebug)
		ftp_err("--> [%s] ABOR\n", ftp->url->hostname);
	else
		ftp_trace("--> [%s] ABOR\n", ftp->url->hostname);

    /* read remaining bytes from connection */
	while(fp && sock_read(fp, buf, sizeof(buf)) > 0)
		/* LOOP */ ;

	/* we expect a 426 or 226 reply here... */
	ftp_read_reply();
	if(ftp->fullcode != 426 && ftp->fullcode != 226)
		ftp_trace("Huh!? Expected a 426 or 226 reply\n");

	/* ... and a 226 or 225 reply here, respectively */
	/* FIXME: should skip this reply if prev. reply wasn't 426 or 226 ? */
	ftp_read_reply();
	if(ftp->fullcode != 226 && ftp->fullcode != 225)
		ftp_trace("Huh!? Expected a 226 or 225 reply\n");

	return -1;
}
Exemple #2
0
static void ftp_print_reply(void)
{
    verbose_t v = ftp_get_verbosity();

    ftp_trace("<-- [%s] %s\n",
              ftp->url ? ftp->url->hostname : host_getname(ftp->host),
              ftp_getreply(true));

    if(v >= vbCommand || (ftp->code >= ctTransient && v == vbError)) {
        if(v == vbDebug)
            fprintf(stderr, "<-- [%s] %s\n",
                    ftp->url ? ftp->url->hostname : host_getname(ftp->host),
                    ftp_getreply(true));
        else
            fprintf(stderr, "%s\n", ftp_getreply(false));
    }
}
Exemple #3
0
static void ftp_print_cmd(const char *cmd, va_list ap)
{
    if(ftp_get_verbosity() == vbDebug) {
        ftp_err("--> [%s] ", ftp->url->hostname);
        if(strncmp(cmd, "PASS", 4) == 0)
            ftp_err("PASS ********");
        else {
            vfprintf(stderr, cmd, ap);
            ftp_vtrace(cmd, ap);
        }
        ftp_err("\n");
    } else {
        ftp_trace("--> [%s] ", ftp->url->hostname);
        if(strncmp(cmd, "PASS", 4) == 0)
            ftp_trace("PASS ********");
        else
            ftp_vtrace(cmd, ap);
        ftp_trace("\n");
    }
}
Exemple #4
0
void cmd_system(int argc, char **argv)
{
	if(argv) {
		OPT_HELP_NEW(_("Show type of remote system."), "system [options]\n", NULL);

		maxargs(optind - 1);
	}
	need_connected();
	need_loggedin();

#ifdef HAVE_LIBSSH
	if(ftp->session) {
		fprintf(stderr, "remote system: SSH (version %d)\n", ftp->ssh_version);
		return;
	}
#endif

	if(ftp_get_verbosity() != vbDebug)
		fprintf(stderr, _("remote system: "));
	ftp_set_tmp_verbosity(vbCommand);
	ftp_cmd("SYST");
}
Exemple #5
0
void cmd_system(int argc, char **argv)
{
	if(argv) {
		OPT_HELP("Show type of remote system.  Usage:\n"
				 "  system [options]\n"
				 "Options:\n"
				 "  -h, --help    show this help\n");

		maxargs(optind - 1);
	}
	need_connected();
	need_loggedin();

	if(ftp->ssh_pid) {
		fprintf(stderr, "remote system: SSH (version %d)\n", ftp->ssh_version);
		return;
	}

	if(ftp_get_verbosity() != vbDebug)
		fprintf(stderr, _("remote system: "));
	ftp_set_tmp_verbosity(vbCommand);
	ftp_cmd("SYST");
}
Exemple #6
0
static char *remote_completion_function(const char *text, int state)
{
    static int len;            /* length of unquoted */
    static char *dir = NULL;   /* any initial directory in text */
    static char *unquoted = NULL; /* the unquoted filename (or beginning of it) */
    static listitem *lip = NULL;
    static rdirectory *rdir = NULL; /* the cached remote directory */
    static char merge_fmt[] = "%s/%s";

    if (!ftp_loggedin())
        return 0;

    /* this is not really true, this is for local filename completion,
     * but it works here too (sort of), and it looks nicer, since
     * the whole path is not printed by readline, ie
     * only foo is printed and not /bar/fu/foo (if cwd == /bar/fu)
     * readline appends a class character (ie /,@,*) in _local_ filenames
     */
    rl_filename_completion_desired = 1;
#ifndef HAVE_LIBEDIT
    rl_filename_quoting_desired = 1;
#endif

    if (!state) {
        dir = base_dir_xptr(text);
        if (dir) {
            stripslash(dir);
            char* e = strchr(dir, 0);
            if (e[-1]=='\"')
                e[-1] = '\0';
            unquote(dir);
            if (strcmp(dir, "/") == 0)
                strlcpy(merge_fmt, "%s%s", sizeof(merge_fmt));
            else
                strlcpy(merge_fmt, "%s/%s", sizeof(merge_fmt));
        }
#ifndef HAVE_LIBEDIT
        if(gvWaitingDots) {
            rl_insert_text("..."); /* show dots while waiting, like ncftp */
            rl_redisplay();
        }
#endif

        char* ap = ftp_path_absolute(dir);
        rdir = ftp_cache_get_directory(ap);
        const bool dir_is_cached = (rdir != 0);
        if (!rdir)
            rdir = ftp_read_directory(ap);
        free(ap);

#ifndef HAVE_LIBEDIT
        if (gvWaitingDots)
            rl_do_undo(); /* remove the dots */
#endif

        if (!dir_is_cached && ftp_get_verbosity() >= vbCommand)
            rl_forced_update_display();

        if (!rdir) {
            free(dir);
            return 0;
        }
        unquoted = dequote_filename(base_name_ptr(text), 0);
        if (!unquoted)
            unquoted = (char *)xmalloc(1);
        len = strlen(unquoted);
        lip = rdir->files->first;
    }

    while (lip) {
        rfile* fp = (rfile *)lip->data;
        lip = lip->next;

        /* 0 = not dir, 1 = dir, 2 = link (maybe dir) */
        const int isdir = ftp_maybe_isdir(fp);
        if (remote_dir_only && isdir == 0)
            continue;

        const char* name = base_name_ptr(fp->path);
        /* skip dotdirs in completion */
        if(strcmp(name, ".") == 0 || strcmp(name, "..") == 0)
            continue;

        if (strncmp(name, unquoted, len) == 0) {
            char *ret;
            if (dir)
            {
                if (asprintf(&ret, merge_fmt, dir, name) == -1)
                {
                    fprintf(stderr, _("Failed to allocate memory.\n"));
                    free(unquoted);
                    free(dir);
                    return NULL;
                }
            }
            else
                ret = xstrdup(name);
            if (isdir == 1) {
                rl_completion_append_character = '/';
            } else {
                rl_completion_append_character = ' ';
            }
            return ret;
        }
    }
    free(unquoted);
    free(dir);
    return NULL;
}
Exemple #7
0
int ssh_open_url(url_t* urlp)
{
  ftp->session = ssh_new();
  if (!ftp->session)
    return -1;

  /* set log level */
  if (ftp_get_verbosity() == vbDebug)
  {
    int verbosity = SSH_LOG_PROTOCOL;
    ssh_options_set(ftp->session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
  }

  /* If we have ssh options from yafcrc, load them */
  if (gvSSHOptions) {
    args_t *args = args_create();
    args_init(args, 0, NULL);
    args_push_back(args, gvSSHOptions);
    int argc = 0;
    if (ssh_options_getopt(ftp->session, &argc, args->argv) != SSH_OK) {
      ftp_err(_("Failed to load SSH options from yafcrc config (ssh_options = '%s')\n"), gvSSHOptions);
      ssh_free(ftp->session);
      ftp->session = NULL;
      return -1;
    }
    args->argc = argc;
    args_destroy(args);
  }

  /* set host name */
  ssh_options_set(ftp->session, SSH_OPTIONS_HOST, urlp->hostname);
  /* if we have port use that one */
  if (urlp->port > 0)
    ssh_options_set(ftp->session, SSH_OPTIONS_PORT, &urlp->port);

  /* parse .ssh/config */
  int r = ssh_options_parse_config(ftp->session, NULL);
  if (r != SSH_OK)
  {
    ftp_err(_("Failed to parse ssh config: %s\n"), ssh_get_error(ftp->session));
    ssh_free(ftp->session);
    ftp->session = NULL;
    return r;
  }

  /* if we have username use that one */
  if (urlp->username)
    ssh_options_set(ftp->session, SSH_OPTIONS_USER, urlp->username);

  /* connect to server */
  r = ssh_connect(ftp->session);
  if (r != SSH_OK)
  {
    ftp_err(_("Couldn't initialise connection to server: %s\n"), ssh_get_error(ftp->session));
    ssh_free(ftp->session);
    ftp->session = NULL;
    return r;
  }

  /* verify server */
  if (verify_knownhost(ftp->session))
  {
    ssh_disconnect(ftp->session);
    ssh_free(ftp->session);
    ftp->session = NULL;
    return -1;
  }

  /* authenticate user */
  r = test_several_auth_methods(ftp->session, urlp);
  if (r != SSH_OK)
  {
    ftp_err(_("Authentication failed: %s\n"), ssh_get_error(ftp->session));
    ssh_disconnect(ftp->session);
    ssh_free(ftp->session);
    ftp->session = NULL;
    return -1;
  }

  ftp->ssh_version = ssh_get_version(ftp->session);
  if (!ftp->ssh_version) {
    ftp_err(_("Couldn't initialise connection to server\n"));
    return -1;
  }

  ftp->sftp_session = sftp_new(ftp->session);
  if (!ftp->sftp_session)
  {
    ftp_err(_("Couldn't initialise ftp subsystem: %s\n"), ssh_get_error(ftp->session));
    ssh_disconnect(ftp->session);
    ssh_free(ftp->session);
    ftp->session = NULL;
    return -1;
  }

  r = sftp_init(ftp->sftp_session);
  if (r != SSH_OK)
  {
    ftp_err(_("Couldn't initialise ftp subsystem: %s\n"), ssh_get_error(ftp->sftp_session));
    sftp_free(ftp->sftp_session);
    ftp->sftp_session = NULL;
    ssh_disconnect(ftp->session);
    ssh_free(ftp->session);
    ftp->session = NULL;
    return r;
  }

  ftp->connected = true;
  ftp->loggedin = true;

  free(ftp->homedir);
  ftp->homedir = ftp_getcurdir();

  url_destroy(ftp->url);
  ftp->url = url_clone(urlp);

  free(ftp->curdir);
  ftp->curdir = xstrdup(ftp->homedir);
  free(ftp->prevdir);
  ftp->prevdir = xstrdup(ftp->homedir);
  if (ftp->url->directory)
    ftp_chdir(ftp->url->directory);

  ftp_get_feat();
  return 0;
}
Exemple #8
0
int ssh_open_url(url_t *urlp)
{
	char *sftp = gvSFTPServerProgram;
	char *s;
	int r;

	args_clear(ftp->ssh_args);

	if(urlp->sftp_server)
		sftp = urlp->sftp_server;

	args_push_back(ftp->ssh_args, gvSSHProgram);
	if(gvSSHOptions && strlen(gvSSHOptions))
		args_push_back(ftp->ssh_args, gvSSHOptions);
	args_push_back(ftp->ssh_args, urlp->hostname);

	r = get_username(urlp, gvUsername, false);
	if(r != 0)
		return r;

	if(urlp->username) {
		args_push_back(ftp->ssh_args, "-l");
		args_push_back(ftp->ssh_args, urlp->username);
	} else {
		/* we need a username, otherwise other functions will fail
		 */
		urlp->username = xstrdup(gvUsername);
	}

	if(urlp->port) {
		char *p;
		asprintf(&p, "%d", urlp->port);
		args_push_back(ftp->ssh_args, "-p");
		args_push_back(ftp->ssh_args, p);
		free(p);
	}

	if(ftp_get_verbosity() == vbDebug)
		args_push_back(ftp->ssh_args, "-v");

	/* no subsystem if the server-spec contains a '/' */
	if(sftp == 0 || strchr(sftp, '/') == 0)
		args_push_back(ftp->ssh_args, "-s");

	/* Otherwise finish up and return the arg array */
	if(sftp != 0)
		args_push_back(ftp->ssh_args, sftp);
	else
		args_push_back(ftp->ssh_args, "sftp");

	s = args_cat2(ftp->ssh_args, 0);
	ftp_trace("SSH args: %s\n", s);
	if(ftp_get_verbosity() == vbDebug)
		fprintf(stderr, "SSH args: %s\n", s);
	free(s);

	args_add_null(ftp->ssh_args);

	if(ssh_connect(ftp->ssh_args->argv, &ftp->ssh_in, &ftp->ssh_out,
				   &ftp->ssh_pid) == -1)
		{
			return -1;
		}

	ftp->ssh_version = ssh_init();
	if(ftp->ssh_version == -1) {
		ftp_err("Couldn't initialise connection to server\n");
		return -1;
	}

	ftp->connected = true;
	ftp->loggedin = true;

	ftp->homedir = ftp_getcurdir();

	url_destroy(ftp->url);
	ftp->url = url_clone(urlp);

	ftp->curdir = xstrdup(ftp->homedir);
	ftp->prevdir = xstrdup(ftp->homedir);
	if(ftp->url->directory)
		ftp_chdir(ftp->url->directory);

	ftp_get_feat();

	return 0;
}
Exemple #9
0
/* abort routine originally from Cftp by Dieter Baron
 */
int ftp_abort(FILE *fp)
{
    char buf[4096];
    fd_set ready;
    struct timeval poll;

    if(ftp->ssh_pid)
        /* FIXME: what? */
        return 0;

    if(!ftp_connected())
        return -1;

    ftp_set_close_handler();

    poll.tv_sec = poll.tv_usec = 0;
    FD_ZERO(&ready);
    FD_SET(ftp->ctrl->handle, &ready);
    if(select(ftp->ctrl->handle+1, &ready, 0, 0, &poll) == 1) {
        ftp_trace("There is data on the control channel, won't send ABOR\n");
        /* read remaining bytes from connection */
        while(fp && fread(buf, 1, 4096, fp) > 0)
            /* LOOP */ ;
        return 0;
    }

    ftp->ti.interrupted = true;
    ftp_err(_("Waiting for remote to finish abort...\n"));

    ftp_trace("--> telnet interrupt\n");
    if(sock_telnet_interrupt(ftp->ctrl) != 0)
        ftp_err("telnet interrupt: %s\n", strerror(errno));

    /* ftp_cmd("ABOR") won't work here,
     * we must flush data between the ABOR command and ftp_read_reply()
     */
    sock_krb_printf(ftp->ctrl, "ABOR");
    sock_printf(ftp->ctrl, "\r\n");
    sock_flush(ftp->ctrl);
    if(ftp_get_verbosity() == vbDebug)
        ftp_err("--> [%s] ABOR\n", ftp->url->hostname);
    else
        ftp_trace("--> [%s] ABOR\n", ftp->url->hostname);

    /* read remaining bytes from connection */
    while(fp && fread(buf, 1, 4096, fp) > 0)
        /* LOOP */ ;

    /* we expect a 426 or 226 reply here... */
    ftp_read_reply();
    if(ftp->fullcode != 426 && ftp->fullcode != 226)
        ftp_trace("Huh!? Expected a 426 or 226 reply\n");

    /* ... and a 226 or 225 reply here, respectively */
    /* FIXME: should skip this reply if prev. reply wasn't 426 or 226 ? */
    ftp_read_reply();
    if(ftp->fullcode != 226 && ftp->fullcode != 225)
        ftp_trace("Huh!? Expected a 226 or 225 reply\n");

    return -1;
}