1<?php 2 3namespace Sabre\HTTP\Auth; 4 5use Sabre\HTTP\Request; 6use Sabre\HTTP\Response; 7 8class AWSTest extends \PHPUnit_Framework_TestCase { 9 10 /** 11 * @var Sabre\HTTP\Response 12 */ 13 private $response; 14 15 /** 16 * @var Sabre\HTTP\Request 17 */ 18 private $request; 19 20 /** 21 * @var Sabre\HTTP\Auth\AWS 22 */ 23 private $auth; 24 25 const REALM = 'SabreDAV unittest'; 26 27 function setUp() { 28 29 $this->response = new Response(); 30 $this->request = new Request(); 31 $this->auth = new AWS(self::REALM, $this->request, $this->response); 32 33 } 34 35 function testNoHeader() { 36 37 $this->request->setMethod('GET'); 38 $result = $this->auth->init(); 39 40 $this->assertFalse($result, 'No AWS Authorization header was supplied, so we should have gotten false'); 41 $this->assertEquals(AWS::ERR_NOAWSHEADER, $this->auth->errorCode); 42 43 } 44 45 function testIncorrectContentMD5() { 46 47 $accessKey = 'accessKey'; 48 $secretKey = 'secretKey'; 49 50 $this->request->setMethod('GET'); 51 $this->request->setHeaders([ 52 'Authorization' => "AWS $accessKey:sig", 53 'Content-MD5' => 'garbage', 54 ]); 55 $this->request->setUrl('/'); 56 57 $this->auth->init(); 58 $result = $this->auth->validate($secretKey); 59 60 $this->assertFalse($result); 61 $this->assertEquals(AWS::ERR_MD5CHECKSUMWRONG, $this->auth->errorCode); 62 63 } 64 65 function testNoDate() { 66 67 $accessKey = 'accessKey'; 68 $secretKey = 'secretKey'; 69 $content = 'thisisthebody'; 70 $contentMD5 = base64_encode(md5($content, true)); 71 72 $this->request->setMethod('POST'); 73 $this->request->setHeaders([ 74 'Authorization' => "AWS $accessKey:sig", 75 'Content-MD5' => $contentMD5, 76 ]); 77 $this->request->setUrl('/'); 78 $this->request->setBody($content); 79 80 $this->auth->init(); 81 $result = $this->auth->validate($secretKey); 82 83 $this->assertFalse($result); 84 $this->assertEquals(AWS::ERR_INVALIDDATEFORMAT, $this->auth->errorCode); 85 86 } 87 88 function testFutureDate() { 89 90 $accessKey = 'accessKey'; 91 $secretKey = 'secretKey'; 92 $content = 'thisisthebody'; 93 $contentMD5 = base64_encode(md5($content, true)); 94 95 $date = new \DateTime('@' . (time() + (60 * 20))); 96 $date->setTimeZone(new \DateTimeZone('GMT')); 97 $date = $date->format('D, d M Y H:i:s \\G\\M\\T'); 98 99 $this->request->setMethod('POST'); 100 $this->request->setHeaders([ 101 'Authorization' => "AWS $accessKey:sig", 102 'Content-MD5' => $contentMD5, 103 'Date' => $date, 104 ]); 105 106 $this->request->setBody($content); 107 108 $this->auth->init(); 109 $result = $this->auth->validate($secretKey); 110 111 $this->assertFalse($result); 112 $this->assertEquals(AWS::ERR_REQUESTTIMESKEWED, $this->auth->errorCode); 113 114 } 115 116 function testPastDate() { 117 118 $accessKey = 'accessKey'; 119 $secretKey = 'secretKey'; 120 $content = 'thisisthebody'; 121 $contentMD5 = base64_encode(md5($content, true)); 122 123 $date = new \DateTime('@' . (time() - (60 * 20))); 124 $date->setTimeZone(new \DateTimeZone('GMT')); 125 $date = $date->format('D, d M Y H:i:s \\G\\M\\T'); 126 127 $this->request->setMethod('POST'); 128 $this->request->setHeaders([ 129 'Authorization' => "AWS $accessKey:sig", 130 'Content-MD5' => $contentMD5, 131 'Date' => $date, 132 ]); 133 134 $this->request->setBody($content); 135 136 $this->auth->init(); 137 $result = $this->auth->validate($secretKey); 138 139 $this->assertFalse($result); 140 $this->assertEquals(AWS::ERR_REQUESTTIMESKEWED, $this->auth->errorCode); 141 142 } 143 144 function testIncorrectSignature() { 145 146 $accessKey = 'accessKey'; 147 $secretKey = 'secretKey'; 148 $content = 'thisisthebody'; 149 150 $contentMD5 = base64_encode(md5($content, true)); 151 152 $date = new \DateTime('now'); 153 $date->setTimeZone(new \DateTimeZone('GMT')); 154 $date = $date->format('D, d M Y H:i:s \\G\\M\\T'); 155 156 $this->request->setUrl('/'); 157 $this->request->setMethod('POST'); 158 $this->request->setHeaders([ 159 'Authorization' => "AWS $accessKey:sig", 160 'Content-MD5' => $contentMD5, 161 'X-amz-date' => $date, 162 ]); 163 $this->request->setBody($content); 164 165 $this->request->setBody($content); 166 167 $this->auth->init(); 168 $result = $this->auth->validate($secretKey); 169 170 $this->assertFalse($result); 171 $this->assertEquals(AWS::ERR_INVALIDSIGNATURE, $this->auth->errorCode); 172 173 } 174 175 function testValidRequest() { 176 177 $accessKey = 'accessKey'; 178 $secretKey = 'secretKey'; 179 $content = 'thisisthebody'; 180 $contentMD5 = base64_encode(md5($content, true)); 181 182 $date = new \DateTime('now'); 183 $date->setTimeZone(new \DateTimeZone('GMT')); 184 $date = $date->format('D, d M Y H:i:s \\G\\M\\T'); 185 186 187 $sig = base64_encode($this->hmacsha1($secretKey, 188 "POST\n$contentMD5\n\n$date\nx-amz-date:$date\n/evert" 189 )); 190 191 $this->request->setUrl('/evert'); 192 $this->request->setMethod('POST'); 193 $this->request->setHeaders([ 194 'Authorization' => "AWS $accessKey:$sig", 195 'Content-MD5' => $contentMD5, 196 'X-amz-date' => $date, 197 ]); 198 199 $this->request->setBody($content); 200 201 $this->auth->init(); 202 $result = $this->auth->validate($secretKey); 203 204 $this->assertTrue($result, 'Signature did not validate, got errorcode ' . $this->auth->errorCode); 205 $this->assertEquals($accessKey, $this->auth->getAccessKey()); 206 207 } 208 209 function test401() { 210 211 $this->auth->requireLogin(); 212 $test = preg_match('/^AWS$/', $this->response->getHeader('WWW-Authenticate'), $matches); 213 $this->assertTrue($test == true, 'The WWW-Authenticate response didn\'t match our pattern'); 214 215 } 216 217 /** 218 * Generates an HMAC-SHA1 signature 219 * 220 * @param string $key 221 * @param string $message 222 * @return string 223 */ 224 private function hmacsha1($key, $message) { 225 226 $blocksize = 64; 227 if (strlen($key) > $blocksize) 228 $key = pack('H*', sha1($key)); 229 $key = str_pad($key, $blocksize, chr(0x00)); 230 $ipad = str_repeat(chr(0x36), $blocksize); 231 $opad = str_repeat(chr(0x5c), $blocksize); 232 $hmac = pack('H*', sha1(($key ^ $opad) . pack('H*', sha1(($key ^ $ipad) . $message)))); 233 return $hmac; 234 235 } 236 237} 238