018-CVE-2016-0755.patch 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. From d41dcba4e9b69d6b761e3460cc6ae7e8fd8f621f Mon Sep 17 00:00:00 2001
  2. From: Isaac Boukris <iboukris@gmail.com>
  3. Date: Wed, 13 Jan 2016 11:05:51 +0200
  4. Subject: [PATCH] NTLM: Fix ConnectionExists to compare Proxy credentials
  5. Proxy NTLM authentication should compare credentials when
  6. re-using a connection similar to host authentication, as it
  7. authenticate the connection.
  8. Example:
  9. curl -v -x http://proxy:port http://host/ -U good_user:good_pwd
  10. --proxy-ntlm --next -x http://proxy:port http://host/
  11. [-U fake_user:fake_pwd --proxy-ntlm]
  12. CVE-2016-0755
  13. Bug: http://curl.haxx.se/docs/adv_20160127A.html
  14. ---
  15. lib/url.c | 62 ++++++++++++++++++++++++++++++++++++++++----------------------
  16. 1 file changed, 40 insertions(+), 22 deletions(-)
  17. --- a/lib/url.c
  18. +++ b/lib/url.c
  19. @@ -3044,11 +3044,16 @@ ConnectionExists(struct SessionHandle *d
  20. struct connectdata *check;
  21. struct connectdata *chosen = 0;
  22. bool canPipeline = IsPipeliningPossible(data, needle);
  23. - bool wantNTLMhttp = ((data->state.authhost.want & CURLAUTH_NTLM) ||
  24. - (data->state.authhost.want & CURLAUTH_NTLM_WB)) &&
  25. - (needle->handler->protocol & PROTO_FAMILY_HTTP) ? TRUE : FALSE;
  26. struct connectbundle *bundle;
  27. + bool wantNTLMhttp = ((data->state.authhost.want &
  28. + (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
  29. + (needle->handler->protocol & PROTO_FAMILY_HTTP));
  30. + bool wantProxyNTLMhttp = (needle->bits.proxy_user_passwd &&
  31. + ((data->state.authproxy.want &
  32. + (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
  33. + (needle->handler->protocol & PROTO_FAMILY_HTTP)));
  34. +
  35. *force_reuse = FALSE;
  36. /* We can't pipe if the site is blacklisted */
  37. @@ -3077,9 +3082,6 @@ ConnectionExists(struct SessionHandle *d
  38. curr = bundle->conn_list->head;
  39. while(curr) {
  40. bool match = FALSE;
  41. -#if defined(USE_NTLM)
  42. - bool credentialsMatch = FALSE;
  43. -#endif
  44. size_t pipeLen;
  45. /*
  46. @@ -3185,21 +3187,14 @@ ConnectionExists(struct SessionHandle *d
  47. }
  48. if((!(needle->handler->flags & PROTOPT_CREDSPERREQUEST)) ||
  49. -#if defined(USE_NTLM)
  50. - (wantNTLMhttp || check->ntlm.state != NTLMSTATE_NONE)) {
  51. -#else
  52. wantNTLMhttp) {
  53. -#endif
  54. - /* This protocol requires credentials per connection or is HTTP+NTLM,
  55. + /* This protocol requires credentials per connection,
  56. so verify that we're using the same name and password as well */
  57. if(!strequal(needle->user, check->user) ||
  58. !strequal(needle->passwd, check->passwd)) {
  59. /* one of them was different */
  60. continue;
  61. }
  62. -#if defined(USE_NTLM)
  63. - credentialsMatch = TRUE;
  64. -#endif
  65. }
  66. if(!needle->bits.httpproxy || needle->handler->flags&PROTOPT_SSL ||
  67. @@ -3258,20 +3253,43 @@ ConnectionExists(struct SessionHandle *d
  68. possible. (Especially we must not reuse the same connection if
  69. partway through a handshake!) */
  70. if(wantNTLMhttp) {
  71. - if(credentialsMatch && check->ntlm.state != NTLMSTATE_NONE) {
  72. - chosen = check;
  73. + if(!strequal(needle->user, check->user) ||
  74. + !strequal(needle->passwd, check->passwd))
  75. + continue;
  76. + }
  77. + else if(check->ntlm.state != NTLMSTATE_NONE) {
  78. + /* Connection is using NTLM auth but we don't want NTLM */
  79. + continue;
  80. + }
  81. + /* Same for Proxy NTLM authentication */
  82. + if(wantProxyNTLMhttp) {
  83. + if(!strequal(needle->proxyuser, check->proxyuser) ||
  84. + !strequal(needle->proxypasswd, check->proxypasswd))
  85. + continue;
  86. + }
  87. + else if(check->proxyntlm.state != NTLMSTATE_NONE) {
  88. + /* Proxy connection is using NTLM auth but we don't want NTLM */
  89. + continue;
  90. + }
  91. +
  92. + if(wantNTLMhttp || wantProxyNTLMhttp) {
  93. + /* Credentials are already checked, we can use this connection */
  94. + chosen = check;
  95. +
  96. + if((wantNTLMhttp &&
  97. + (check->ntlm.state != NTLMSTATE_NONE)) ||
  98. + (wantProxyNTLMhttp &&
  99. + (check->proxyntlm.state != NTLMSTATE_NONE))) {
  100. /* We must use this connection, no other */
  101. *force_reuse = TRUE;
  102. break;
  103. }
  104. - else if(credentialsMatch)
  105. - /* this is a backup choice */
  106. - chosen = check;
  107. +
  108. + /* Continue look up for a better connection */
  109. continue;
  110. }
  111. #endif
  112. -
  113. if(canPipeline) {
  114. /* We can pipeline if we want to. Let's continue looking for
  115. the optimal connection to use, i.e the shortest pipe that is not