This file is indexed.

/usr/include/cpprest/oauth1.h is in libcpprest-dev 2.8.0-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
/***
* ==++==
*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* ==--==
* =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
*
* HTTP Library: Oauth 1.0
*
* For the latest on this and related APIs, please see: https://github.com/Microsoft/cpprestsdk
*
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
****/
#pragma once

#ifndef _CASA_OAUTH1_H
#define _CASA_OAUTH1_H

#include "cpprest/http_msg.h"
#include "cpprest/details/web_utilities.h"

namespace web
{
namespace http
{
namespace client
{
    // Forward declaration to avoid circular include dependency.
    class http_client_config;
}

/// oAuth 1.0 library.
namespace oauth1
{
namespace details
{

class oauth1_handler;

// State currently used by oauth1_config to authenticate request.
// The state varies for every request (due to timestamp and nonce).
// The state also contains extra transmitted protocol parameters during
// authorization flow (i.e. 'oauth_callback' or 'oauth_verifier').
class oauth1_state
{
public:
    oauth1_state(utility::string_t timestamp, utility::string_t nonce,
            utility::string_t extra_key=utility::string_t(),
            utility::string_t extra_value=utility::string_t()) :
        m_timestamp(std::move(timestamp)),
        m_nonce(std::move(nonce)),
        m_extra_key(std::move(extra_key)),
        m_extra_value(std::move(extra_value))
    {}

    const utility::string_t& timestamp() const { return m_timestamp; }
    void set_timestamp(utility::string_t timestamp) { m_timestamp = std::move(timestamp); }

    const utility::string_t& nonce() const { return m_nonce; }
    void set_nonce(utility::string_t nonce) { m_nonce = std::move(nonce); }

    const utility::string_t& extra_key() const { return m_extra_key; }
    void set_extra_key(utility::string_t key) { m_extra_key = std::move(key); }

    const utility::string_t& extra_value() const { return m_extra_value; }
    void set_extra_value(utility::string_t value) { m_extra_value = std::move(value); }

private:
    utility::string_t m_timestamp;
    utility::string_t m_nonce;
    utility::string_t m_extra_key;
    utility::string_t m_extra_value;
};

// Constant strings for OAuth 1.0.
typedef utility::string_t oauth1_string;
class oauth1_strings
{
public:
#define _OAUTH1_STRINGS
#define DAT(a_, b_) _ASYNCRTIMP static const oauth1_string a_;
#include "cpprest/details/http_constants.dat"
#undef _OAUTH1_STRINGS
#undef DAT
};

} // namespace web::http::oauth1::details

/// oAuth functionality is currently in beta.
namespace experimental
{

/// <summary>
/// Constant strings for OAuth 1.0 signature methods.
/// </summary>
typedef utility::string_t oauth1_method;
class oauth1_methods
{
public:
#define _OAUTH1_METHODS
#define DAT(a,b) _ASYNCRTIMP static const oauth1_method a;
#include "cpprest/details/http_constants.dat"
#undef _OAUTH1_METHODS
#undef DAT
};

/// <summary>
/// Exception type for OAuth 1.0 errors.
/// </summary>
class oauth1_exception : public std::exception
{
public:
    oauth1_exception(utility::string_t msg) : m_msg(utility::conversions::to_utf8string(std::move(msg))) {}
    ~oauth1_exception() CPPREST_NOEXCEPT {}
    const char* what() const CPPREST_NOEXCEPT { return m_msg.c_str(); }

private:
    std::string m_msg;
};

/// <summary>
/// OAuth 1.0 token and associated information.
/// </summary>
class oauth1_token
{
public:

    /// <summary>
    /// Constructs an initially empty invalid access token.
    /// </summary>
    oauth1_token() {}

    /// <summary>
    /// Constructs a OAuth1 token from a given access token and secret.
    /// </summary>
    /// <param name="access_token">Access token string.</param>
    /// <param name="secret">Token secret string.</param>
    oauth1_token(utility::string_t access_token, utility::string_t secret) :
        m_token(std::move(access_token)),
        m_secret(std::move(secret))
    {}

