Пример #1
0
static void memory_tracking_init(void)
{
  char *env;
  /* if CURL_MEMDEBUG is set, this starts memory tracking message logging */
  env = curl_getenv("CURL_MEMDEBUG");
  if(env) {
    /* use the value as file name */
    char fname[CURL_MT_LOGFNAME_BUFSIZE];
    if(strlen(env) >= CURL_MT_LOGFNAME_BUFSIZE)
      env[CURL_MT_LOGFNAME_BUFSIZE-1] = '\0';
    strcpy(fname, env);
    curl_free(env);
    curl_memdebug(fname);
    /* this weird stuff here is to make curl_free() get called
       before curl_memdebug() as otherwise memory tracking will
       log a free() without an alloc! */
  }
  /* if CURL_MEMLIMIT is set, this enables fail-on-alloc-number-N feature */
  env = curl_getenv("CURL_MEMLIMIT");
  if(env) {
    char *endptr;
    long num = strtol(env, &endptr, 10);
    if((endptr != env) && (endptr == env + strlen(env)) && (num > 0))
      curl_memlimit(num);
    curl_free(env);
  }
}
Пример #2
0
int main(int argc, char **argv)
{
  char *URL;

#ifdef CURLDEBUG
  /* this sends all memory debug messages to a logfile named memdump */
  char *env = curl_getenv("CURL_MEMDEBUG");
  if(env) {
    /* use the value as file name */
    char *s = strdup(env);
    curl_free(env);
    curl_memdebug(s);
    free(s);
    /* this weird strdup() and stuff here is to make the curl_free() get
       called before the memdebug() as otherwise the memdebug tracing will
       with tracing a free() without an alloc! */
  }
  /* this enables the fail-on-alloc-number-N functionality */
  env = curl_getenv("CURL_MEMLIMIT");
  if(env) {
    char *endptr;
    long num = strtol(env, &endptr, 10);
    if((endptr != env) && (endptr == env + strlen(env)) && (num > 0))
      curl_memlimit(num);
    curl_free(env);
  }
#endif

  /*
   * Setup proper locale from environment. This is needed to enable locale-
   * specific behaviour by the C library in order to test for undesired side
   * effects that could cause in libcurl.
   */
#ifdef HAVE_SETLOCALE
  setlocale(LC_ALL, "");
#endif

  if(argc< 2 ) {
    fprintf(stderr, "Pass URL as argument please\n");
    return 1;
  }

  test_argc = argc;
  test_argv = argv;

  if(argc>2)
    libtest_arg2=argv[2];

  if(argc>3)
    libtest_arg3=argv[3];

  URL = argv[1]; /* provide this to the rest */

  fprintf(stderr, "URL: %s\n", URL);

  return test(URL);
}
Пример #3
0
int main(int argc, char **argv)
{
  char *URL;

#ifdef CURLDEBUG
  /* this sends all memory debug messages to a logfile named memdump */
  char *env = curl_getenv("CURL_MEMDEBUG");
  if(env) {
    /* use the value as file name */
    char *s = strdup(env);
    curl_free(env);
    curl_memdebug(s);
    free(s);
    /* this weird strdup() and stuff here is to make the curl_free() get
       called before the memdebug() as otherwise the memdebug tracing will
       with tracing a free() without an alloc! */
  }
  /* this enables the fail-on-alloc-number-N functionality */
  env = curl_getenv("CURL_MEMLIMIT");
  if(env) {
    curl_memlimit(atoi(env));
    curl_free(env);
  }
#endif
  if(argc< 2 ) {
    fprintf(stderr, "Pass URL as argument please\n");
    return 1;
  }
  if(argc>2)
    arg2=argv[2];

  URL = argv[1]; /* provide this to the rest */

  fprintf(stderr, "URL: %s\n", URL);

  return test(URL);
}
Пример #4
0
/*
 * @unittest: 1304
 *
 * *loginp and *passwordp MUST be allocated if they aren't NULL when passed
 * in.
 */
