2
Copyright (C) 2010- The University of Notre Dame
3
This software is distributed under the GNU General Public License.
4
See the file COPYING for details.
7
#include <hash_table.h>
14
#include <b64_encode.h>
20
extern char *s3_endpoint;
21
extern char *s3_address;
22
extern int s3_timeout;
24
int s3_getacl(char* bucketname, char* filename, char* owner, struct hash_table* acls, const char* access_key_id, const char* access_key) {
25
struct s3_message mesg;
27
time_t stoptime = time(0)+s3_timeout;
28
char path[HEADER_LINE_MAX];
29
char response[HEADER_LINE_MAX];
35
if(!s3_endpoint) return -1;
36
if(filename) sprintf(path, "%s?acl", filename);
37
else sprintf(path, "/?acl");
39
mesg.type = S3_MESG_GET;
41
mesg.bucket = bucketname;
42
mesg.content_type = NULL;
43
mesg.content_md5 = NULL;
44
mesg.content_length = 0;
47
mesg.amz_headers = NULL;
49
server = link_connect(s3_address, 80, stoptime);
50
if(!server) return -1;
52
sign_message(&mesg, access_key_id, access_key);
53
length = s3_message_to_string(&mesg, &text);
55
link_putlstring(server, text, length, stoptime);
58
link_readline(server, response, HEADER_LINE_MAX, stoptime);
59
if(strcmp(response, "HTTP/1.1 200 OK")) {
60
// Error: transfer failed; close connection and return failure
61
//fprintf(stderr, "Error: request file failed\nResponse: %s\n", response);
67
if(!strncmp(response, "Content-Length:", 14)) sscanf(response, "Content-Length: %d", &length);
68
if(!strcmp(response, "Transfer-Encoding: chunked")) length = 0;
69
if(!strcmp(response, "Server: AmazonS3")) break;
70
} while(link_readline(server, response, HEADER_LINE_MAX, stoptime));
71
link_readline(server, response, HEADER_LINE_MAX, stoptime);
74
text = malloc(length+1);
75
link_read(server, text, length, stoptime);
82
link_readline(server, response, HEADER_LINE_MAX, stoptime);
83
sscanf(response, "%x", &clen);
84
//link_readline(server, response, HEADER_LINE_MAX, stoptime);
86
text = malloc(clen+1);
87
link_read(server, text, clen, stoptime);
88
link_readline(server, response, HEADER_LINE_MAX, stoptime);
89
list_push_tail(buf, text);
93
text = malloc(length+1);
95
while((temp = list_pop_head(buf))) {
96
sprintf(text, "%s%s", text, temp);
103
if(owner) sscanf(strstr(text, "<Owner>"), "<Owner><ID>%[^<]</ID>", owner);
105
while( (start = strstr(temp, "<Grant>")) ) {
107
char display_name[1024];
108
char permission[1024];
110
struct s3_acl_object *acl;
113
end = strstr(start, "</Grant>");
117
memset(display_name, 0, 1024);
119
if( sscanf(start, "<Grant><Grantee %*[^>]><ID>%[^<]</ID><DisplayName>%[^<]</DisplayName></Grantee><Permission>%[^<]</Permission></Grantee>", id, display_name, permission) != 3 ) {
121
sscanf(start, "<Grant><Grantee %*[^>]><URI>http://acs.amazonaws.com/groups/global/%[^<]</URI></Grantee><Permission>%[^<]</Permission></Grantee>", id, permission);
124
if( !(acl = hash_table_lookup(acls, id)) ) {
125
acl = malloc(sizeof(*acl));
126
acl->acl_type = type;
127
if(*display_name) acl->display_name = strdup(display_name);
128
else acl->display_name = NULL;
130
hash_table_insert(acls, id, acl);
133
if(!strcmp(permission, "FULL_CONTROL")) {
134
acl->perm = acl->perm | S3_ACL_FULL_CONTROL;
135
} else if(!strcmp(permission, "READ")) {
136
acl->perm = acl->perm | S3_ACL_READ;
137
} else if(!strcmp(permission, "WRITE")) {
138
acl->perm = acl->perm | S3_ACL_WRITE;
139
} else if(!strcmp(permission, "READ_ACP")) {
140
acl->perm = acl->perm | S3_ACL_READ_ACP;
141
} else if(!strcmp(permission, "WRITE_ACP")) {
142
acl->perm = acl->perm | S3_ACL_WRITE_ACP;
150
// NOT IMPLEMENTED YET
151
int s3_setacl(char* bucketname, char *filename, const char* owner, struct hash_table* acls, const char* access_key_id, const char* access_key) {
152
struct s3_message mesg;
154
time_t stoptime = time(0)+s3_timeout;
155
char path[HEADER_LINE_MAX];
156
char response[HEADER_LINE_MAX];
160
struct s3_acl_object *acl;
162
if(!s3_endpoint) return -1;
163
if(filename) sprintf(path, "%s?acl", filename);
165
sprintf(path, "/?acl");
168
mesg.content_length = 39 + 32 + strlen(owner) + 32;
169
hash_table_firstkey(acls);
170
while(hash_table_nextkey(acls, &id, (void**)&acl)) {
173
switch(acl->acl_type) {
175
glength = 140+strlen(id);
178
glength = 135+strlen(id);
181
glength = 107+strlen(id);
184
if(acl->perm & S3_ACL_FULL_CONTROL) mesg.content_length += 40 + glength + 12;
185
if(acl->perm & S3_ACL_READ) mesg.content_length += 40 + glength + 4;
186
if(acl->perm & S3_ACL_WRITE) mesg.content_length += 40 + glength + 5;
187
if(acl->perm & S3_ACL_READ_ACP) mesg.content_length += 40 + glength + 8;
188
if(acl->perm & S3_ACL_WRITE_ACP) mesg.content_length += 40 + glength + 9;
190
mesg.content_length += 43;
192
mesg.type = S3_MESG_PUT;
194
mesg.bucket = bucketname;
195
mesg.content_type = NULL;
196
mesg.content_md5 = NULL;
199
mesg.amz_headers = NULL;
201
server = link_connect(s3_address, 80, stoptime);
202
if(!server) return -1;
204
sign_message(&mesg, access_key_id, access_key);
205
length = s3_message_to_string(&mesg, &text);
207
fprintf(stderr, "Message:\n%s\n", text);
208
link_putlstring(server, text, length, stoptime);
211
link_putliteral(server, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", stoptime);
212
link_putliteral(server, "<AccessControlPolicy><Owner><ID>", stoptime);
213
link_putstring(server, owner, stoptime);
214
link_putliteral(server, "</ID></Owner><AccessControlList>", stoptime);
216
hash_table_firstkey(acls);
217
while(hash_table_nextkey(acls, &id, (void**)&acl)) {
218
char grantee[HEADER_LINE_MAX];
220
switch(acl->acl_type) {
222
sprintf(grantee, "<Grantee xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"Group\"><URI>http://acs.amazonaws.com/groups/global/%s</URI></Grantee>", id);
225
sprintf(grantee, "<Grantee xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"AmazonCustomerByEmail\"><EmailAddress>%s</EmailAddress></Grantee>", id);
228
sprintf(grantee, "<Grantee xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"CanonicalUser\"><ID>%s</ID></Grantee>", id);
231
if(acl->perm & S3_ACL_FULL_CONTROL) {
232
link_putfstring(server, "<Grant>%s<Permission>FULL_CONTROL</Permission></Grant>", stoptime, grantee);
234
if(acl->perm & S3_ACL_READ) {
235
link_putfstring(server, "<Grant>%s<Permission>READ</Permission></Grant>", stoptime, grantee);
237
if(acl->perm & S3_ACL_WRITE) {
238
link_putfstring(server, "<Grant>%s<Permission>WRITE</Permission></Grant>", stoptime, grantee);
240
if(acl->perm & S3_ACL_READ_ACP) {
241
link_putfstring(server, "<Grant>%s<Permission>READ_ACP</Permission></Grant>", stoptime, grantee);
243
if(acl->perm & S3_ACL_WRITE_ACP) {
244
link_putfstring(server, "<Grant>%s<Permission>WRITE_ACP</Permission></Grant>", stoptime, grantee);
248
link_putliteral(server, "</AccessControlList></AccessControlPolicy>\n", stoptime);
250
link_readline(server, response, HEADER_LINE_MAX, stoptime);
251
if(strcmp(response, "HTTP/1.1 200 OK")) {
252
// Error: transfer failed; close connection and return failure
253
fprintf(stderr, "Error: send file failed\nResponse: %s\n", response);
258
// fprintf(stderr, "Response:\n");
260
// fprintf(stderr, "\t%s\n", response);
261
if(!strcmp(response, "Server: AmazonS3")) break;
262
} while(link_readline(server, response, HEADER_LINE_MAX, stoptime));