~ubuntu-branches/ubuntu/vivid/cctools/vivid

« back to all changes in this revision

Viewing changes to s3tools/src/s3c_acl.c

  • Committer: Bazaar Package Importer
  • Author(s): Michael Hanke
  • Date: 2011-05-07 09:05:00 UTC
  • Revision ID: james.westby@ubuntu.com-20110507090500-lqpmdtwndor6e7os
Tags: upstream-3.3.2
ImportĀ upstreamĀ versionĀ 3.3.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
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.
 
5
*/
 
6
#include <list.h>
 
7
#include <hash_table.h>
 
8
#include <link.h>
 
9
#include <stdlib.h>
 
10
#include <stdio.h>
 
11
#include <string.h>
 
12
#include <hmac.h>
 
13
#include <math.h>
 
14
#include <b64_encode.h>
 
15
#include <sys/stat.h>
 
16
 
 
17
#include "s3c_util.h"
 
18
#include "s3c_acl.h"
 
19
 
 
20
extern char *s3_endpoint;
 
21
extern char *s3_address;
 
22
extern int s3_timeout;
 
23
 
 
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;
 
26
        struct link* server;
 
27
        time_t stoptime = time(0)+s3_timeout;
 
28
        char path[HEADER_LINE_MAX];
 
29
        char response[HEADER_LINE_MAX];
 
30
        char * text;
 
31
        char * start;
 
32
        char * temp;
 
33
        int length;
 
34
 
 
35
        if(!s3_endpoint) return -1;
 
36
        if(filename) sprintf(path, "%s?acl", filename);
 
37
        else sprintf(path, "/?acl");
 
38
 
 
39
        mesg.type = S3_MESG_GET;
 
40
        mesg.path = path;
 
41
        mesg.bucket = bucketname;
 
42
        mesg.content_type = NULL;
 
43
        mesg.content_md5 = NULL;
 
44
        mesg.content_length = 0;
 
45
        mesg.date = time(0);
 
46
        mesg.expect = 0;
 
47
        mesg.amz_headers = NULL;
 
48
 
 
49
        server = link_connect(s3_address, 80, stoptime);
 
50
        if(!server) return -1;
 
51
 
 
52
        sign_message(&mesg, access_key_id, access_key);
 
53
        length = s3_message_to_string(&mesg, &text);
 
54
 
 
55
        link_putlstring(server, text, length, stoptime);
 
56
        free(text);
 
57
 
 
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);
 
62
                link_close(server);
 
63
                return -1;
 
64
        }
 
65
 
 
66
        do {
 
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);
 
72
 
 
73
        if(length) {
 
74
                text = malloc(length+1);
 
75
                link_read(server, text, length, stoptime);
 
76
        } else {
 
77
                struct list *buf;
 
78
                char *temp;
 
79
                int clen = 0;
 
80
                buf = list_create();
 
81
                do {
 
82
                        link_readline(server, response, HEADER_LINE_MAX, stoptime);
 
83
                        sscanf(response, "%x", &clen);
 
84
                        //link_readline(server, response, HEADER_LINE_MAX, stoptime);
 
85
                        if(clen) {
 
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);
 
90
                                length += clen;
 
91
                        }
 
92
                } while(clen);
 
93
                text = malloc(length+1);
 
94
                text[0] = '\0';
 
95
                while((temp = list_pop_head(buf))) {
 
96
                        sprintf(text, "%s%s", text, temp);
 
97
                        free(temp);
 
98
                }
 
99
                list_delete(buf);
 
100
        }
 
101
        link_close(server);
 
102
 
 
103
        if(owner) sscanf(strstr(text, "<Owner>"), "<Owner><ID>%[^<]</ID>", owner);
 
104
        temp = text;
 
105
        while( (start = strstr(temp, "<Grant>")) ) {
 
106
                char id[1024];
 
107
                char display_name[1024];
 
108
                char permission[1024];
 
109
                char type;
 
110
                struct s3_acl_object *acl;
 
111
                char *end;
 
112
 
 
113
                end = strstr(start, "</Grant>");
 
114
                end[7] = '\0';
 
115
                temp = end + 8;
 
116
 
 
117
                memset(display_name, 0, 1024);
 
118
                type = S3_ACL_ID;
 
119
                if( sscanf(start, "<Grant><Grantee %*[^>]><ID>%[^<]</ID><DisplayName>%[^<]</DisplayName></Grantee><Permission>%[^<]</Permission></Grantee>", id, display_name, permission) != 3 ) {
 
120
                        type = S3_ACL_URI;
 
121
                        sscanf(start, "<Grant><Grantee %*[^>]><URI>http://acs.amazonaws.com/groups/global/%[^<]</URI></Grantee><Permission>%[^<]</Permission></Grantee>", id, permission);
 
122
                }
 
123
 
 
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;
 
129
                        acl->perm = 0;
 
130
                        hash_table_insert(acls, id, acl);
 
131
                }
 