int Curl_parsenetrc(const char *host,
                    char **loginp,
                    char **passwordp,
                    char *netrcfile)
{
  FILE *file;
  int retcode=1;
  int specific_login = (*loginp && **loginp != 0);
  bool netrc_alloc = FALSE;
  enum host_lookup_state state=NOTHING;

  char state_login=0;      /* Found a login keyword */
  char state_password=0;   /* Found a password keyword */
  int state_our_login=FALSE;  /* With specific_login, found *our* login name */

#define NETRC DOT_CHAR "netrc"

  if(!netrcfile) {
    bool home_alloc = FALSE;
    char *home = curl_getenv("HOME"); /* portable environment reader */
    if(home) {
      home_alloc = TRUE;
#if defined(HAVE_GETPWUID_R) && defined(HAVE_GETEUID)
    }
    else {
      struct passwd pw, *pw_res;
      char pwbuf[1024];
      if(!getpwuid_r(geteuid(), &pw, pwbuf, sizeof(pwbuf), &pw_res)
         && pw_res) {
        home = strdup(pw.pw_dir);
        if(!home)
          return CURLE_OUT_OF_MEMORY;
        home_alloc = TRUE;
      }
#elif defined(HAVE_GETPWUID) && defined(HAVE_GETEUID)
    }
    else {
Пример #5
0
/*
 * @unittest: 1304
 */
int Curl_parsenetrc(const char *host,
                    char *login,
                    char *password,
                    char *netrcfile)
{
  FILE *file;
  int retcode=1;
  int specific_login = (login[0] != 0);
  char *home = NULL;
  bool home_alloc = FALSE;
  bool netrc_alloc = FALSE;
  enum host_lookup_state state=NOTHING;

  char state_login=0;      /* Found a login keyword */
  char state_password=0;   /* Found a password keyword */
  int state_our_login=FALSE;  /* With specific_login, found *our* login name */

#define NETRC DOT_CHAR "netrc"

  if(!netrcfile) {
    home = curl_getenv("HOME"); /* portable environment reader */
    if(home) {
      home_alloc = TRUE;
#if defined(HAVE_GETPWUID) && defined(HAVE_GETEUID)
    }
    else {
      struct passwd *pw;
      pw= getpwuid(geteuid());
      if(pw) {
#ifdef __VMS
        home = decc_translate_vms(pw->pw_dir);
#else
        home = pw->pw_dir;
#endif
      }
#endif
    }

    if(!home)
      return -1;

    netrcfile = curl_maprintf("%s%s%s", home, DIR_CHAR, NETRC);
    if(!netrcfile) {
      if(home_alloc)
        free(home);
      return -1;
    }
    netrc_alloc = TRUE;
  }

  file = fopen(netrcfile, "r");
  if(file) {
    char *tok;
    char *tok_buf;
    bool done=FALSE;
    char netrcbuffer[256];
    int  netrcbuffsize = (int)sizeof(netrcbuffer);

    while(!done && fgets(netrcbuffer, netrcbuffsize, file)) {
      tok=strtok_r(netrcbuffer, " \t\n", &tok_buf);
      while(!done && tok) {

        if(login[0] && password[0]) {
          done=TRUE;
          break;
        }

        switch(state) {
        case NOTHING:
          if(Curl_raw_equal("machine", tok)) {
            /* the next tok is the machine name, this is in itself the
               delimiter that starts the stuff entered for this machine,
               after this we need to search for 'login' and
               'password'. */
            state=HOSTFOUND;
          }
          break;
        case HOSTFOUND:
          if(Curl_raw_equal(host, tok)) {
            /* and yes, this is our host! */
            state=HOSTVALID;
            retcode=0; /* we did find our host */
          }
          else
            /* not our host */
            state=NOTHING;
          break;
        case HOSTVALID:
          /* we are now parsing sub-keywords concerning "our" host */
          if(state_login) {
            if(specific_login) {
              state_our_login = Curl_raw_equal(login, tok);
            }
            else {
              strncpy(login, tok, LOGINSIZE-1);
            }
            state_login=0;
          }
          else if(state_password) {
            if(state_our_login || !specific_login) {
              strncpy(password, tok, PASSWORDSIZE-1);
            }
            state_password=0;
          }
          else if(Curl_raw_equal("login", tok))
            state_login=1;
          else if(Curl_raw_equal("password", tok))
            state_password=1;
          else if(Curl_raw_equal("machine", tok)) {
            /* ok, there's machine here go => */
            state = HOSTFOUND;
            state_our_login = FALSE;
          }
          break;
        } /* switch (state) */

        tok = strtok_r(NULL, " \t\n", &tok_buf);
      } /* while(tok) */
    } /* while fgets() */

    fclose(file);
  }

  if(home_alloc)
    free(home);
  if(netrc_alloc)
    free(netrcfile);

  return retcode;
}
Пример #6
0
/* returns -1 on failure, 0 if the host is found, 1 is the host isn't found */
int Curl_parsenetrc(char *host,
                    char *login,
                    char *password,
                    char *netrcfile)
{
  FILE *file;
  int retcode=1;
  int specific_login = (login[0] != 0);
  char *home = NULL;
  bool home_alloc = FALSE;
  bool netrc_alloc = FALSE;
  int state=NOTHING;

  char state_login=0;      /* Found a login keyword */
  char state_password=0;   /* Found a password keyword */
  int state_our_login=FALSE;  /* With specific_login, found *our* login name */

#define NETRC DOT_CHAR "netrc"

#ifdef CURLDEBUG
  {
    /* This is a hack to allow testing.
     * If compiled with --enable-debug and CURL_DEBUG_NETRC is defined,
     * then it's the path to a substitute .netrc for testing purposes *only* */

    char *override = curl_getenv("CURL_DEBUG_NETRC");

    if (override) {
      fprintf(stderr, "NETRC: overridden " NETRC " file: %s\n", override);
      netrcfile = override;
      netrc_alloc = TRUE;
    }
  }
#endif /* CURLDEBUG */
  if(!netrcfile) {
    home = curl_getenv("HOME"); /* portable environment reader */
    if(home) {
      home_alloc = TRUE;
#if defined(HAVE_GETPWUID) && defined(HAVE_GETEUID)
    }
    else {
      struct passwd *pw;
      pw= getpwuid(geteuid());
      if (pw) {
#ifdef  VMS
        home = decc$translate_vms(pw->pw_dir);
#else
        home = pw->pw_dir;
#endif
      }
#endif
    }

    if(!home)
      return -1;

    netrcfile = curl_maprintf("%s%s%s", home, DIR_CHAR, NETRC);
    if(!netrcfile) {
      if(home_alloc)
        free(home);
      return -1;
    }
    netrc_alloc = TRUE;
  }

  file = fopen(netrcfile, "r");
  if(file) {
    char *tok;
    char *tok_buf;
    bool done=FALSE;
    char netrcbuffer[256];

    while(!done && fgets(netrcbuffer, sizeof(netrcbuffer), file)) {
      tok=strtok_r(netrcbuffer, " \t\n", &tok_buf);
      while(!done && tok) {

        if (login[0] && password[0]) {
          done=TRUE;
          break;
        }

        switch(state) {
        case NOTHING:
          if(strequal("machine", tok)) {
            /* the next tok is the machine name, this is in itself the
               delimiter that starts the stuff entered for this machine,
               after this we need to search for 'login' and
               'password'. */
            state=HOSTFOUND;
          }
          break;
        case HOSTFOUND:
          if(strequal(host, tok)) {
            /* and yes, this is our host! */
            state=HOSTVALID;
#ifdef _NETRC_DEBUG
            fprintf(stderr, "HOST: %s\n", tok);
#endif
            retcode=0; /* we did find our host */
          }
          else
            /* not our host */
            state=NOTHING;
          break;
        case HOSTVALID:
          /* we are now parsing sub-keywords concerning "our" host */
          if(state_login) {
            if (specific_login) {
              state_our_login = strequal(login, tok);
            }
            else {
              strncpy(login, tok, LOGINSIZE-1);
#ifdef _NETRC_DEBUG
              fprintf(stderr, "LOGIN: %s\n", login);
#endif
            }
            state_login=0;
          }
          else if(state_password) {
            if (state_our_login || !specific_login) {
              strncpy(password, tok, PASSWORDSIZE-1);
#ifdef _NETRC_DEBUG
              fprintf(stderr, "PASSWORD: %s\n", password);
#endif
            }
            state_password=0;
          }
          else if(strequal("login", tok))
            state_login=1;
          else if(strequal("password", tok))
            state_password=1;
          else if(strequal("machine", tok)) {
            /* ok, there's machine here go => */
            state = HOSTFOUND;
            state_our_login = FALSE;
          }
          break;
        } /* switch (state) */

        tok = strtok_r(NULL, " \t\n", &tok_buf);
      } /* while (tok) */
    } /* while fgets() */

    fclose(file);
  }

  if(home_alloc)
    free(home);
  if(netrc_alloc)
    free(netrcfile);

  return retcode;
}
Пример #7
0
static CURLcode ntlm_wb_init(struct connectdata *conn, const char *userp)
{
  curl_socket_t sockfds[2];
  pid_t child_pid;
  const char *username;
  char *slash, *domain = NULL;
  const char *ntlm_auth = NULL;
  char *ntlm_auth_alloc = NULL;
#if defined(HAVE_GETPWUID_R) && defined(HAVE_GETEUID)
  struct passwd pw, *pw_res;
  char pwbuf[1024];
#endif
  int error;

  /* Return if communication with ntlm_auth already set up */
  if(conn->ntlm_auth_hlpr_socket != CURL_SOCKET_BAD ||
     conn->ntlm_auth_hlpr_pid)
    return CURLE_OK;

  username = userp;
  /* The real ntlm_auth really doesn't like being invoked with an
     empty username. It won't make inferences for itself, and expects
     the client to do so (mostly because it's really designed for
     servers like squid to use for auth, and client support is an
     afterthought for it). So try hard to provide a suitable username
     if we don't already have one. But if we can't, provide the
     empty one anyway. Perhaps they have an implementation of the
     ntlm_auth helper which *doesn't* need it so we might as well try */
  if(!username || !username[0]) {
    username = getenv("NTLMUSER");
    if(!username || !username[0])
      username = getenv("LOGNAME");
    if(!username || !username[0])
      username = getenv("USER");
#if defined(HAVE_GETPWUID_R) && defined(HAVE_GETEUID)
    if((!username || !username[0]) &&
       !getpwuid_r(geteuid(), &pw, pwbuf, sizeof(pwbuf), &pw_res) &&
       pw_res) {
      username = pw.pw_name;
    }
#endif
    if(!username || !username[0])
      username = userp;
  }
  slash = strpbrk(username, "\\/");
  if(slash) {
    if((domain = strdup(username)) == NULL)
      return CURLE_OUT_OF_MEMORY;
    slash = domain + (slash - username);
    *slash = '\0';
    username = username + (slash - domain) + 1;
  }

  /* For testing purposes, when DEBUGBUILD is defined and environment
     variable CURL_NTLM_WB_FILE is set a fake_ntlm is used to perform
     NTLM challenge/response which only accepts commands and output
     strings pre-written in test case definitions */
#ifdef DEBUGBUILD
  ntlm_auth_alloc = curl_getenv("CURL_NTLM_WB_FILE");
  if(ntlm_auth_alloc)
    ntlm_auth = ntlm_auth_alloc;
  else
#endif
    ntlm_auth = NTLM_WB_FILE;

  if(access(ntlm_auth, X_OK) != 0) {
    error = ERRNO;
    failf(conn->data, "Could not access ntlm_auth: %s errno %d: %s",
          ntlm_auth, error, Curl_strerror(conn, error));
    goto done;
  }

  if(socketpair(AF_UNIX, SOCK_STREAM, 0, sockfds)) {
    error = ERRNO;
    failf(conn->data, "Could not open socket pair. errno %d: %s",
          error, Curl_strerror(conn, error));
    goto done;
  }

  child_pid = fork();
  if(child_pid == -1) {
    error = ERRNO;
    sclose(sockfds[0]);
    sclose(sockfds[1]);
    failf(conn->data, "Could not fork. errno %d: %s",
          error, Curl_strerror(conn, error));
    goto done;
  }
  else if(!child_pid) {
    /*
     * child process
     */

    /* Don't use sclose in the child since it fools the socket leak detector */
    sclose_nolog(sockfds[0]);
    if(dup2(sockfds[1], STDIN_FILENO) == -1) {
      error = ERRNO;
      failf(conn->data, "Could not redirect child stdin. errno %d: %s",
            error, Curl_strerror(conn, error));
      exit(1);
    }

    if(dup2(sockfds[1], STDOUT_FILENO) == -1) {
      error = ERRNO;
      failf(conn->data, "Could not redirect child stdout. errno %d: %s",
            error, Curl_strerror(conn, error));
      exit(1);
    }

    if(domain)
      execl(ntlm_auth, ntlm_auth,
            "--helper-protocol", "ntlmssp-client-1",
            "--use-cached-creds",
            "--username", username,
            "--domain", domain,
            NULL);
    else
      execl(ntlm_auth, ntlm_auth,
            "--helper-protocol", "ntlmssp-client-1",
            "--use-cached-creds",
            "--username", username,
            NULL);

    error = ERRNO;
    sclose_nolog(sockfds[1]);
    failf(conn->data, "Could not execl(). errno %d: %s",
          error, Curl_strerror(conn, error));
    exit(1);
  }

  sclose(sockfds[1]);
  conn->ntlm_auth_hlpr_socket = sockfds[0];
  conn->ntlm_auth_hlpr_pid = child_pid;
  free(domain);
  free(ntlm_auth_alloc);
  return CURLE_OK;

done:
  free(domain);
  free(ntlm_auth_alloc);
  return CURLE_REMOTE_ACCESS_DENIED;
}
Пример #8
0
/*
 * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
 * do protocol-specific actions at connect-time.
 */
CURLcode Curl_ssh_connect(struct connectdata *conn, bool *done)
{
  int i;
  struct SSHPROTO *ssh;
  const char *fingerprint;
  const char *authlist;
  char *home;
  char rsa_pub[PATH_MAX];
  char rsa[PATH_MAX];
  char tempHome[PATH_MAX];
  curl_socket_t sock;
  char *real_path;
  char *working_path;
  int working_path_len;
  bool authed = FALSE;
  CURLcode result;
  struct SessionHandle *data = conn->data;

  rsa_pub[0] = rsa[0] = '\0';

  result = ssh_init(conn);
  if (result)
    return result;

  ssh = data->reqdata.proto.ssh;

  working_path = curl_easy_unescape(data, data->reqdata.path, 0,
                                    &working_path_len);
  if (!working_path)
    return CURLE_OUT_OF_MEMORY;

#ifdef CURL_LIBSSH2_DEBUG
  if (ssh->user) {
    infof(data, "User: %s\n", ssh->user);
  }
  if (ssh->passwd) {
    infof(data, "Password: %s\n", ssh->passwd);
  }
#endif /* CURL_LIBSSH2_DEBUG */
  sock = conn->sock[FIRSTSOCKET];
  ssh->ssh_session = libssh2_session_init_ex(libssh2_malloc, libssh2_free,
                                            libssh2_realloc, ssh);
  if (ssh->ssh_session == NULL) {
    failf(data, "Failure initialising ssh session\n");
    Curl_safefree(ssh->path);
    return CURLE_FAILED_INIT;
  }
#ifdef CURL_LIBSSH2_DEBUG
  infof(data, "SSH socket: %d\n", sock);
#endif /* CURL_LIBSSH2_DEBUG */

  if (libssh2_session_startup(ssh->ssh_session, sock)) {
    failf(data, "Failure establishing ssh session\n");
    libssh2_session_free(ssh->ssh_session);
    ssh->ssh_session = NULL;
    Curl_safefree(ssh->path);
    return CURLE_FAILED_INIT;
  }

  /*
   * Before we authenticate we should check the hostkey's fingerprint against
   * our known hosts. How that is handled (reading from file, whatever) is
   * up to us. As for know not much is implemented, besides showing how to
   * get the fingerprint.
   */
  fingerprint = libssh2_hostkey_hash(ssh->ssh_session,
                                     LIBSSH2_HOSTKEY_HASH_MD5);

#ifdef CURL_LIBSSH2_DEBUG
  /* The fingerprint points to static storage (!), don't free() it. */
  infof(data, "Fingerprint: ");
  for (i = 0; i < 16; i++) {
    infof(data, "%02X ", (unsigned char) fingerprint[i]);
  }
  infof(data, "\n");
#endif /* CURL_LIBSSH2_DEBUG */

  /* TBD - methods to check the host keys need to be done */

  /*
   * Figure out authentication methods
   * NB: As soon as we have provided a username to an openssh server we must
   * never change it later. Thus, always specify the correct username here,
   * even though the libssh2 docs kind of indicate that it should be possible
   * to get a 'generic' list (not user-specific) of authentication methods,
   * presumably with a blank username. That won't work in my experience.
   * So always specify it here.
   */
  authlist = libssh2_userauth_list(ssh->ssh_session, ssh->user,
                                   strlen(ssh->user));

  /*
   * Check the supported auth types in the order I feel is most secure with the
   * requested type of authentication
   */
  if ((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) &&
      (strstr(authlist, "publickey") != NULL)) {
    /* To ponder about: should really the lib be messing about with the HOME
       environment variable etc? */
    home = curl_getenv("HOME");

    if (data->set.ssh_public_key)
      snprintf(rsa_pub, sizeof(rsa_pub), "%s", data->set.ssh_public_key);
    else if (home)
      snprintf(rsa_pub, sizeof(rsa_pub), "%s/.ssh/id_dsa.pub", home);

    if (data->set.ssh_private_key)
      snprintf(rsa, sizeof(rsa), "%s", data->set.ssh_private_key);
    else if (home)
      snprintf(rsa, sizeof(rsa), "%s/.ssh/id_dsa", home);

    curl_free(home);

    if (rsa_pub[0]) {
      /* The function below checks if the files exists, no need to stat() here.
      */
      if (libssh2_userauth_publickey_fromfile(ssh->ssh_session, ssh->user,
                                              rsa_pub, rsa, "") == 0) {
        authed = TRUE;
      }
    }
  }
  if (!authed &&
      (data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD) &&
      (strstr(authlist, "password") != NULL)) {
    if (!libssh2_userauth_password(ssh->ssh_session, ssh->user, ssh->passwd))
      authed = TRUE;
  }
  if (!authed && (data->set.ssh_auth_types & CURLSSH_AUTH_HOST) &&
      (strstr(authlist, "hostbased") != NULL)) {
  }
  if (!authed && (data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD)
      && (strstr(authlist, "keyboard-interactive") != NULL)) {
    /* Authentication failed. Continue with keyboard-interactive now. */
    if (libssh2_userauth_keyboard_interactive_ex(ssh->ssh_session, ssh->user,
                                                 strlen(ssh->user),
                                                 &kbd_callback) == 0) {
      authed = TRUE;
    }
  }

  if (!authed) {
    failf(data, "Authentication failure\n");
    libssh2_session_free(ssh->ssh_session);
    ssh->ssh_session = NULL;
    Curl_safefree(ssh->path);
    return CURLE_FAILED_INIT;
  }

  /*
   * At this point we have an authenticated ssh session.
   */
  conn->sockfd = sock;
  conn->writesockfd = CURL_SOCKET_BAD;

  if (conn->protocol == PROT_SFTP) {
    /*
     * Start the libssh2 sftp session
     */
    ssh->sftp_session = libssh2_sftp_init(ssh->ssh_session);
    if (ssh->sftp_session == NULL) {
      failf(data, "Failure initialising sftp session\n");
      libssh2_sftp_shutdown(ssh->sftp_session);
      ssh->sftp_session = NULL;
      libssh2_session_free(ssh->ssh_session);
      ssh->ssh_session = NULL;
      return CURLE_FAILED_INIT;
    }

    /*
     * Get the "home" directory
     */
    i = libssh2_sftp_realpath(ssh->sftp_session, ".", tempHome, PATH_MAX-1);
    if (i > 0) {
      /* It seems that this string is not always NULL terminated */
      tempHome[i] = '\0';
      ssh->homedir = (char *)strdup(tempHome);
      if (!ssh->homedir) {
        libssh2_sftp_shutdown(ssh->sftp_session);
        ssh->sftp_session = NULL;
        libssh2_session_free(ssh->ssh_session);
        ssh->ssh_session = NULL;
        return CURLE_OUT_OF_MEMORY;
      }
    }
    else {
      /* Return the error type */
      i = libssh2_sftp_last_error(ssh->sftp_session);
      DEBUGF(infof(data, "error = %d\n", i));
    }
  }

  /* Check for /~/ , indicating realative to the users home directory */
  if (conn->protocol == PROT_SCP) {
    real_path = (char *)malloc(working_path_len+1);
    if (real_path == NULL) {
      Curl_safefree(working_path);
      libssh2_session_free(ssh->ssh_session);
      ssh->ssh_session = NULL;
      return CURLE_OUT_OF_MEMORY;
    }
    if (working_path[1] == '~')
      /* It is referenced to the home directory, so strip the leading '/' */
      memcpy(real_path, working_path+1, 1 + working_path_len-1);
    else
      memcpy(real_path, working_path, 1 + working_path_len);
  }
  else if (conn->protocol == PROT_SFTP) {
    if (working_path[1] == '~') {
      real_path = (char *)malloc(strlen(ssh->homedir) +
                                 working_path_len + 1);
      if (real_path == NULL) {
        libssh2_sftp_shutdown(ssh->sftp_session);
        ssh->sftp_session = NULL;
        libssh2_session_free(ssh->ssh_session);
        ssh->ssh_session = NULL;
        Curl_safefree(working_path);
        return CURLE_OUT_OF_MEMORY;
      }
      /* It is referenced to the home directory, so strip the leading '/' */
      memcpy(real_path, ssh->homedir, strlen(ssh->homedir));
      real_path[strlen(ssh->homedir)] = '/';
      real_path[strlen(ssh->homedir)+1] = '\0';
      if (working_path_len > 3) {
        memcpy(real_path+strlen(ssh->homedir)+1, working_path + 3,
               1 + working_path_len -3);
      }
    }
    else {
      real_path = (char *)malloc(working_path_len+1);
      if (real_path == NULL) {
        libssh2_session_free(ssh->ssh_session);
        ssh->ssh_session = NULL;
        Curl_safefree(working_path);
        return CURLE_OUT_OF_MEMORY;
      }
      memcpy(real_path, working_path, 1+working_path_len);
    }
  }
  else
    return CURLE_FAILED_INIT;

  Curl_safefree(working_path);
  ssh->path = real_path;

  *done = TRUE;
  return CURLE_OK;
}
Пример #9
0
static CURLcode ntlm_wb_init(struct connectdata *conn, const char *userp)
{
  curl_socket_t sockfds[2];
  pid_t child_pid;
  const char *username;
  char *slash, *domain = NULL;
  const char *ntlm_auth = NULL;
  char *ntlm_auth_alloc = NULL;
  int error;

  /* Return if communication with ntlm_auth already set up */
  if(conn->ntlm_auth_hlpr_socket != CURL_SOCKET_BAD ||
     conn->ntlm_auth_hlpr_pid)
    return CURLE_OK;

  username = userp;
  slash = strpbrk(username, "\\/");
  if(slash) {
    if((domain = strdup(username)) == NULL)
      return CURLE_OUT_OF_MEMORY;
    slash = domain + (slash - username);
    *slash = '\0';
    username = username + (slash - domain) + 1;
  }

  /* For testing purposes, when DEBUGBUILD is defined and environment
     variable CURL_NTLM_WB_FILE is set a fake_ntlm is used to perform
     NTLM challenge/response which only accepts commands and output
     strings pre-written in test case definitions */
#ifdef DEBUGBUILD
  ntlm_auth_alloc = curl_getenv("CURL_NTLM_WB_FILE");
  if(ntlm_auth_alloc)
    ntlm_auth = ntlm_auth_alloc;
  else
#endif
    ntlm_auth = NTLM_WB_FILE;

  if(access(ntlm_auth, X_OK) != 0) {
    error = ERRNO;
    failf(conn->data, "Could not access ntlm_auth: %s errno %d: %s",
          ntlm_auth, error, Curl_strerror(conn, error));
    goto done;
  }

  if(socketpair(AF_UNIX, SOCK_STREAM, 0, sockfds)) {
    error = ERRNO;
    failf(conn->data, "Could not open socket pair. errno %d: %s",
          error, Curl_strerror(conn, error));
    goto done;
  }

  child_pid = fork();
  if(child_pid == -1) {
    error = ERRNO;
    sclose(sockfds[0]);
    sclose(sockfds[1]);
    failf(conn->data, "Could not fork. errno %d: %s",
          error, Curl_strerror(conn, error));
    goto done;
  }
  else if(!child_pid) {
    /*
     * child process
     */

    /* Don't use sclose in the child since it fools the socket leak detector */
    sclose_nolog(sockfds[0]);
    if(dup2(sockfds[1], STDIN_FILENO) == -1) {
      error = ERRNO;
      failf(conn->data, "Could not redirect child stdin. errno %d: %s",
            error, Curl_strerror(conn, error));
      exit(1);
    }

    if(dup2(sockfds[1], STDOUT_FILENO) == -1) {
      error = ERRNO;
      failf(conn->data, "Could not redirect child stdout. errno %d: %s",
            error, Curl_strerror(conn, error));
      exit(1);
    }

    if(domain)
      execl(ntlm_auth, ntlm_auth,
            "--helper-protocol", "ntlmssp-client-1",
            "--use-cached-creds",
            "--username", username,
            "--domain", domain,
            NULL);
    else
      execl(ntlm_auth, ntlm_auth,
            "--helper-protocol", "ntlmssp-client-1",
            "--use-cached-creds",
            "--username", username,
            NULL);

    error = ERRNO;
    sclose_nolog(sockfds[1]);
    failf(conn->data, "Could not execl(). errno %d: %s",
          error, Curl_strerror(conn, error));
    exit(1);
  }

  sclose(sockfds[1]);
  conn->ntlm_auth_hlpr_socket = sockfds[0];
  conn->ntlm_auth_hlpr_pid = child_pid;
  Curl_safefree(domain);
  Curl_safefree(ntlm_auth_alloc);
  return CURLE_OK;

done:
  Curl_safefree(domain);
  Curl_safefree(ntlm_auth_alloc);
  return CURLE_REMOTE_ACCESS_DENIED;
}