    /// <summary>
    /// Get access token validity state.
    /// If true, token is a valid access token.
    /// </summary>
    /// <returns>Access token validity state of the token.</returns>
    bool is_valid_access_token() const { return !(access_token().empty() || secret().empty()); }

    /// <summary>
    /// Get access token.
    /// </summary>
    /// <returns>The access token string.</returns>
    const utility::string_t& access_token() const { return m_token; }

    /// <summary>
    /// Set access token.
    /// </summary>
    /// <param name="access_token">Access token string to set.</param>
    void set_access_token(utility::string_t &&access_token) { m_token = std::move(access_token); }

    /// <summary>
    /// Set access token.
    /// </summary>
    /// <param name="access_token">Access token string to set.</param>
    void set_access_token(const utility::string_t &access_token) { m_token = access_token; }

    /// <summary>
    /// Get token secret.
    /// </summary>
    /// <returns>Token secret string.</returns>
    const utility::string_t& secret() const { return m_secret; }

    /// <summary>
    /// Set token secret.
    /// </summary>
    /// <param name="secret">Token secret string to set.</param>
    void set_secret(utility::string_t &&secret) { m_secret = std::move(secret); }

    /// <summary>
    /// Set token secret.
    /// </summary>
    /// <param name="secret">Token secret string to set.</param>
    void set_secret(const utility::string_t &secret) { m_secret = secret; }

    /// <summary>
    /// Retrieves any additional parameters.
    /// </summary>
    /// <returns>A map containing the additional parameters.</returns>
    const std::map<utility::string_t, utility::string_t> &additional_parameters() const { return m_additional_parameters; }

    /// <summary>
    /// Sets a specific parameter additional parameter.
    /// </summary>
    /// <param name="paramName">Parameter name.</param>
    /// <param name="paramValue">Parameter value.</param>
    void set_additional_parameter(utility::string_t &&paramName, utility::string_t &&paramValue)
    {
        m_additional_parameters[std::move(paramName)] = std::move(paramValue);
    }

    /// <summary>
    /// Sets a specific parameter additional parameter.
    /// </summary>
    /// <param name="paramName">Parameter name.</param>
    /// <param name="paramValue">Parameter value.</param>
    void set_additional_parameter(const utility::string_t &paramName, const utility::string_t &paramValue)
    {
        m_additional_parameters[paramName] = paramValue;
    }

    /// <summary>
    /// Clears all additional parameters.
    /// </summary>
    void clear_additional_parameters() { m_additional_parameters.clear(); }

private:
    friend class oauth1_config;

    utility::string_t m_token;
    utility::string_t m_secret;
    std::map<utility::string_t, utility::string_t> m_additional_parameters;
};

/// <summary>
/// OAuth 1.0 configuration class.
/// </summary>
class oauth1_config
{
public:
    oauth1_config(utility::string_t consumer_key, utility::string_t consumer_secret,
            utility::string_t temp_endpoint, utility::string_t auth_endpoint,
            utility::string_t token_endpoint, utility::string_t callback_uri,
            oauth1_method method, utility::string_t realm=utility::string_t()) :
        m_consumer_key(std::move(consumer_key)),
        m_consumer_secret(std::move(consumer_secret)),
        m_temp_endpoint(std::move(temp_endpoint)),
        m_auth_endpoint(std::move(auth_endpoint)),
        m_token_endpoint(std::move(token_endpoint)),
        m_callback_uri(std::move(callback_uri)),
        m_realm(std::move(realm)),
        m_method(std::move(method)),
        m_is_authorization_completed(false)
    {}

    /// <summary>
    /// Builds an authorization URI to be loaded in a web browser/view.
    /// The URI is built with auth_endpoint() as basis.
    /// The method creates a task for HTTP request to first obtain a
    /// temporary token. The authorization URI build based on this token.
    /// </summary>
    /// <returns>Authorization URI to be loaded in a web browser/view.</returns>
    _ASYNCRTIMP pplx::task<utility::string_t> build_authorization_uri();

