Example #1
0
static void create_bookmark(const char *guessed_alias)
{
	char *default_alias = 0;
	char *prompt;
	url_t *url;
	listitem *li;
	int a;
	char *alias;

	alias = xstrdup(guessed_alias);

	while(true) {
		if(!alias) {
			default_alias = guess_alias(ftp->url);

			if(default_alias)
				asprintf(&prompt, "alias (%s): ", default_alias);
			else
				prompt = xstrdup("alias: ");

			force_completion_type = cpBookmark;
			alias = input_read_string(prompt);
			free(prompt);
			if(!alias || !*alias)
				alias = default_alias;
			else
				free(default_alias);
		}

		url = url_clone(ftp->url);
		url_setalias(url, alias);
		free(alias);
		alias = 0;

		li = list_search(gvBookmarks, (listsearchfunc)urlcmp, url);
		if(li) {
			a = ask(ASKYES|ASKNO|ASKCANCEL, ASKYES,
					_("a bookmark named '%s' already exists, overwrite?"),
					url->alias ? url->alias : url->hostname);
			if(a == ASKCANCEL) {
				url_destroy(url);
				return;
			}
			if(a == ASKYES)
				break;
		} else
			break;
	}

	/* password is automatically saved if anonymous login */
	if(!url_isanon(url) && url->password) {
		a = ask(ASKYES|ASKNO, ASKNO, _("Save password?"));
		if(a == ASKNO)
			url_setpassword(url, 0);
	}

	create_the_bookmark(url);
	printf(_("created bookmark %s\n"), url->alias);
}
Example #2
0
int ftp_reopen(void)
{
    if(ftp && ftp->url) {
        url_t *u = url_clone(ftp->url);
        int r;

        url_setdirectory(u, ftp->curdir);

        r = ftp_open_url(u, false);
        if(r == 0) {
            r = ftp_login(u->username, gvAnonPasswd);
        } else
            ftp_close();
        url_destroy(u);
        return r;
    }

    return -1;
}
Example #3
0
int ftp_login(const char *guessed_username, const char *anonpass)
{
    int ptype, r;
    static url_t *purl = 0;

    if(!ftp_connected())
        return 1;

    if(!ftp->url)
        return -1;

#ifdef HAVE_LIBSSH
    if (ftp->session)
        /* login authentication is performed by the ssh program */
        return 0;
#endif

    ptype = proxy_type(ftp->url);
    if(purl) {
        url_destroy(purl);
        purl = 0;
    }
    if(ptype > 0)
        purl = url_clone(gvProxyUrl);

    r = get_username(ftp->url, guessed_username, false);
    if(r != 0)
        return r;
    if(ptype > 1 && ptype < 7) {
        r = get_username(purl, 0, true);
        if(r != 0)
            return r;
    }

#ifdef SECFTP
    ftp->sec_complete = false;
    ftp->data_prot = prot_clear;

    /* don't use secure stuff if anonymous
     */
    if(!url_isanon(ftp->url)) {
        list *mechlist;
        /* request a protection level
         */
        if(ftp->url->protlevel) {
            if(sec_request_prot(ftp->url->protlevel) != 0)
                ftp_err(_("Invalid protection level '%s'\n"),
                        ftp->url->protlevel);
        }

        /* get list of mechanisms to try
         */
        mechlist = ftp->url->mech ? ftp->url->mech : gvDefaultMechanism;
        if(mechlist) {
            listitem *li = mechlist->first;
            int ret = 0;
            for(; li; li=li->next) {
                const char *mech_name;

                mech_name = secext_name((char *)li->data);
                if(mech_name == 0) {
                    ftp_err(_("unknown mechanism '%s'\n"), (char *)li->data);
                    continue;
                }
                if(mech_unsupported(mech_name)) {
                    ftp_err(_("Yafc was not compiled with support for %s\n"),
                            mech_name);
                    continue;
                }
                ret = sec_login(host_getname(ftp->host), mech_name);
                if(ret == -1) {
                    if(ftp->code == ctError
                       && ftp->fullcode != 504 && ftp->fullcode != 534)
                        url_setmech(ftp->url, "none");
                }
                if(ret != 1)
                    break;
            }
        }
        if(ftp->sec_complete)
            ftp_err(_("Authentication successful.\n"));
        else
            ftp_err(_("*** Using plaintext username"
                      " and password ***\n"));
    }
#endif

    if(url_isanon(ftp->url))
        fprintf(stderr, _("logging in anonymously...\n"));
    ftp_set_tmp_verbosity(ftp->url->password ? vbError : vbCommand);

    switch(ptype) {
      case 0:
      default:
        ftp_cmd("USER %s", ftp->url->username);
        break;
      case 1:
        ftp_cmd("USER %s@%s", ftp->url->username, ftp->url->hostname);
        break;
      case 2:
      case 3:
      case 4:
        ftp_cmd("USER %s", purl->username);
        if(ftp->code == ctContinue) {
            r = get_password(purl, 0, true);
            if(r != 0)
                return 0;
            ftp_cmd("PASS %s", purl->password);
            /* FIXME: what reply code do we expect now? */
            if(ftp->code < ctTransient) {
                if(ptype == 2) {
                    ftp_cmd("USER %s@%s",
                            ftp->url->username, ftp->url->hostname);
                } else {
                    if(ptype == 3)
                        ftp_cmd("SITE %s", purl->hostname);
                    else
                        ftp_cmd("OPEN %s", purl->hostname);
                    if(ftp->code < ctTransient)
                        ftp_cmd("USER %s", ftp->url->username);
                }
            }
        }
        break;
      case 5:
        ftp_cmd("USER %s@%s@%s",
                ftp->url->username, purl->username, ftp->url->hostname);
        break;
      case 6:
        ftp_cmd("USER %s@%s", purl->username, ftp->url->hostname);
        if(ftp->code == ctContinue) {
            r = get_password(purl, 0, true);
            if(r != 0)
                return 0;
            ftp_cmd("PASS %s", purl->password);
            if(ftp->code < ctTransient)
                ftp_cmd("USER %s", ftp->url->username);
        }
        break;
      case 7:
        ftp_cmd("USER %s@%s:%i", ftp->url->username, ftp->url->hostname, ftp->url->port);
        break;
    }

    if(ftp->code == ctContinue) {
        ftp->loggedin = false;
        r = get_password(ftp->url, anonpass, false);
        if(r != 0)
            return r;
        if(ptype == 5) {
            r = get_password(purl, 0, true);
            if(r != 0) {
                url_destroy(purl);
                purl = 0;
                return 0;
            }
        }

        ftp_set_tmp_verbosity(vbCommand);
        switch(ptype) {
          default:
          case 0:
          case 1:
          case 2:
          case 3:
          case 4:
          case 6:
            ftp_cmd("PASS %s", ftp->url->password);
            break;
          case 5:
            ftp_cmd("PASS %s@%s", ftp->url->password, purl->password);
            break;

        }
    }

    url_destroy(purl);
    purl = 0;

    if(ftp->code > ctContinue) {
        if(ftp->fullcode == 530 && ftp_loggedin()) {
            /* this probable means '530 Already logged in' */
            return 2;
        }
        ftp->loggedin = false;
        return 1;
    }
    if(ftp->code == ctComplete) {
        ftp->loggedin = true;
#ifdef SECFTP
        /* we are logged in, now set the requested data protection level
         * requested from the autologin information in the config file,
         * if any, else uses default protection level 'clear', ie
         * no protection on the data channel
         */
        if(ftp->sec_complete) {
            sec_set_protection_level();
            fprintf(stderr, _("Data protection is %s\n"),
                    level_to_name(ftp->data_prot));
        }
#endif
        ftp->homedir = ftp_getcurdir();
        ftp->curdir = xstrdup(ftp->homedir);
        ftp->prevdir = xstrdup(ftp->homedir);
        if(ftp->url->directory)
            ftp_chdir(ftp->url->directory);
        ftp_get_feat();
        return 0;
    }
    if(ftp->code == ctTransient)
        return 1;
    return -1;
}
Example #4
0
int ftp_open_url(url_t *urlp, bool reset_vars)
{
    bool use_proxy;
    int i;

    if(reset_vars)
        ftp_reset_vars();
    /* don't assume server is in ascii mode initially even if RFC says so */
    ftp->prev_type = '?';

#ifdef HAVE_POSIX_SIGSETJMP
    if(sigsetjmp(open_timeout_jmp, 1))
#else
    if(setjmp(open_timeout_jmp))
#endif
    {
        ftp_close();
        ftp_err(_("Connection timeout after %u seconds\n"),
                ftp->open_timeout);
        return 1;
    }
    ftp_set_signal(SIGALRM, ftp_open_handler);
    alarm(ftp->open_timeout);

    use_proxy = (proxy_type(urlp) != 0);

    ftp_err(_("Looking up %s... "),
            use_proxy ? gvProxyUrl->hostname : urlp->hostname);

    /* Set the default port (22) for SSH if no port is specified. We
     * need to do this here, 'cause host_lookup() sets it to 21
     * (default port for vanilla FTP)
     */
    if(urlp->protocol) {
        if(strcmp(urlp->protocol, "sftp") == 0)
            url_setprotocol(urlp, "ssh");
        if(strcmp(urlp->protocol, "ssh") == 0 && urlp->port == -1)
            urlp->port = 22; /* default SSH port */
    }

    ftp->host = host_create(use_proxy ? gvProxyUrl : urlp);

    if(!host_lookup(ftp->host)) {
        herror(host_getname(ftp->host));
        alarm(0);
        ftp_set_signal(SIGALRM, SIG_IGN);
        return -1;
    }
    /* keep the value in urlp->port
    urlp->port = ntohs(ftp->host->port);
    and set it to 21 if it is -1 */
    if(urlp->port == -1) {
	    urlp->port = 21;
    }


    fprintf(stderr, "\r               ");
    i = strlen(use_proxy ? gvProxyUrl->hostname : urlp->hostname);
    while(i--)
        fprintf(stderr, " ");
    fprintf(stderr, "\r");
    ftp_trace("\n");

#ifdef HAVE_LIBSSH
    if(urlp->protocol && strcmp(urlp->protocol, "ssh") == 0) {
        int ret = ssh_open_url(urlp);
        alarm(0);
        return ret;
    }
#endif

    if(urlp->protocol && strcmp(urlp->protocol, "ftp") != 0) {
        ftp_err(_("Sorry, don't know how to handle your '%s' protocol\n"
                  "trying 'ftp' instead...\n"),
                urlp->protocol);
        url_setprotocol(urlp, 0);
    }

    if(use_proxy) {
        ftp_err(_("Connecting to proxy %s at port %d...\n"),
                host_getoname(ftp->host), urlp->port);
    } else {
        ftp_err(_("Connecting to %s at port %d...\n"),
                host_getoname(ftp->host), urlp->port);
    }

    ftp->ctrl = sock_create();
    if (ftp->ctrl == 0) {
        ftp_err(_("Unable to create socket.\n"));
        alarm(0);
        ftp_set_signal(SIGALRM, SIG_IGN);
        return -1;
    }

    if(!sock_connect_host(ftp->ctrl, ftp->host)) {
        alarm(0);
        ftp_set_signal(SIGALRM, SIG_IGN);
        return -1;
    }
    sock_lowdelay(ftp->ctrl);
    char* ip = host_getip(ftp->host);
    ftp_err(_("Connected to %s ([%s]:%d).\n"),
        host_getoname(ftp->host), ip, urlp->port);
    free(ip);

    /* read startup message from server */
    ftp_set_tmp_verbosity(vbCommand);
    ftp_read_reply();
    if(ftp->fullcode == 120) {
        ftp_set_tmp_verbosity(vbCommand);
        ftp_read_reply();
    }
    alarm(0);
    ftp_set_signal(SIGALRM, SIG_IGN);
    if(!sock_connected(ftp->ctrl)) {
        ftp_close();
        return 1;
    }
    ftp->connected = (ftp->fullcode == 220);

    if(ftp->connected) {
        void (*tracefunq)(const char *fmt, ...);

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

        tracefunq = (ftp->verbosity == vbDebug ? ftp_err : ftp_trace);

        char* remote_addr = printable_address(sock_remote_addr(ftp->ctrl)),
            *local_addr = printable_address(sock_local_addr(ftp->ctrl));
        tracefunq("remote address: %s\n", remote_addr);
        tracefunq("local address: %s\n", local_addr);
        free(remote_addr);
        free(local_addr);

        return 0;
    } else {
        ftp_close();
        return 1;
    }
}
Example #5
0
void auto_create_bookmark(void)
{
	listitem *li;
	int a;
	bool auto_create, had_passwd = false;
	bool update = false;

	if(gvAutoBookmark == 0 && gvAutoBookmarkUpdate == 0)
		return;

	if(!ftp_loggedin() || gvSighupReceived)
		return;

	auto_create = (gvAutoBookmark == 1);

	/* check if bookmark already exists */
	li = list_search(gvBookmarks, (listsearchfunc)urlcmp, ftp->url);
	if(li) {
		if(!should_update_bookmark((url_t *)li->data))
			return;

		/* bookmark already exist, update it */
		if(gvAutoBookmarkUpdate == 2) {
			a = ask(ASKYES|ASKNO, ASKYES,
					_("Do you want to update the bookmark for this site?"));
			if(a == ASKNO)
				return;
		}

		update = true;
		auto_create = true;
		had_passwd = (((url_t *)li->data)->password != 0);
	}

	if(gvAutoBookmark == 2 && !auto_create) {
		a = ask(ASKYES|ASKNO, ASKYES,
				_("Do you want to create a bookmark for this site?"));
		if(a == ASKNO)
			return;
		create_bookmark(0);
	} else { /* auto autobookmark... */
		url_t* url = url_clone(ftp->url);
		char* a = guess_alias(ftp->url);
		url_setalias(url, a);
		free(a);

		li = list_search(gvBookmarks, (listsearchfunc)urlcmp, url);
		if(li) {
			/* bookmark already exist, overwrite it */
			while(true) {
				url_t *xurl = (url_t *)li->data;

				if(xurl->alias && (strcmp(xurl->alias, url->alias) == 0)
				   && (strcmp(xurl->hostname, url->hostname) != 0))
				{
					/* create a new version of the alias, since guessed alias
					 * already exists but for another host
					 */

					update = false;
					char* par = strrchr(url->alias, '(');
          int ver = 1;
          if (par)
					{
						*par = 0;
						ver = atoi(par + 1);
					}
          if (asprintf(&a, "%s(%d)", url->alias, ver + 1) == -1)
          {
            fprintf(stderr, _("Failed to allocate memory.\n"));
            url_destroy(url);
            return;
          }
					url_setalias(url, a);
					free(a);
				} else {
					update = true;
					had_passwd = (xurl->password != 0);
					break;
				}
				li = list_search(gvBookmarks, (listsearchfunc)urlcmp, url);
				if(li == 0)
					break;
			}
			if(li) /* overwrite bookmark (ie, delete old and create a new) */
				list_delitem(gvBookmarks, li);
			if(!url_isanon(url) && gvAutoBookmarkSavePasswd == false
			   && !had_passwd)
				url_setpassword(url, 0);
		} else {
			if(!url_isanon(url) && gvAutoBookmarkSavePasswd == false)
				url_setpassword(url, 0);
		}
		create_the_bookmark(url);
		if(!gvAutoBookmarkSilent) {
			if(update)
				printf(_("updated bookmark %s\n"), url->alias);
			else
				printf(_("created bookmark %s\n"), url->alias);
		}
	}
}
Example #6
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;
}
Example #7
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;
}