int crypto_sign(unsigned char *sm,unsigned long long *smlen, const unsigned char *m,unsigned long long mlen, const unsigned char *sk){ /* ... the code for your Square2048 implementation goes here, ... generating a signed message sm[0],sm[1],...,sm[*smlen-1] ... from original message m[0],m[1],...,m[mlen-1] ... under secret key sk[0],sk[1],... */ struct PublicParameter PP = {PUBLIC_PARAMETER_N, PUBLIC_PARAMETER_M,PUBLIC_PARAMETER_SIGMA,PUBLIC_PARAMETER_K}; unsigned long long length; NTL::ZZ prime_number; prime_number = NTL::ZZFromBytes(sk, BYTES_PRIMENUMBER); initialize_ZZ_pE(prime_number, PUBLIC_PARAMETER_N); // initialize ZZ_pE and ZZ_p NTL::ZZ_pE hash_polynomial[PUBLIC_PARAMETER_M]; NTL::ZZ_pE sk_ZZ_pE[PUBLIC_PARAMETER_M]; convert_char_array_to_ZZ_pE_array(hash_polynomial, (unsigned char*)&sk[BYTES_PRIMENUMBER], BYTES_HASHFUNCTION, PUBLIC_PARAMETER_M,PUBLIC_PARAMETER_N); convert_char_array_to_ZZ_pE_array(sk_ZZ_pE, (unsigned char*)&sk[BYTES_PRIMENUMBER+BYTES_HASHFUNCTION],BYTES_SECRETKEY,PUBLIC_PARAMETER_M,PUBLIC_PARAMETER_N); NTL::ZZ_pE sign_e; NTL::ZZ_pE sign_z[PUBLIC_PARAMETER_M]; sign_message(PP, (unsigned char*) m, mlen, sk_ZZ_pE, hash_polynomial, &sign_e, sign_z); /* copy message and signature */ *smlen = mlen + BYTES_SIGNATUR_E + BYTES_SIGNATUR_Z; strncpy((char *)sm, (const char*)m, mlen); convert_ZZ_pE_array_to_char_array(sign_z,PP.m, &length, sm+mlen); convert_ZZ_pE_array_to_char_array(&sign_e, 1, &length, sm+mlen+BYTES_SIGNATUR_Z); return 0; }
int s3_mk_bucket(char* bucketname, enum amz_base_perm perms, const char* access_key_id, const char* access_key) { struct link* server; char path[] = "/"; struct s3_header_object *head; time_t stoptime = time(0)+s3_timeout; struct s3_message mesg; char response[HEADER_LINE_MAX]; if(!access_key_id || !access_key || !s3_endpoint) return -1; mesg.type = S3_MESG_PUT; mesg.path = path; mesg.bucket = bucketname; mesg.content_length = 0; mesg.content_type = NULL; mesg.content_md5 = NULL; mesg.date = time(0); mesg.expect = 0; switch(perms) { case AMZ_PERM_PRIVATE: head = s3_new_header_object(S3_HEADER_AMZ_ACL, NULL, "private"); break; case AMZ_PERM_PUBLIC_READ: head = s3_new_header_object(S3_HEADER_AMZ_ACL, NULL, "public-read"); break; case AMZ_PERM_PUBLIC_WRITE: head = s3_new_header_object(S3_HEADER_AMZ_ACL, NULL, "public-read-write"); break; case AMZ_PERM_AUTH_READ: head = s3_new_header_object(S3_HEADER_AMZ_ACL, NULL, "authenticated-read"); break; case AMZ_PERM_BUCKET_READ: head = s3_new_header_object(S3_HEADER_AMZ_ACL, NULL, "bucket-owner-read"); break; case AMZ_PERM_BUCKET_FULL: head = s3_new_header_object(S3_HEADER_AMZ_ACL, NULL, "bucket-owner-full-control"); break; default: return -1; } mesg.amz_headers = list_create(); list_push_tail(mesg.amz_headers, head); sign_message(&mesg, access_key_id, access_key); server = s3_send_message(&mesg, NULL, stoptime); list_free(mesg.amz_headers); list_delete(mesg.amz_headers); if(!server) return -1; link_readline(server, response, HEADER_LINE_MAX, stoptime); if(strcmp(response, "HTTP/1.1 200 OK")) { // Error: transfer failed; close connection and return failure //fprintf(stderr, "Error: create bucket failed\nResponse: %s\n", response); link_close(server); return -1; } do { if(!strcmp(response, "Server: AmazonS3")) break; } while(link_readline(server, response, HEADER_LINE_MAX, stoptime)); link_close(server); return 0; }
int s3_rm_bucket(char* bucketname, const char* access_key_id, const char* access_key) { struct s3_message mesg; struct link* server; time_t stoptime = time(0)+s3_timeout; char response[HEADER_LINE_MAX]; char path[] = "/"; if(!access_key_id || !access_key || !s3_endpoint) return -1; mesg.type = S3_MESG_DELETE; mesg.path = path; mesg.bucket = bucketname; mesg.content_type = NULL; mesg.content_md5 = NULL; mesg.content_length = 0; mesg.date = time(0); mesg.expect = 0; mesg.amz_headers = NULL; sign_message(&mesg, access_key_id, access_key); server = s3_send_message(&mesg, NULL, stoptime); if(!server) return -1; link_readline(server, response, HEADER_LINE_MAX, stoptime); if(strcmp(response, "HTTP/1.1 204 No Content")) { // Error: transfer failed; close connection and return failure //fprintf(stderr, "Error: delete bucket failed\nResponse: %s\n", response); link_close(server); return -1; } do { if(!strcmp(response, "Server: AmazonS3")) break; } while(link_readline(server, response, HEADER_LINE_MAX, stoptime)); link_close(server); return 0; }
static void *worker_loop(void *ignored) { bool keep_running = true; while(keep_running) { brine_task_s *task = (brine_task_s *) brine_queue_dequeue(queue); if (!task) { keep_running = false; break; } switch(task->cmd) { case BRINE_STOP: keep_running = false; break; case BRINE_NEW_KEYPAIR: generate_keypair(task); break; case BRINE_NEW_KEYPAIR_FROM_SEED: generate_keypair_from_seed(task); break; case BRINE_SIGN_MSG: sign_message(task); break; case BRINE_VERIFY: verify_signature(task); break; case BRINE_TO_BINARY: keypair_to_binary(task); break; case BRINE_TO_KEYPAIR: binary_to_keypair(task); break; default: break; } brine_task_destroy(&task); } return NULL; }
int s3_getacl(char* bucketname, char* filename, char* owner, struct hash_table* acls, const char* access_key_id, const char* access_key) { struct s3_message mesg; struct link* server; time_t stoptime = time(0)+s3_timeout; char path[HEADER_LINE_MAX]; char response[HEADER_LINE_MAX]; char * text; char * start; char * temp; int length; if(!s3_endpoint) return -1; if(filename) sprintf(path, "%s?acl", filename); else sprintf(path, "/?acl"); mesg.type = S3_MESG_GET; mesg.path = path; mesg.bucket = bucketname; mesg.content_type = NULL; mesg.content_md5 = NULL; mesg.content_length = 0; mesg.date = time(0); mesg.expect = 0; mesg.amz_headers = NULL; //server = link_connect(s3_address, 80, stoptime); sign_message(&mesg, access_key_id, access_key); server = s3_send_message(&mesg, NULL, stoptime); if(!server) return -1; //length = s3_message_to_string(&mesg, &text); //link_putlstring(server, text, length, stoptime); //free(text); link_readline(server, response, HEADER_LINE_MAX, stoptime); if(strcmp(response, "HTTP/1.1 200 OK")) { // Error: transfer failed; close connection and return failure //fprintf(stderr, "Error: request file failed\nResponse: %s\n", response); link_close(server); return -1; } do { if(!strncmp(response, "Content-Length:", 14)) sscanf(response, "Content-Length: %d", &length); if(!strcmp(response, "Transfer-Encoding: chunked")) length = 0; if(!strcmp(response, "Server: AmazonS3")) break; } while(link_readline(server, response, HEADER_LINE_MAX, stoptime)); link_readline(server, response, HEADER_LINE_MAX, stoptime); if(length) { text = malloc(length+1); link_read(server, text, length, stoptime); } else { struct list *buf; char *temp; unsigned int clen = 0; buf = list_create(); do { link_readline(server, response, HEADER_LINE_MAX, stoptime); sscanf(response, "%x", &clen); //link_readline(server, response, HEADER_LINE_MAX, stoptime); if(clen) { text = malloc(clen+1); link_read(server, text, clen, stoptime); link_readline(server, response, HEADER_LINE_MAX, stoptime); list_push_tail(buf, text); length += clen; } } while(clen); text = malloc(length+1); text[0] = '\0'; while((temp = list_pop_head(buf))) { sprintf(text, "%s%s", text, temp); free(temp); } list_delete(buf); } link_close(server); if(owner) sscanf(strstr(text, "<Owner>"), "<Owner><ID>%[^<]</ID>", owner); temp = text; while( (start = strstr(temp, "<Grant>")) ) { char id[1024]; char display_name[1024]; char permission[1024]; char type; struct s3_acl_object *acl; char *end; end = strstr(start, "</Grant>"); end[7] = '\0'; temp = end + 8; memset(display_name, 0, 1024); type = S3_ACL_ID; if( sscanf(start, "<Grant><Grantee %*[^>]><ID>%[^<]</ID><DisplayName>%[^<]</DisplayName></Grantee><Permission>%[^<]</Permission></Grantee>", id, display_name, permission) != 3 ) { type = S3_ACL_URI; sscanf(start, "<Grant><Grantee %*[^>]><URI>http://acs.amazonaws.com/groups/global/%[^<]</URI></Grantee><Permission>%[^<]</Permission></Grantee>", id, permission); } if( !(acl = hash_table_lookup(acls, id)) ) { acl = malloc(sizeof(*acl)); acl->acl_type = type; if(*display_name) acl->display_name = strdup(display_name); else acl->display_name = NULL; acl->perm = 0; hash_table_insert(acls, id, acl); } if(!strcmp(permission, "FULL_CONTROL")) { acl->perm = acl->perm | S3_ACL_FULL_CONTROL; } else if(!strcmp(permission, "READ")) { acl->perm = acl->perm | S3_ACL_READ; } else if(!strcmp(permission, "WRITE")) { acl->perm = acl->perm | S3_ACL_WRITE; } else if(!strcmp(permission, "READ_ACP")) { acl->perm = acl->perm | S3_ACL_READ_ACP; } else if(!strcmp(permission, "WRITE_ACP")) { acl->perm = acl->perm | S3_ACL_WRITE_ACP; } } free(text); return 0; }
// NOT IMPLEMENTED YET int s3_setacl(char* bucketname, char *filename, const char* owner, struct hash_table* acls, const char* access_key_id, const char* access_key) { struct s3_message mesg; struct link* server; time_t stoptime = time(0)+s3_timeout; char path[HEADER_LINE_MAX]; char response[HEADER_LINE_MAX]; //char * text; //int length; char *id; struct s3_acl_object *acl; if(!s3_endpoint) return -1; if(filename) sprintf(path, "%s?acl", filename); else sprintf(path, "/?acl"); mesg.content_length = 39 + 32 + strlen(owner) + 32; hash_table_firstkey(acls); while(hash_table_nextkey(acls, &id, (void**)&acl)) { int glength; switch(acl->acl_type) { case S3_ACL_URI: glength = 140+strlen(id); break; case S3_ACL_EMAIL: glength = 135+strlen(id); break; default: glength = 107+strlen(id); } if(acl->perm & S3_ACL_FULL_CONTROL) mesg.content_length += 40 + glength + 12; if(acl->perm & S3_ACL_READ) mesg.content_length += 40 + glength + 4; if(acl->perm & S3_ACL_WRITE) mesg.content_length += 40 + glength + 5; if(acl->perm & S3_ACL_READ_ACP) mesg.content_length += 40 + glength + 8; if(acl->perm & S3_ACL_WRITE_ACP) mesg.content_length += 40 + glength + 9; } mesg.content_length += 43; mesg.type = S3_MESG_PUT; mesg.path = path; mesg.bucket = bucketname; mesg.content_type = NULL; mesg.content_md5 = NULL; mesg.date = time(0); mesg.expect = 0; mesg.amz_headers = NULL; //server = link_connect(s3_address, 80, stoptime); sign_message(&mesg, access_key_id, access_key); server = s3_send_message(&mesg, NULL, stoptime); if(!server) return -1; //length = s3_message_to_string(&mesg, &text); //fprintf(stderr, "Message:\n%s\n", text); //link_putlstring(server, text, length, stoptime); //free(text); link_putliteral(server, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", stoptime); link_putliteral(server, "<AccessControlPolicy><Owner><ID>", stoptime); link_putstring(server, owner, stoptime); link_putliteral(server, "</ID></Owner><AccessControlList>", stoptime); hash_table_firstkey(acls); while(hash_table_nextkey(acls, &id, (void**)&acl)) { char grantee[HEADER_LINE_MAX]; switch(acl->acl_type) { case S3_ACL_URI: 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); break; case S3_ACL_EMAIL: sprintf(grantee, "<Grantee xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"AmazonCustomerByEmail\"><EmailAddress>%s</EmailAddress></Grantee>", id); break; default: sprintf(grantee, "<Grantee xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:type=\"CanonicalUser\"><ID>%s</ID></Grantee>", id); } if(acl->perm & S3_ACL_FULL_CONTROL) { link_putfstring(server, "<Grant>%s<Permission>FULL_CONTROL</Permission></Grant>", stoptime, grantee); } if(acl->perm & S3_ACL_READ) { link_putfstring(server, "<Grant>%s<Permission>READ</Permission></Grant>", stoptime, grantee); } if(acl->perm & S3_ACL_WRITE) { link_putfstring(server, "<Grant>%s<Permission>WRITE</Permission></Grant>", stoptime, grantee); } if(acl->perm & S3_ACL_READ_ACP) { link_putfstring(server, "<Grant>%s<Permission>READ_ACP</Permission></Grant>", stoptime, grantee); } if(acl->perm & S3_ACL_WRITE_ACP) { link_putfstring(server, "<Grant>%s<Permission>WRITE_ACP</Permission></Grant>", stoptime, grantee); } } link_putliteral(server, "</AccessControlList></AccessControlPolicy>\n", stoptime); link_readline(server, response, HEADER_LINE_MAX, stoptime); if(strcmp(response, "HTTP/1.1 200 OK")) { // Error: transfer failed; close connection and return failure fprintf(stderr, "Error: send file failed\nResponse: %s\n", response); link_close(server); return -1; } // fprintf(stderr, "Response:\n"); do { // fprintf(stderr, "\t%s\n", response); if(!strcmp(response, "Server: AmazonS3")) break; } while(link_readline(server, response, HEADER_LINE_MAX, stoptime)); link_close(server); return 0; }
/* accept and process request form local client */ void process_client_request(int fd_un2) { int len, len_toreceive, len_received, len_tosend, len_sent; int rc, fd_in = 0; CLI_REQUEST creq; CLI_RESPONSE cresp; SRV_REQUEST sreq; SRV_RESPONSE sresp; SRV_MESSAGE smsg; char buf[2048]; char keyid[MAX_TAG_LEN + MAX_HOST_LEN + 10]; BIGNUM *bn_base = NULL, *bn_prime = NULL, *bn_private = NULL; unsigned char* public = NULL; int public_len; unsigned char* secret_key = NULL; int secret_key_len; memset(&cresp, 0, sizeof(cresp)); memset(&sreq, 0, sizeof(sreq)); memset(&smsg, 0, sizeof(smsg)); /* receive request - we can expect at least 7 first bytes to receive */ len = recv(fd_un2, buf, 7, 0); if (len < 0) { output(LOG_ERR, "recv failed. %s", strerror(errno)); cresp.status = MK_STATUS(SCOPE_HOST, ERR_COMM); goto send; } else if (!len) return; len_received = len; len_toreceive = get_der_seq_size(buf); if (len_toreceive > sizeof(buf)) { output(LOG_ERR, "packet sent by client is too big"); cresp.status = MK_STATUS(SCOPE_CLIENT, ERR_MALFORMED); goto send; } /* get the rest */ while (len_toreceive > len_received) { len = len_toreceive - len_received; len = recv(fd_un2, &buf[len_received], len, 0); if (len < 0) { output(LOG_ERR, "recv failed. %s", strerror(errno)); cresp.status = MK_STATUS(SCOPE_HOST, ERR_COMM); goto send; } else if (!len) return; len_received += len; } /* decode request message */ rc = decode_client_request(buf, len_received, &creq); if (rc) { cresp.status = MK_STATUS(SCOPE_CLIENT, rc); goto send; } /* check if parameters, flags are valid */ if (creq.version != CURRENT_PROTOCOL_VERSION) { output(LOG_ERR, "unsupported protocol version %d", creq.version); cresp.status = MK_STATUS(SCOPE_CLIENT, ERR_PROTOCOL); goto send; } if (check_flag_validity(creq.flags)) { output(LOG_ERR, "not allowed option combination"); cresp.status = MK_STATUS(SCOPE_CLIENT, ERR_INVALID_PARAM); goto send; } if (creq.reqType == CRT_ENUM_KEYS) { cresp.status = STATUS_SUCCESS; goto send; } else if (creq.reqType == CRT_REQUEST_KEY && (!creq.keyLen || creq.keyLen > MAX_KEY_LEN)) { output(LOG_ERR, "invalid size of requested key: %d", creq.keyLen); cresp.status = MK_STATUS(SCOPE_CLIENT, ERR_INVALID_PARAM); goto send; } /* make keyid */ sprintf(keyid, "%s@%s", creq.tag, creq.peer); /* process request */ if (creq.reqType == CRT_DELETE_KEY) { /* check for a key in database and delete it */ if (keydb_exists(keyid)) { rc = keydb_delete(keyid); if (rc) { output(LOG_ERR, "keydb_delete failed. %s", strerror(errno)); cresp.status = MK_STATUS(SCOPE_HOST, ERR_INTERNAL); } } else { output(LOG_ERR, "requested key does not exist: '%s'", keyid); cresp.status = MK_STATUS(SCOPE_HOST, ERR_KEY_NOT_EXISTS); } } /* here we block and get requested key */ else if (creq.flags & FLAG_INIT_KEY) { struct sockaddr_in peer_addr; char addr_accept[] = "0123456789."; PEER_ENTRY* pe; /* locate and check the peer */ pe = find_peer(creq.peer); if (!pe) { output(LOG_ERR, "peer '%s' is not available", creq.peer); cresp.status = MK_STATUS(SCOPE_HOST, ERR_NOT_AVAILABLE); goto send; } else if (!pe->allow) { output(LOG_ERR, "access denied for peer '%s'", creq.peer); cresp.status = MK_STATUS(SCOPE_HOST, ERR_ACCESS_DENIED); goto send; } /* generate secret, calculate public value */ rc = dh_init_group_params(conf_dh_group, &bn_prime, &bn_base); if (rc) { output(LOG_ERR, "dh_init_group_params failed"); cresp.status = MK_STATUS(SCOPE_HOST, rc); goto send; } DUMP_BN(bn_prime, "prime "); DUMP_BN(bn_base, "base "); rc = dh_gen_private_public(conf_dh_group, bn_prime, bn_base, &bn_private, &public, &public_len); if (rc) { output(LOG_ERR, "dh_gen_private_public failed"); cresp.status = MK_STATUS(SCOPE_HOST, rc); goto send; } DUMP_BN(bn_private, "priv-i"); DUMP_BIN(public, public_len, "publ-i"); /* fill-in request */ sreq.cookie = generate_unique_cookie(); sreq.keyLen = creq.keyLen; strncpy(sreq.tag, creq.tag, sizeof(sreq.tag)); strncpy(sreq.host, conf_host, sizeof(sreq.host)); strncpy(sreq.expires, creq.expires, sizeof(sreq.expires)); sreq.dhGroup = conf_dh_group; sreq.dhPublic_len = public_len; memcpy(sreq.dhPublic, public, public_len); smsg.tbsMsg_len = sizeof(smsg.tbsMsg); rc = encode_server_request(&sreq, smsg.tbsMsg, &smsg.tbsMsg_len); if (rc) { cresp.status = MK_STATUS(SCOPE_HOST, rc); goto send; } /* fill-in request message */ smsg.version = CURRENT_PROTOCOL_VERSION; /* sign request if required */ if (pe->auth != AUTH_NONE) { rc = sign_message(pe, smsg.tbsMsg, smsg.tbsMsg_len, smsg.sigAlg, &smsg.sigAlg_len, smsg.sig, &smsg.sig_len); if (rc) { cresp.status = MK_STATUS(SCOPE_HOST, rc); goto send; } } /* encode message */ len = sizeof(buf); rc = encode_server_message(&smsg, buf, &len); if (rc) { cresp.status = MK_STATUS(SCOPE_HOST, rc); goto send; } /* get peer id & address, connect to socket and send the message */ /* is it ip address? */ if (strspn(creq.peer, addr_accept) == strlen(creq.peer)) { if (!inet_aton(creq.peer, &(peer_addr.sin_addr))) { output(LOG_ERR, "inet_aton failed"); cresp.status = MK_STATUS(SCOPE_HOST, ERR_COMM); goto send; } } /* resolve dns */ else { struct hostent* h = gethostbyname(creq.peer); if (!h) { output(LOG_ERR, "gethostbyname failed"); cresp.status = MK_STATUS(SCOPE_HOST, ERR_COMM); goto send; } peer_addr.sin_addr = *((struct in_addr*)h->h_addr); } peer_addr.sin_family = AF_INET; peer_addr.sin_port = htons(creq.port ? creq.port : DEFAULT_PORT); memset(peer_addr.sin_zero, 0, sizeof(peer_addr.sin_zero)); fd_in = socket(AF_INET, SOCK_STREAM, 0); if (!fd_in) { output(LOG_ERR, "socket failed. %s", strerror(errno)); cresp.status = MK_STATUS(SCOPE_HOST, ERR_COMM); goto send; } rc = connect(fd_in, (struct sockaddr*)&peer_addr, sizeof(struct sockaddr)); if (rc == -1) { output(LOG_ERR, "connect failed. %s", strerror(errno)); cresp.status = MK_STATUS(SCOPE_HOST, ERR_COMM); goto send; } /* send request */ len_sent = 0; len_tosend = len; while (len_tosend > len_sent) { len = len_tosend - len_sent; len = send(fd_in, &buf[len_sent], len, 0); if (len < 0) { output(LOG_ERR, "send failed/connection closed by peer"); cresp.status = MK_STATUS(SCOPE_HOST, ERR_COMM); goto send; } len_sent += len; } memset(&smsg, 0, sizeof(smsg)); /* receive response - we can expect at least 14 bytes to receive */ len = recv(fd_in, buf, 14, 0); if (len <= 0) { output(LOG_ERR, "recv failed/connection closed by peer"); cresp.status = MK_STATUS(SCOPE_HOST, ERR_COMM); goto send; } len_received = len; len_toreceive = get_der_seq_size(buf); assert(len_toreceive <= sizeof(buf)); if (len_toreceive > sizeof(buf)) { output(LOG_ERR, "packet sent by peer is too big"); cresp.status = MK_STATUS(SCOPE_PEER, ERR_MALFORMED); goto send; } /* get the rest */ while (len_toreceive > len_received) { len = len_toreceive - len_received; len = recv(fd_in, &buf[len_received], len, 0); if (len < 0) { output(LOG_ERR, "recv failed/connection closed by peer"); cresp.status = MK_STATUS(SCOPE_HOST, ERR_COMM); goto send; } len_received += len; } close(fd_in); fd_in = 0; /* decode response message */ rc = decode_server_message(buf, len_received, &smsg); if (rc) { cresp.status = MK_STATUS(SCOPE_HOST, rc); goto send; } /* sanity check */ if (smsg.version != CURRENT_PROTOCOL_VERSION) { output(LOG_ERR, "unsupported protocol version %d", smsg.version); cresp.status = MK_STATUS(SCOPE_PEER, ERR_PROTOCOL); goto send; } /* verify signature if required */ if (smsg.sigAlg_len && smsg.sig_len) { rc = verify_signature(pe, smsg.tbsMsg, smsg.tbsMsg_len, smsg.sigAlg, smsg.sigAlg_len, smsg.sig, smsg.sig_len); if (rc) { cresp.status = MK_STATUS(SCOPE_HOST, rc); goto send; } } else if (pe->auth != AUTH_NONE) { output(LOG_ERR, "response is not signed"); cresp.status = MK_STATUS(SCOPE_PEER, ERR_SIG_VERIFY); goto send; } /* decode response */ rc = decode_server_response(smsg.tbsMsg, smsg.tbsMsg_len, &sresp); if (rc) { cresp.status = MK_STATUS(SCOPE_HOST, rc); goto send; } if (GET_ERR(sresp.status)) { output(LOG_ERR, "peer returned status 0x%0.2hx", sresp.status); cresp.status = MK_STATUS(SCOPE_PEER, GET_ERR(sresp.status)); goto send; } /* calculate shared secret, make a requested key */ rc = dh_get_secret(sresp.dhPublic, sresp.dhPublic_len, bn_private, bn_prime, &secret_key, &secret_key_len); if (rc) { output(LOG_ERR, "dh_get_secret failed"); cresp.status = MK_STATUS(SCOPE_HOST, rc); goto send; } DUMP_BIN(sresp.dhPublic, sresp.dhPublic_len, "publ-r"); DUMP_BIN(secret_key, secret_key_len, "secr-i"); assert(secret_key_len >= BITS_TO_BYTES(creq.keyLen)); /* store a key to database */ if (creq.flags & FLAG_STORE_KEY) { char kval_buf[KEY_VAL_SIZE + MAX_KEY_LEN]; PKEY_VAL pkey_val = (PKEY_VAL)kval_buf; pkey_val->expires = gentime_to_time_t(creq.expires); if (pkey_val->expires == -1) { output(LOG_ERR, "cannot convert time value %s", creq.expires); cresp.status = MK_STATUS(SCOPE_HOST, ERR_INVALID_PARAM); goto send; } pkey_val->key_len = creq.keyLen; memcpy(pkey_val->key, secret_key, BITS_TO_BYTES(pkey_val->key_len)); rc = keydb_store(keyid, kval_buf, sizeof(KEY_VAL) + BITS_TO_BYTES(pkey_val->key_len)); if (rc) { output(LOG_ERR, "keydb_store failed. %s", strerror(errno)); cresp.status = MK_STATUS(SCOPE_HOST, ERR_INTERNAL); goto send; } output(LOG_INFO, "new key '%s' (%dbits) added, validity: %s", keyid, pkey_val->key_len, ctime(&pkey_val->expires)); } cresp.keyLen = creq.keyLen; memcpy(cresp.key, secret_key, BITS_TO_BYTES(cresp.keyLen)); cresp.status = STATUS_SUCCESS; } else {
int s3_ls_bucket(char* bucketname, struct list* dirents, const char* access_key_id, const char* access_key) { struct s3_message mesg; struct link* server = NULL; time_t stoptime = time(0)+s3_timeout; char response[HEADER_LINE_MAX]; char path[HEADER_LINE_MAX]; int length; char done = 0; if(!access_key_id || !access_key || !s3_endpoint) return -1; sprintf(path, "/"); mesg.type = S3_MESG_GET; mesg.path = path; mesg.bucket = bucketname; mesg.content_type = NULL; mesg.content_md5 = NULL; mesg.content_length = 0; mesg.date = time(0); mesg.expect = 0; mesg.amz_headers = NULL; do { char *buffer, *temp, *start, *end; char trunc[25]; int keys; sign_message(&mesg, access_key_id, access_key); server = s3_send_message(&mesg, server, stoptime); if(!server) return -1; link_readline(server, response, HEADER_LINE_MAX, stoptime); if(strcmp(response, "HTTP/1.1 200 OK")) { // Error: transfer failed; close connection and return failure fprintf(stderr, "Error: list bucket failed\nResponse: %s\n", response); link_close(server); return -1; } length = 0; do { if(!strncmp(response, "Content-Length:", 14)) sscanf(response, "Content-Length: %d", &length); if(!strcmp(response, "Transfer-Encoding: chunked")) length = 0; if(!strcmp(response, "Server: AmazonS3")) break; } while(link_readline(server, response, HEADER_LINE_MAX, stoptime)); link_readline(server, response, HEADER_LINE_MAX, stoptime); if(length) { buffer = malloc(length+1); link_read(server, buffer, length, stoptime); } else { struct list *buf; unsigned int clen = 0; buf = list_create(); do { link_readline(server, response, HEADER_LINE_MAX, stoptime); sscanf(response, "%x", &clen); //link_readline(server, response, HEADER_LINE_MAX, stoptime); if(clen) { buffer = malloc(clen+1); link_read(server, buffer, clen, stoptime); link_readline(server, response, HEADER_LINE_MAX, stoptime); list_push_tail(buf, buffer); length += clen; } } while(clen); buffer = malloc(length+1); buffer[0] = '\0'; while((temp = list_pop_head(buf))) { sprintf(buffer, "%s%s", buffer, temp); free(temp); } list_delete(buf); } sscanf(buffer, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<ListBucketResult xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\"><Name>%*[^<]</Name><Prefix></Prefix><Marker></Marker><MaxKeys>%d</MaxKeys><IsTruncated>%[^<]</IsTruncated>", &keys, trunc); if(!strcmp(trunc, "false")) done = 1; temp = buffer; while( (start = strstr(temp, "<Contents>")) ) { struct s3_dirent_object *dirent; struct tm date; char display_name[1024]; end = strstr(start, "</Contents>"); end[10] = '\0'; temp = end + 11; dirent = malloc(sizeof(*dirent)); date.tm_isdst = -1; sscanf(strstr(start, "<Key>"), "<Key>%[^<]</Key>", dirent->key); sscanf(strstr(start, "<LastModified>"), "<LastModified>%d-%d-%dT%d:%d:%d.%*dZ</LastModified>", &date.tm_year, &date.tm_mon, &date.tm_mday, &date.tm_hour, &date.tm_min, &date.tm_sec); sscanf(strstr(start, "<ETag>"), "<ETag>"%[^&]"</ETag>", dirent->digest); sscanf(strstr(start, "<Size>"), "<Size>%d</Size>", &dirent->size); sscanf(strstr(start, "<Owner>"), "<Owner><ID>%*[^<]</ID><DisplayName>%[^<]</DisplayName></Owner>", display_name); if(strlen(display_name)) dirent->display_name = strdup(display_name); date.tm_mon -= 1; dirent->last_modified = mktime(&date); list_push_tail(dirents, dirent); } free(buffer); } while(!done); link_close(server); return 0; }
static gboolean send_review_request (GsPlugin *plugin, const gchar *method, const gchar *path, JsonBuilder *request, gboolean do_sign, guint *status_code, JsonParser **result, GCancellable *cancellable, GError **error) { g_autofree gchar *uri = NULL; g_autoptr(SoupMessage) msg = NULL; uri = g_strdup_printf ("%s%s", UBUNTU_REVIEWS_SERVER, path); msg = soup_message_new (method, uri); if (request != NULL) { g_autoptr(JsonGenerator) generator = NULL; gchar *data; gsize length; generator = json_generator_new (); json_generator_set_root (generator, json_builder_get_root (request)); data = json_generator_to_data (generator, &length); soup_message_set_request (msg, "application/json", SOUP_MEMORY_TAKE, data, length); } if (do_sign) sign_message (msg, OA_PLAINTEXT, gs_plugin_get_auth_by_id (plugin, "ubuntuone")); *status_code = soup_session_send_message (gs_plugin_get_soup_session (plugin), msg); if (*status_code == SOUP_STATUS_UNAUTHORIZED) { g_set_error_literal (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_AUTH_REQUIRED, "Requires authentication with @ubuntuone"); return FALSE; } if (result != NULL) { g_autoptr(JsonParser) parser = NULL; const gchar *content_type; content_type = soup_message_headers_get_content_type (msg->response_headers, NULL); if (g_strcmp0 (content_type, "application/json") != 0) { g_set_error (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "Got unknown content type %s from reviews.ubuntu.com", content_type); return FALSE; } parser = json_parser_new (); if (!json_parser_load_from_data (parser, msg->response_body->data, -1, error)) { return FALSE; } *result = g_steal_pointer (&parser); } return TRUE; }