    /// <summary>
    /// Fetch an access token based on redirected URI.
    /// The URI is expected to contain 'oauth_verifier'
    /// parameter, which is then used to fetch an access token using the
    /// token_from_verifier() method.
    /// See: http://tools.ietf.org/html/rfc5849#section-2.2
    /// The received 'oauth_token' is parsed and verified to match the current token().
    /// When access token is successfully obtained, set_token() is called, and config is
    /// ready for use by oauth1_handler.
    /// </summary>
    /// <param name="redirected_uri">The URI where web browser/view was redirected after resource owner's authorization.</param>
    /// <returns>Task that fetches the access token based on redirected URI.</returns>
    _ASYNCRTIMP pplx::task<void> token_from_redirected_uri(const web::http::uri& redirected_uri);

    /// <summary>
    /// Creates a task with HTTP request to fetch an access token from the token endpoint.
    /// The request exchanges a verifier code to an access token.
    /// If successful, the resulting token is set as active via set_token().
    /// See: http://tools.ietf.org/html/rfc5849#section-2.3
    /// </summary>
    /// <param name="verifier">Verifier received via redirect upon successful authorization.</param>
    /// <returns>Task that fetches the access token based on the verifier.</returns>
    pplx::task<void> token_from_verifier(utility::string_t verifier)
    {
        return _request_token(_generate_auth_state(details::oauth1_strings::verifier, std::move(verifier)), false);
    }

    /// <summary>
    /// Creates a task with HTTP request to fetch an access token from the token endpoint.
    /// If successful, the resulting token is set as active via set_token().
    /// </summary>
    /// <returns>Task that fetches the access token based on the verifier.</returns>
    pplx::task<void> refresh_token(const utility::string_t &key)
    {
        return _request_token(_generate_auth_state(key, m_token.additional_parameters().at(key)), false);
    }

    /// <summary>
    /// Get consumer key used in authorization and authentication.
    /// </summary>
    /// <returns>Consumer key string.</returns>
    const utility::string_t& consumer_key() const { return m_consumer_key; }
    /// <summary>
    /// Set consumer key used in authorization and authentication.
    /// </summary>
    /// <param name="key">Consumer key string to set.</param>
    void set_consumer_key(utility::string_t key) { m_consumer_key = std::move(key); }

    /// <summary>
    /// Get consumer secret used in authorization and authentication.
    /// </summary>
    /// <returns>Consumer secret string.</returns>
    const utility::string_t& consumer_secret() const { return m_consumer_secret; }
    /// <summary>
    /// Set consumer secret used in authorization and authentication.
    /// </summary>
    /// <param name="secret">Consumer secret string to set.</param>
    void set_consumer_secret(utility::string_t secret) { m_consumer_secret = std::move(secret); }

    /// <summary>
    /// Get temporary token endpoint URI string.
    /// </summary>
    /// <returns>Temporary token endpoint URI string.</returns>
    const utility::string_t& temp_endpoint() const { return m_temp_endpoint; }
    /// <summary>
    /// Set temporary token endpoint URI string.
    /// </summary>
    /// <param name="temp_endpoint">Temporary token endpoint URI string to set.</param>
    void set_temp_endpoint(utility::string_t temp_endpoint) { m_temp_endpoint = std::move(temp_endpoint); }

    /// <summary>
    /// Get authorization endpoint URI string.
    /// </summary>
    /// <returns>Authorization endpoint URI string.</returns>
    const utility::string_t& auth_endpoint() const { return m_auth_endpoint; }
    /// <summary>
    /// Set authorization endpoint URI string.
    /// </summary>
    /// <param name="auth_endpoint">Authorization endpoint URI string to set.</param>
    void set_auth_endpoint(utility::string_t auth_endpoint) { m_auth_endpoint = std::move(auth_endpoint); }