132
 
 
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;
 
143
                }
 
144
        }
 
145
 
 
146
        free(text);
 
147
        return 0;
 
148
}
 
149
 
 
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;
 
153
        struct link* server;
 
154
        time_t stoptime = time(0)+s3_timeout;
 
155
        char path[HEADER_LINE_MAX];
 
156
        char response[HEADER_LINE_MAX];
 
157
        char * text;
 
158
        int length;
 
159
        char *id;
 
160
        struct s3_acl_object *acl;
 
161
 
 
162
        if(!s3_endpoint) return -1;
 
163
        if(filename) sprintf(path, "%s?acl", filename);
 
164
        else
 
165
        sprintf(path, "/?acl");
 
166
 
 
167
 
 
168
        mesg.content_length = 39 + 32 + strlen(owner) + 32;
 
169
        hash_table_firstkey(acls);
 
170
        while(hash_table_nextkey(acls, &id, (void**)&acl)) {
 
171
                int glength;
 
172
 
 
173
                switch(acl->acl_type) {
 
174
                        case S3_ACL_URI:
 
175
                                glength = 140+strlen(id);
 
176
                                break;
 
177
                        case S3_ACL_EMAIL:
 
178
                                glength = 135+strlen(id);
 
179
                                break;
 
180
                        default:
 
181
                                glength = 107+strlen(id);
 
182
                }
 
183
 
 
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;
 
189
        }
 
190
        mesg.content_length += 43;
 
191
 
 
192
        mesg.type = S3_MESG_PUT;
 
193
        mesg.path = path;
 
194
        mesg.bucket = bucketname;
 
195
        mesg.content_type = NULL;
 
196
        mesg.content_md5 = NULL;
 
197
        mesg.date = time(0);
 
198
        mesg.expect = 0;
 
199
        mesg.amz_headers = NULL;
 
200
 
 
201
        server = link_connect(s3_address, 80, stoptime);
 
202
        if(!server) return -1;
 
203
 
 
204
        sign_message(&mesg, access_key_id, access_key);
 
205
        length = s3_message_to_string(&mesg, &text);
 
206
 
 
207
        fprintf(stderr, "Message:\n%s\n", text);
 
208
        link_putlstring(server, text, length, stoptime);
 
209
        free(text);
 
210
 
 
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);
 
215
 
 
216
        hash_table_firstkey(acls);
 
217
        while(hash_table_nextkey(acls, &id, (void**)&acl)) {
 
218
                char grantee[HEADER_LINE_MAX];
 
219
 
 
220
                switch(acl->acl_type) {
 
221
                        case S3_ACL_URI:
 
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);
 
223
                                break;
 
224
                        case S3_ACL_EMAIL:
 
225
                                sprintf(grantee, "<Grantee xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"AmazonCustomerByEmail\"><EmailAddress>%s</EmailAddress></Grantee>", id);
 
226
                                break;
 
227
                        default:
 
228
                                sprintf(grantee, "<Grantee xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"CanonicalUser\"><ID>%s</ID></Grantee>", id);
 
229
                }
 
230
 
 
231
                if(acl->perm & S3_ACL_FULL_CONTROL) {
 
232
                        link_putfstring(server, "<Grant>%s<Permission>FULL_CONTROL</Permission></Grant>", stoptime, grantee);
 
233
                }
 
234
                if(acl->perm & S3_ACL_READ) {
 
235
                        link_putfstring(server, "<Grant>%s<Permission>READ</Permission></Grant>", stoptime, grantee);
 
236
                }
 
237
                if(acl->perm & S3_ACL_WRITE) {
 
238
                        link_putfstring(server, "<Grant>%s<Permission>WRITE</Permission></Grant>", stoptime, grantee);
 
239
                }
 
240
                if(acl->perm & S3_ACL_READ_ACP) {
 
241
                        link_putfstring(server, "<Grant>%s<Permission>READ_ACP</Permission></Grant>", stoptime, grantee);
 
242
                }
 
243
                if(acl->perm & S3_ACL_WRITE_ACP) {
 
244
                        link_putfstring(server, "<Grant>%s<Permission>WRITE_ACP</Permission></Grant>", stoptime, grantee);
 
245
                }
 
246
        }
 
247
 
 
248
        link_putliteral(server, "</AccessControlList></AccessControlPolicy>\n", stoptime);
 
249
 
 
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);
 
254
                link_close(server);
 
255
                return -1;
 
256
        }
 
257
 
 
258
//      fprintf(stderr, "Response:\n");
 
259
        do {
 
260
//              fprintf(stderr, "\t%s\n", response);
 
261
                if(!strcmp(response, "Server: AmazonS3")) break;
 
262
        } while(link_readline(server, response, HEADER_LINE_MAX, stoptime));
 
263
 
 
264
        link_close(server);
 
265
 
 
266
        return 0;
 
267
}
 
268