Example #1
0
CStdString CWIN32Util::URLEncode(const CURL &url)
{
  /* due to smb wanting encoded urls we have to build it manually */

  CStdString flat = "smb://";

  if(url.GetDomain().length() > 0)
  {
    flat += url.GetDomain();
    flat += ";";
  }

  /* samba messes up of password is set but no username is set. don't know why yet */
  /* probably the url parser that goes crazy */
  if(url.GetUserName().length() > 0 /* || url.GetPassWord().length() > 0 */)
  {
    flat += url.GetUserName();
    flat += ":";
    flat += url.GetPassWord();
    flat += "@";
  }
  else if( !url.GetHostName().IsEmpty() && !g_guiSettings.GetString("smb.username").IsEmpty() )
  {
    /* okey this is abit uggly to do this here, as we don't really only url encode */
    /* but it's the simplest place to do so */
    flat += g_guiSettings.GetString("smb.username");
    flat += ":";
    flat += g_guiSettings.GetString("smb.password");
    flat += "@";
  }

  flat += url.GetHostName();

  /* okey sadly since a slash is an invalid name we have to tokenize */
  std::vector<CStdString> parts;
  std::vector<CStdString>::iterator it;
  CUtil::Tokenize(url.GetFileName(), parts, "/");
  for( it = parts.begin(); it != parts.end(); it++ )
  {
    flat += "/";
    flat += (*it);
  }

  /* okey options should go here, thou current samba doesn't support any */

  return flat;
}
Example #2
0
std::string CSMB::URLEncode(const CURL &url)
{
  /* due to smb wanting encoded urls we have to build it manually */

  std::string flat = "smb://";

  /* samba messes up of password is set but no username is set. don't know why yet */
  /* probably the url parser that goes crazy */
  if(url.GetUserName().length() > 0 /* || url.GetPassWord().length() > 0 */)
  {
    if(!url.GetDomain().empty())
    {
      flat += URLEncode(url.GetDomain());
      flat += ";";
    }
    flat += URLEncode(url.GetUserName());
    if(url.GetPassWord().length() > 0)
    {
      flat += ":";
      flat += URLEncode(url.GetPassWord());
    }
    flat += "@";
  }
  flat += URLEncode(url.GetHostName());

  if (url.HasPort())
  {
    flat += StringUtils::Format(":%i", url.GetPort());
  }

  /* okey sadly since a slash is an invalid name we have to tokenize */
  std::vector<std::string> parts;
  std::vector<std::string>::iterator it;
  StringUtils::Tokenize(url.GetFileName(), parts, "/");
  for( it = parts.begin(); it != parts.end(); ++it )
  {
    flat += "/";
    flat += URLEncode((*it));
  }

  /* okey options should go here, thou current samba doesn't support any */

  return flat;
}
Example #3
0
    CVFSURLWrapper(const CURL& url2)
    {
      m_strings.push_back(url2.Get());
      m_strings.push_back(url2.GetDomain());
      m_strings.push_back(url2.GetHostName());
      m_strings.push_back(url2.GetFileName());
      m_strings.push_back(url2.GetOptions());
      m_strings.push_back(url2.GetUserName());
      m_strings.push_back(url2.GetPassWord());
      m_strings.push_back(url2.GetRedacted());
      m_strings.push_back(url2.GetShareName());

      url.url = m_strings[0].c_str();
      url.domain = m_strings[1].c_str();
      url.hostname = m_strings[2].c_str();
      url.filename = m_strings[3].c_str();
      url.port = url2.GetPort();
      url.options = m_strings[4].c_str();
      url.username = m_strings[5].c_str();
      url.password = m_strings[6].c_str();
      url.redacted = m_strings[7].c_str();
      url.sharename = m_strings[8].c_str();
    }