    /// <summary>
    /// Get token endpoint URI string.
    /// </summary>
    /// <returns>Token endpoint URI string.</returns>
    const utility::string_t& token_endpoint() const { return m_token_endpoint; }
    /// <summary>
    /// Set token endpoint URI string.
    /// </summary>
    /// <param name="token_endpoint">Token endpoint URI string to set.</param>
    void set_token_endpoint(utility::string_t token_endpoint) { m_token_endpoint = std::move(token_endpoint); }

    /// <summary>
    /// Get callback URI string.
    /// </summary>
    /// <returns>Callback URI string.</returns>
    const utility::string_t& callback_uri() const { return m_callback_uri; }
    /// <summary>
    /// Set callback URI string.
    /// </summary>
    /// <param name="callback_uri">Callback URI string to set.</param>
    void set_callback_uri(utility::string_t callback_uri) { m_callback_uri = std::move(callback_uri); }

    /// <summary>
    /// Get token.
    /// </summary>
    /// <returns>Token.</returns>
    _ASYNCRTIMP const oauth1_token& token() const;

    /// <summary>
    /// Set token.
    /// </summary>
    /// <param name="token">Token to set.</param>
    void set_token(oauth1_token token)
    {
        m_token = std::move(token);
        m_is_authorization_completed = true;
    }

    /// <summary>
    /// Get signature method.
    /// </summary>
    /// <returns>Signature method.</returns>
    const oauth1_method& method() const { return m_method; }
    /// <summary>
    /// Set signature method.
    /// </summary>
    /// <param name="method">Signature method.</param>
    void set_method(oauth1_method method) { m_method = std::move(method); }

    /// <summary>
    /// Get authentication realm.
    /// </summary>
    /// <returns>Authentication realm string.</returns>
    const utility::string_t& realm() const { return m_realm; }
    /// <summary>
    /// Set authentication realm.
    /// </summary>
    /// <param name="realm">Authentication realm string to set.</param>
    void set_realm(utility::string_t realm) { m_realm = std::move(realm); }

    /// <summary>
    /// Returns enabled state of the configuration.
    /// The oauth1_handler will perform OAuth 1.0 authentication only if
    /// this method returns true.
    /// Return value is true if access token is valid (=fetched or manually set)
    /// and both consumer_key() and consumer_secret() are set (=non-empty).
    /// </summary>
    /// <returns>The configuration enabled state.</returns>
    bool is_enabled() const { return token().is_valid_access_token() && !(consumer_key().empty() || consumer_secret().empty()); }

    // Builds signature base string according to:
    // http://tools.ietf.org/html/rfc5849#section-3.4.1.1
    _ASYNCRTIMP utility::string_t _build_signature_base_string(http_request request, details::oauth1_state state) const;

    // Builds HMAC-SHA1 signature according to:
    // http://tools.ietf.org/html/rfc5849#section-3.4.2
    utility::string_t _build_hmac_sha1_signature(http_request request, details::oauth1_state state) const
    {
        auto text(_build_signature_base_string(std::move(request), std::move(state)));
        auto digest(_hmac_sha1(_build_key(), std::move(text)));
        auto signature(utility::conversions::to_base64(std::move(digest)));
        return signature;
    }

    // Builds PLAINTEXT signature according to:
    // http://tools.ietf.org/html/rfc5849#section-3.4.4
    utility::string_t _build_plaintext_signature() const
    {
        return _build_key();
    }

    details::oauth1_state _generate_auth_state(utility::string_t extra_key, utility::string_t extra_value)
    {
        return details::oauth1_state(_generate_timestamp(), _generate_nonce(), std::move(extra_key), std::move(extra_value));
    }

    details::oauth1_state _generate_auth_state()
    {
        return details::oauth1_state(_generate_timestamp(), _generate_nonce());
    }

    /// <summary>
    /// Gets map of parameters to sign.
    /// </summary>
    /// <returns>Map of parameters.</returns>
    const std::map<utility::string_t, utility::string_t>& parameters() const { return m_parameters_to_sign; }

