Imported Upstream version 17.25.4
[platform/upstream/libzypp.git] / zypp / media / MediaUserAuth.cc
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/media/MediaUserAuth.cc
10  *
11  */
12
13 #include <list>
14 #include <curl/curl.h>
15
16 #include <zypp/base/Gettext.h>
17 #include <zypp/base/String.h>
18
19 #include <zypp/media/MediaException.h>
20 #include <zypp/media/MediaUserAuth.h>
21
22 using std::endl;
23
24 namespace zypp {
25   namespace media {
26
27
28 AuthData::AuthData(const Url & url)
29   : _url(url)
30 {
31   _username = url.getUsername();
32   _password = url.getPassword();
33 }
34
35
36 bool AuthData::valid() const
37 {
38   return username().size() && password().size();
39 }
40
41 std::ostream & AuthData::dumpOn( std::ostream & str ) const
42 {
43   if (_url.isValid())
44     str << "[" << _url.asString( url::ViewOptions() - url::ViewOptions::WITH_USERNAME - url::ViewOptions::WITH_PASSWORD ) << "]" << endl;
45   else
46     str << "[<no-url>]" << endl;
47   str << "username: '" << _username << "'" << std::endl
48       << "password: " << (_password.empty() ? "<empty>" : "<non-empty>");
49   return str;
50 }
51
52 std::ostream & AuthData::dumpAsIniOn( std::ostream & str ) const
53 {
54   if (_url.isValid())
55     str
56       << "[" << _url.asString(
57         url::ViewOptions()
58         - url::ViewOptions::WITH_USERNAME
59         - url::ViewOptions::WITH_PASSWORD)
60       << "]" << endl;
61
62   str
63     << "username = " << _username << endl
64     << "password = " << _password << endl;
65
66   return str;
67 }
68
69 CurlAuthData::CurlAuthData()
70   : AuthData()
71   , _auth_type_str()
72   , _auth_type(CURLAUTH_NONE)
73 {}
74
75 CurlAuthData::CurlAuthData(const AuthData & authData)
76   : AuthData(authData)
77   , _auth_type_str()
78   , _auth_type(CURLAUTH_NONE)
79 {}
80
81 bool CurlAuthData::valid() const
82 {
83   return username().size() && password().size();
84 }
85
86 std::ostream & CurlAuthData::dumpOn( std::ostream & str ) const
87 {
88   AuthData::dumpOn(str) << endl
89   << " auth_type: " << _auth_type_str << " (" << _auth_type << ")";
90   return str;
91 }
92
93 long CurlAuthData::auth_type_str2long( std::string & auth_type_str )
94 {
95   return auth_type_str2long( const_cast< const std::string &>(auth_type_str) );
96 }
97
98 long CurlAuthData::auth_type_str2long( const std::string & auth_type_str )
99 {
100   curl_version_info_data *curl_info = curl_version_info(CURLVERSION_NOW);
101
102   std::vector<std::string>                  list;
103   std::vector<std::string>::const_iterator  it;
104   long                                      auth_type = CURLAUTH_NONE;
105
106   zypp::str::split(auth_type_str, std::back_inserter(list), ",");
107
108   for(it = list.begin(); it != list.end(); ++it)
109   {
110     if(*it == "basic")
111     {
112       auth_type |= CURLAUTH_BASIC;
113     }
114     else
115     if(*it == "digest")
116     {
117       auth_type |= CURLAUTH_DIGEST;
118     }
119     else
120     if((curl_info && (curl_info->features & CURL_VERSION_NTLM)) &&
121        (*it == "ntlm"))
122     {
123       auth_type |= CURLAUTH_NTLM;
124     }
125     else
126     if((curl_info && (curl_info->features & CURL_VERSION_SPNEGO)) &&
127        (*it == "spnego" || *it == "negotiate"))
128     {
129       // there is no separate spnego flag for this auth type
130       auth_type |= CURLAUTH_GSSNEGOTIATE;
131     }
132     else
133     if((curl_info && (curl_info->features & CURL_VERSION_GSSNEGOTIATE)) &&
134        (*it == "gssnego" || *it == "negotiate"))
135     {
136       auth_type |= CURLAUTH_GSSNEGOTIATE;
137     }
138     else
139     {
140       ZYPP_THROW(MediaException(str::Format(_("Unsupported HTTP authentication method '%s'")) % *it));
141     }
142   }
143
144   return auth_type;
145 }
146
147 std::string CurlAuthData::auth_type_long2str(long auth_type)
148 {
149   std::list<std::string> auth_list;
150
151   if(auth_type & CURLAUTH_GSSNEGOTIATE)
152     auth_list.push_back("negotiate");
153
154   if(auth_type & CURLAUTH_NTLM)
155     auth_list.push_back("ntlm");
156
157   if(auth_type & CURLAUTH_DIGEST)
158     auth_list.push_back("digest");
159
160   if(auth_type & CURLAUTH_BASIC)
161     auth_list.push_back("basic");
162
163   return str::join(auth_list, ",");
164 }
165
166
167 std::ostream & operator << (std::ostream & str, const AuthData & auth_data)
168 {
169   auth_data.dumpOn(str);
170   return str;
171 }
172
173 std::ostream & operator << (std::ostream & str, const CurlAuthData & auth_data)
174 {
175   auth_data.dumpOn(str);
176   return str;
177 }
178
179
180   } // namespace media
181 } // namespace zypp