Example #4
0
bool CWin32SMBDirectory::ConnectAndAuthenticate(CURL& url, bool allowPromptForCredential /*= false*/)
{
  assert(url.GetProtocol() == "smb");
  if (url.GetHostName().empty())
    return false; // can't connect to empty host name
  
  if (url.GetUserName().empty() && url.GetPassWord().empty())
    CPasswordManager::GetInstance().AuthenticateURL(url); // set username and password if any

  /* convert everything to wide strings */
  std::wstring serverNameW;
  if (!g_charsetConverter.utf8ToW(url.GetHostName(), serverNameW, false, false, true))
  {
    CLog::Log(LOGERROR, "%s: Can't convert server name \"%s\" to wide string", __FUNCTION__, url.GetHostName().c_str());
    return false;
  }
  serverNameW = L"\\\\" + serverNameW;

  std::string serverShareName; // for error descriptions
  std::wstring serverShareNameW;
  if (!url.GetShareName().empty())
  {
    serverShareName = "\\\\" + url.GetHostName() + "\\" + url.GetShareName();
    if (!g_charsetConverter.utf8ToW(serverShareName, serverShareNameW, false, false, true))
    {
      CLog::Log(LOGERROR, "%s: Can't convert share name \"%s\" to wide string", __FUNCTION__, serverShareName.c_str());
      return false;
    }
  }
  else
  {
    serverShareName = "\\\\" + url.GetHostName();
    serverShareNameW = serverNameW;
  }

  std::wstring usernameW;
  if (!url.GetUserName().empty() && !g_charsetConverter.utf8ToW(url.GetUserName(), usernameW, false, false, true))
  {
    CLog::Log(LOGERROR, "%s: Can't convert username \"%s\" to wide string", __FUNCTION__, url.GetUserName().c_str());
    return false;
    std::wstring domainW;
    if (!url.GetDomain().empty() && !g_charsetConverter.utf8ToW(url.GetDomain(), domainW, false, false, true))
    {
      CLog::Log(LOGERROR, "%s: Can't convert domain name \"%s\" to wide string", __FUNCTION__, url.GetDomain().c_str());
      return false;
    }
    if (!domainW.empty())
      usernameW += L'@' + domainW;
  }

  std::wstring passwordW;
  if (!url.GetPassWord().empty() && !g_charsetConverter.utf8ToW(url.GetPassWord(), passwordW, false, false, true))
  {
    CLog::Log(LOGERROR, "%s: Can't convert password to wide string", __FUNCTION__);
    return false;
  }

  std::string loginDescr;
  if (url.GetUserName().empty())
    loginDescr = "without username";
  else
    loginDescr = "with username \"" + url.GetUserName() + (url.GetDomain().empty() ? "" : "@" + url.GetDomain()) + "\"";

  loginDescr += url.GetPassWord().empty() ? " and without password" : " and with password";
  NETRESOURCEW connInfo = {};
  connInfo.dwType = RESOURCETYPE_ANY;
  connInfo.lpRemoteName = (LPWSTR)serverShareNameW.c_str();
  DWORD connRes;
  for (int i = 0; i < 3; i++) // make up to three attempts to connect
  {
    connRes = WNetAddConnection2W(&connInfo, passwordW.empty() ? NULL : (LPWSTR)passwordW.c_str(),
                                  usernameW.empty() ? NULL : (LPWSTR)usernameW.c_str(), CONNECT_TEMPORARY);
    if (connRes == NO_ERROR)
    {
      CLog::Log(LOGDEBUG, "%s: Connected to \"%s\" %s", __FUNCTION__, serverShareName.c_str(), loginDescr.c_str());
      return true;
    }
    
    if (connRes == ERROR_ACCESS_DENIED || connRes == ERROR_BAD_USERNAME || connRes == ERROR_INVALID_PASSWORD ||
        connRes == ERROR_LOGON_FAILURE || connRes == ERROR_LOGON_TYPE_NOT_GRANTED || connRes == ERROR_LOGON_NOT_GRANTED)
    {
      if (connRes == ERROR_ACCESS_DENIED)
        CLog::Log(LOGERROR, "%s: Doesn't have permissions to access \"%s\" %s", __FUNCTION__, serverShareName.c_str(), loginDescr.c_str());
      else
        CLog::Log(LOGERROR, "%s: Username/password combination was not accepted by \"%s\" when trying to connect %s", __FUNCTION__, serverShareName.c_str(), loginDescr.c_str());
      if (allowPromptForCredential)
        RequireAuthentication(url);

      return false; // don't try any more
    }
    else if (connRes == ERROR_BAD_NET_NAME || connRes == ERROR_NO_NET_OR_BAD_PATH || connRes == ERROR_NO_NETWORK)
    {
      CLog::Log(LOGERROR, "%s: Can't find \"%s\"", __FUNCTION__, serverShareName.c_str());
      return false; // don't try any more
    }
    else if (connRes == ERROR_BUSY)
      CLog::Log(LOGNOTICE, "%s: Network is busy for \"%s\"", __FUNCTION__, serverShareName.c_str());
    else if (connRes == ERROR_SESSION_CREDENTIAL_CONFLICT)
    {
      CLog::Log(LOGWARNING, "%s: Can't connect to \"%s\" %s because of conflict of credential. Will try to close current connections.", __FUNCTION__, serverShareName.c_str(), loginDescr.c_str());
      WNetCancelConnection2W((LPWSTR)serverShareNameW.c_str(), 0, FALSE);
      WNetCancelConnection2W((LPWSTR)(serverNameW + L"\\IPC$").c_str(), 0, FALSE);
      WNetCancelConnection2W((LPWSTR)serverNameW.c_str(), 0, FALSE);
    }
  }

  CLog::Log(LOGWARNING, "%s: Can't connect to \"%s\" %s. Error code: %lu", __FUNCTION__, serverShareName.c_str(), loginDescr.c_str(), (unsigned long)connRes);
  return false;
}