    /// <summary>
    /// Adds a key value parameter.
    /// </summary>
    /// <param name="key">Key as a string value.</param>
    /// <param name="value">Value as a string value.</param>
    void add_parameter(const utility::string_t &key, const utility::string_t &value) { m_parameters_to_sign[key] = value; }

    /// <summary>
    /// Adds a key value parameter.
    /// </summary>
    /// <param name="key">Key as a string value.</param>
    /// <param name="value">Value as a string value.</param>
    void add_parameter(utility::string_t &&key, utility::string_t &&value) { m_parameters_to_sign[std::move(key)] = std::move(value); }

    /// <summary>
    /// Sets entire map or parameters replacing all previously values.
    /// </summary>
    /// <param name="parameters">Map of values.</param>
    void set_parameters(const std::map<utility::string_t, utility::string_t> &parameters)
    {
        m_parameters_to_sign.clear();
        m_parameters_to_sign = parameters;
    }

    /// <summary>
    /// Clears all parameters.
    /// </summary>
    void clear_parameters() { m_parameters_to_sign.clear(); }

    /// <summary>
    /// Get the web proxy object
    /// </summary>
    /// <returns>A reference to the web proxy object.</returns>
    const web_proxy& proxy() const
    {
        return m_proxy;
    }

    /// <summary>
    /// Set the web proxy object that will be used by token_from_code and token_from_refresh
    /// </summary>
    /// <param name="proxy">A reference to the web proxy object.</param>
    void set_proxy(const web_proxy& proxy)
    {
        m_proxy = proxy;
    }

private:
    friend class web::http::client::http_client_config;
    friend class web::http::oauth1::details::oauth1_handler;

    oauth1_config() :
        m_is_authorization_completed(false)
    {}

    utility::string_t _generate_nonce()
    {
        return m_nonce_generator.generate();
    }

    static utility::string_t _generate_timestamp()
    {
        return utility::conversions::print_string(utility::datetime::utc_timestamp(), std::locale::classic());
    }

    _ASYNCRTIMP static std::vector<unsigned char> __cdecl _hmac_sha1(const utility::string_t& key, const utility::string_t& data);

    static utility::string_t _build_base_string_uri(const uri& u);

    utility::string_t _build_normalized_parameters(web::http::uri u, const details::oauth1_state& state) const;

    utility::string_t _build_signature(http_request request, details::oauth1_state state) const;

    utility::string_t _build_key() const
    {
        return uri::encode_data_string(consumer_secret()) + _XPLATSTR("&") + uri::encode_data_string(m_token.secret());
    }

    void _authenticate_request(http_request &req)
    {
        _authenticate_request(req, _generate_auth_state());
    }

    _ASYNCRTIMP void _authenticate_request(http_request &req, details::oauth1_state state);

    _ASYNCRTIMP pplx::task<void> _request_token(details::oauth1_state state, bool is_temp_token_request);

    utility::string_t m_consumer_key;
    utility::string_t m_consumer_secret;
    oauth1_token m_token;

    utility::string_t m_temp_endpoint;
    utility::string_t m_auth_endpoint;
    utility::string_t m_token_endpoint;
    utility::string_t m_callback_uri;
    utility::string_t m_realm;
    oauth1_method m_method;

	std::map<utility::string_t, utility::string_t> m_parameters_to_sign;

    web::web_proxy m_proxy;

    utility::nonce_generator m_nonce_generator;
    bool m_is_authorization_completed;
};

} // namespace web::http::oauth1::experimental

namespace details
{

class oauth1_handler : public http_pipeline_stage
{
public:
    oauth1_handler(std::shared_ptr<experimental::oauth1_config> cfg) :
        m_config(std::move(cfg))
    {}

    virtual pplx::task<http_response> propagate(http_request request) override
    {
        if (m_config)
        {
            m_config->_authenticate_request(request);
        }
        return next_stage()->propagate(request);
    }

private:
    std::shared_ptr<experimental::oauth1_config> m_config;
};

}}}}

#endif