Example #1
0
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;
}
Example #2
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;
}
Example #3
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;
}
Example #4
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;
}
Example #5
0
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;
}
Example #6
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;
}
Example #7
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 {
Example #8
0
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>&quot;%[^&]&quot;</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;
}