<commit_before>// Copyright 2016 PLUMgrid
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.package main

package driver

import (
	"encoding/json"
	"strings"
)

func BridgeCreate(ID string, domainid string, gatewayip string) {

	url := "/0/connectivity/domain/" + domainid + "/ne/bri" + ID
	data := []byte(`{"action": {
				"action1": {
					"action_text": "create_and_link_ifc(DYN_1)"}
				},
				"ifc": {},
				"mobility": "true",
				"ne_description": "PLUMgrid Bridge",
				"ne_dname": "net-` + ID[:10] + `",
				"ne_group": "Bridge",
				"ne_type": "bridge"
	}`)

	RestCall("PUT", url, data)

	url = "/0/connectivity/domain/" + domainid + "/rule_group/cnf" + ID
	data = []byte(`{"mark_disabled": false,
			"ne_dest": "/ne/bri` + ID + `/action/action1",
			"ne_dname": "cont-` + ID[10:] + `",
			"ne_type": "cnf-vmgroup",
					"rule": {
						"rules` + ID + `": {
							"add_context": "",
							"criteria": "pgtag2",
							"match": "bridge-` + ID[:10] + `"
						}
					}
	}`)

	RestCall("PUT", url, data)

	url = "/0/connectivity/domain_prop/" + domainid + "/ne/brii" + ID
	data = []byte(`{"ne_metadata": "` + gatewayip + `"}`)
	RestCall("PUT", url, data)
}

func BridgeDelete(ID string, domainid string) {

	url := "/0/connectivity/domain_prop/" + domainid + "/ne/brii" + ID
	RestCall("DELETE", url, nil)

	url = "/0/connectivity/domain/" + domainid + "/ne/bri" + ID
	RestCall("DELETE", url, nil)

	url = "/0/connectivity/domain/" + domainid + "/rule_group/cnf" + ID
	RestCall("DELETE", url, nil)
}

func FindDomainFromNetwork(ID string) (domainid string) {

	url := "/0/connectivity/domain?configonly=true&level=3"
	body, _ := RestCall("GET", url, nil)
	var domain_data map[string]interface{}
	err := json.Unmarshal([]byte(body), &domain_data)
	if err != nil {
		panic(err)
	}
	for domains, domain_val := range domain_data {
		if nes, ok := domain_val.(map[string]interface{})["ne"]; ok {
			if _, ok := nes.(map[string]interface{})["bri"+ID]; ok {
				domainid = domains
				break
			}
		}
	}
	return
}

func FindNetworkGateway(domainID string, networkID string) (gatewayIP string) {

	url := "/0/connectivity/domain_prop/" + domainID + "/ne/brii" + networkID
	body, _ := RestCall("GET", url, nil)
	var domain_prop map[string]interface{}
	err := json.Unmarshal([]byte(body), &domain_prop)
	if err != nil {
		panic(err)
	}
	gatewayIP = domain_prop["ne_metadata"].(string)
	return
}

func DomainCreate(domainID string) {

	url := "/0/connectivity/domain?configonly=true"
	body, _ := RestCall("GET", url, nil)
	var domain_data map[string]interface{}
	err := json.Unmarshal([]byte(body), &domain_data)
	if err != nil {
		panic(err)
	}
	for domains := range domain_data {
		if domains == domainID {
			return
		}
	}

	url = "/0/tenant_manager/tenants" + "/" + domainID
	data := []byte(`{"containers": {
				"` + domainID + `": {
					"enable": "True",
					"qos_marking": "9",
					"context": "` + domainID + `",
					"type": "Gold",
					"property": "Container ` + domainID + ` Property",
					"domains": {}, "rules": {}}}}`)

	RestCall("PUT", url, data)

	url = "/0/tunnel_service/vnd_config/" + domainID
	data = []byte(`{"profile_name": "VXLAN",
			"add_vlan": "False"}`)
	RestCall("PUT", url, data)

	url = "/0/connectivity/domain/" + domainID
	data = []byte(`{"container_group": "` + domainID + `",
			"topology_name": "docker"}`)
	RestCall("PUT", url, data)

	url = "/0/connectivity/domain_prop/" + domainID
	data = []byte(`{}`)
	RestCall("PUT", url, data)

	url = "/0/pem_master/log_rule/" + domainID
	data = []byte(`{"rule": {
				"rule_` + domainID + `": {
					"pgtag1": "` + domainID + `",
					"log_ifc_type": "ACCESS_VM"}}}`)

	RestCall("PUT", url, data)
}

func DomainDelete(domainID string) {

	url := "/0/connectivity/domain?configonly=true"
	body, _ := RestCall("GET", url, nil)
	var domain_data map[string]interface{}
	err := json.Unmarshal([]byte(body), &domain_data)
	if err != nil {
		panic(err)
	}
	for domains, domain_val := range domain_data {
		if domains == domainID {
			res := domain_val.(map[string]interface{})["ne"]
			if len(res.(map[string]interface{})) == 0 {

				url = "/0/pem_master/log_rule/" + domainID
				RestCall("DELETE", url, nil)

				url = "/0/connectivity/domain_prop/" + domainID
				RestCall("DELETE", url, nil)

				url = "/0/connectivity/domain/" + domainID
				RestCall("DELETE", url, nil)

				url = "/0/tunnel_service/vnd_config/" + domainID
				RestCall("DELETE", url, nil)

				url = "/0/tenant_manager/tenants" + "/" + domainID
				RestCall("DELETE", url, nil)
			}
		}
	}
}

func GetNeId(NeName string, DomainID string) (NeID string) {

	url := "/0/connectivity/domain/" + DomainID + "/ne?configonly=true&level=1"
	body, _ := RestCall("GET", url, nil)
	var ne_data map[string]interface{}
	err := json.Unmarshal([]byte(body), &ne_data)
	if err != nil {
		panic(err)
	}
	for nes, ne_val := range ne_data {
		if ne_val.(map[string]interface{})["ne_dname"] == NeName {
			NeID = nes
			break
		}
	}
	return
}

func CreateNetworkLink(NeName string, DomainID string, NetworkID string, IP string, Netmask string) {

	ne_ID := GetNeId(NeName, DomainID)
	CheckNeChildList(ne_ID, DomainID, "ifc")
	CheckNeChildList(NetworkName(NetworkID), DomainID, "ifc")
	ne_ifc := NetworkID
	url := "/0/connectivity/domain/" + DomainID + "/ne/" + ne_ID + "/ifc/" + ne_ifc
	data := []byte(`{"attachable": "true",
                         "list": "true",
                         "attach_type": "static,dynamic",
                         "mobility": "true",
                         "ifc_name": "` + ne_ifc + `",
                         "ifc_type": "static",
                         "ip_address": "` + IP + `",
                         "ip_address_mask": "` + Netmask + `"}`)
	RestCall("PUT", url, data)

	net_ifc := ne_ID
	url = "/0/connectivity/domain/" + DomainID + "/ne/" + NetworkName(NetworkID) + "/ifc/" + net_ifc
	data = []byte(`{"attachable": "true",
                         "list": "true",
                         "attach_type": "static,dynamic",
                         "mobility": "true",
                         "ifc_type": "static"}`)
	RestCall("PUT", url, data)

	link_name := ne_ID + NetworkID
	url = "/0/connectivity/domain/" + DomainID + "/link/" + link_name
	data = []byte(`{"link_type": "static",
                         "link_name": "` + link_name + `",
                         "attachment1": "/ne/` + ne_ID + `/ifc/` + ne_ifc + `",
                         "attachment2": "/ne/` + NetworkName(NetworkID) + `/ifc/` + net_ifc + `"}`)
	RestCall("PUT", url, data)
}

func DeleteNetworkLinks(DomainID string, NetworkID string) {

	var ne_ID string
	var ne_ifc string
	url := "/0/connectivity/domain/" + DomainID
	body, _ := RestCall("GET", url+"?configonly=true", nil)
	var domain_data map[string]interface{}
	err := json.Unmarshal([]byte(body), &domain_data)
	if err != nil {
		panic(err)
	}
	for domains, domain_val := range domain_data {
		if domains == "link" {
			links := domain_val.(map[string]interface{})
			for att, att_info := range links {
				att_1 := att_info.(map[string]interface{})["attachment1"].(string)
				att_2 := att_info.(map[string]interface{})["attachment2"].(string)
				if strings.Split(att_1, "/")[2][3:] == NetworkID {
					ne_ID = strings.Split(att_2, "/")[2]
					ne_ifc = strings.Split(att_2, "/")[4]
					RestCall("DELETE", url+"/link/"+att, nil)
					ifc_url := url + "/ne/" + ne_ID + "/ifc/" + ne_ifc
					RestCall("DELETE", ifc_url, nil)
				} else if strings.Split(att_2, "/")[2][3:] == NetworkID {
					ne_ID = strings.Split(att_1, "/")[2]
					ne_ifc = strings.Split(att_1, "/")[4]
					RestCall("DELETE", url+"/link/"+att, nil)
					ifc_url := url + "/ne/" + ne_ID + "/ifc/" + ne_ifc
					RestCall("DELETE", ifc_url, nil)
				}
			}
		}
	}
}

func NetworkName(ID string) (name string) {
	name = "bri" + ID
	return
}

func CheckNeChildList(NeID string, DomainID string, childList string) {

	url := "/0/connectivity/domain/" + DomainID + "/ne/" + NeID + "?configonly=true"
	body, _ := RestCall("GET", url, nil)
	var ne_data map[string]interface{}
	err := json.Unmarshal([]byte(body), &ne_data)
	if err != nil {
		panic(err)
	}
	if _, ok := ne_data[childList]; ok {
		return
	} else {
		data := []byte(`{}`)
		RestCall("PUT", url+"/"+childList, data)
		return
	}
}
<commit_msg>changing access type (II)<commit_after>// Copyright 2016 PLUMgrid
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.package main

package driver

import (
	"encoding/json"
	"strings"
)

func BridgeCreate(ID string, domainid string, gatewayip string) {

	url := "/0/connectivity/domain/" + domainid + "/ne/bri" + ID
	data := []byte(`{"action": {
				"action1": {
					"action_text": "create_and_link_ifc(DYN_1)"}
				},
				"ifc": {},
				"mobility": "true",
				"ne_description": "PLUMgrid Bridge",
				"ne_dname": "net-` + ID[:10] + `",
				"ne_group": "Bridge",
				"ne_type": "bridge"
	}`)

	RestCall("PUT", url, data)

	url = "/0/connectivity/domain/" + domainid + "/rule_group/cnf" + ID
	data = []byte(`{"mark_disabled": false,
			"ne_dest": "/ne/bri` + ID + `/action/action1",
			"ne_dname": "cont-` + ID[10:] + `",
			"ne_type": "cnf-vmgroup",
					"rule": {
						"rules` + ID + `": {
							"add_context": "",
							"criteria": "pgtag2",
							"match": "bridge-` + ID[:10] + `"
						}
					}
	}`)

	RestCall("PUT", url, data)

	url = "/0/connectivity/domain_prop/" + domainid + "/ne/brii" + ID
	data = []byte(`{"ne_metadata": "` + gatewayip + `"}`)
	RestCall("PUT", url, data)
}

func BridgeDelete(ID string, domainid string) {

	url := "/0/connectivity/domain_prop/" + domainid + "/ne/brii" + ID
	RestCall("DELETE", url, nil)

	url = "/0/connectivity/domain/" + domainid + "/ne/bri" + ID
	RestCall("DELETE", url, nil)

	url = "/0/connectivity/domain/" + domainid + "/rule_group/cnf" + ID
	RestCall("DELETE", url, nil)
}

func FindDomainFromNetwork(ID string) (domainid string) {

	url := "/0/connectivity/domain?configonly=true&level=3"
	body, _ := RestCall("GET", url, nil)
	var domain_data map[string]interface{}
	err := json.Unmarshal([]byte(body), &domain_data)
	if err != nil {
		panic(err)
	}
	for domains, domain_val := range domain_data {
		if nes, ok := domain_val.(map[string]interface{})["ne"]; ok {
			if _, ok := nes.(map[string]interface{})["bri"+ID]; ok {
				domainid = domains
				break
			}
		}
	}
	return
}

func FindNetworkGateway(domainID string, networkID string) (gatewayIP string) {

	url := "/0/connectivity/domain_prop/" + domainID + "/ne/brii" + networkID
	body, _ := RestCall("GET", url, nil)
	var domain_prop map[string]interface{}
	err := json.Unmarshal([]byte(body), &domain_prop)
	if err != nil {
		panic(err)
	}
	gatewayIP = domain_prop["ne_metadata"].(string)
	return
}

func DomainCreate(domainID string) {

	url := "/0/connectivity/domain?configonly=true"
	body, _ := RestCall("GET", url, nil)
	var domain_data map[string]interface{}
	err := json.Unmarshal([]byte(body), &domain_data)
	if err != nil {
		panic(err)
	}
	for domains := range domain_data {
		if domains == domainID {
			return
		}
	}

	url = "/0/tenant_manager/tenants" + "/" + domainID
	data := []byte(`{"containers": {
				"` + domainID + `": {
					"enable": "True",
					"qos_marking": "9",
					"context": "` + domainID + `",
					"type": "Gold",
					"property": "Container ` + domainID + ` Property",
					"domains": {}, "rules": {}}}}`)

	RestCall("PUT", url, data)

	url = "/0/tunnel_service/vnd_config/" + domainID
	data = []byte(`{"profile_name": "VXLAN",
			"add_vlan": "False"}`)
	RestCall("PUT", url, data)

	url = "/0/connectivity/domain/" + domainID
	data = []byte(`{"container_group": "` + domainID + `",
			"topology_name": "docker"}`)
	RestCall("PUT", url, data)

	url = "/0/connectivity/domain_prop/" + domainID
	data = []byte(`{}`)
	RestCall("PUT", url, data)

	url = "/0/pem_master/log_rule/" + domainID
	data = []byte(`{"rule": {
				"rule_` + domainID + `": {
					"pgtag1": "` + domainID + `",
					"log_ifc_type": "ACCESS_CONTAINER"}}}`)

	RestCall("PUT", url, data)
}

func DomainDelete(domainID string) {

	url := "/0/connectivity/domain?configonly=true"
	body, _ := RestCall("GET", url, nil)
	var domain_data map[string]interface{}
	err := json.Unmarshal([]byte(body), &domain_data)
	if err != nil {
		panic(err)
	}
	for domains, domain_val := range domain_data {
		if domains == domainID {
			res := domain_val.(map[string]interface{})["ne"]
			if len(res.(map[string]interface{})) == 0 {

				url = "/0/pem_master/log_rule/" + domainID
				RestCall("DELETE", url, nil)

				url = "/0/connectivity/domain_prop/" + domainID
				RestCall("DELETE", url, nil)

				url = "/0/connectivity/domain/" + domainID
				RestCall("DELETE", url, nil)

				url = "/0/tunnel_service/vnd_config/" + domainID
				RestCall("DELETE", url, nil)

				url = "/0/tenant_manager/tenants" + "/" + domainID
				RestCall("DELETE", url, nil)
			}
		}
	}
}

func GetNeId(NeName string, DomainID string) (NeID string) {

	url := "/0/connectivity/domain/" + DomainID + "/ne?configonly=true&level=1"
	body, _ := RestCall("GET", url, nil)
	var ne_data map[string]interface{}
	err := json.Unmarshal([]byte(body), &ne_data)
	if err != nil {
		panic(err)
	}
	for nes, ne_val := range ne_data {
		if ne_val.(map[string]interface{})["ne_dname"] == NeName {
			NeID = nes
			break
		}
	}
	return
}

func CreateNetworkLink(NeName string, DomainID string, NetworkID string, IP string, Netmask string) {

	ne_ID := GetNeId(NeName, DomainID)
	CheckNeChildList(ne_ID, DomainID, "ifc")
	CheckNeChildList(NetworkName(NetworkID), DomainID, "ifc")
	ne_ifc := NetworkID
	url := "/0/connectivity/domain/" + DomainID + "/ne/" + ne_ID + "/ifc/" + ne_ifc
	data := []byte(`{"attachable": "true",
                         "list": "true",
                         "attach_type": "static,dynamic",
                         "mobility": "true",
                         "ifc_name": "` + ne_ifc + `",
                         "ifc_type": "static",
                         "ip_address": "` + IP + `",
                         "ip_address_mask": "` + Netmask + `"}`)
	RestCall("PUT", url, data)

	net_ifc := ne_ID
	url = "/0/connectivity/domain/" + DomainID + "/ne/" + NetworkName(NetworkID) + "/ifc/" + net_ifc
	data = []byte(`{"attachable": "true",
                         "list": "true",
                         "attach_type": "static,dynamic",
                         "mobility": "true",
                         "ifc_type": "static"}`)
	RestCall("PUT", url, data)

	link_name := ne_ID + NetworkID
	url = "/0/connectivity/domain/" + DomainID + "/link/" + link_name
	data = []byte(`{"link_type": "static",
                         "link_name": "` + link_name + `",
                         "attachment1": "/ne/` + ne_ID + `/ifc/` + ne_ifc + `",
                         "attachment2": "/ne/` + NetworkName(NetworkID) + `/ifc/` + net_ifc + `"}`)
	RestCall("PUT", url, data)
}

func DeleteNetworkLinks(DomainID string, NetworkID string) {

	var ne_ID string
	var ne_ifc string
	url := "/0/connectivity/domain/" + DomainID
	body, _ := RestCall("GET", url+"?configonly=true", nil)
	var domain_data map[string]interface{}
	err := json.Unmarshal([]byte(body), &domain_data)
	if err != nil {
		panic(err)
	}
	for domains, domain_val := range domain_data {
		if domains == "link" {
			links := domain_val.(map[string]interface{})
			for att, att_info := range links {
				att_1 := att_info.(map[string]interface{})["attachment1"].(string)
				att_2 := att_info.(map[string]interface{})["attachment2"].(string)
				if strings.Split(att_1, "/")[2][3:] == NetworkID {
					ne_ID = strings.Split(att_2, "/")[2]
					ne_ifc = strings.Split(att_2, "/")[4]
					RestCall("DELETE", url+"/link/"+att, nil)
					ifc_url := url + "/ne/" + ne_ID + "/ifc/" + ne_ifc
					RestCall("DELETE", ifc_url, nil)
				} else if strings.Split(att_2, "/")[2][3:] == NetworkID {
					ne_ID = strings.Split(att_1, "/")[2]
					ne_ifc = strings.Split(att_1, "/")[4]
					RestCall("DELETE", url+"/link/"+att, nil)
					ifc_url := url + "/ne/" + ne_ID + "/ifc/" + ne_ifc
					RestCall("DELETE", ifc_url, nil)
				}
			}
		}
	}
}

func NetworkName(ID string) (name string) {
	name = "bri" + ID
	return
}

func CheckNeChildList(NeID string, DomainID string, childList string) {

	url := "/0/connectivity/domain/" + DomainID + "/ne/" + NeID + "?configonly=true"
	body, _ := RestCall("GET", url, nil)
	var ne_data map[string]interface{}
	err := json.Unmarshal([]byte(body), &ne_data)
	if err != nil {
		panic(err)
	}
	if _, ok := ne_data[childList]; ok {
		return
	} else {
		data := []byte(`{}`)
		RestCall("PUT", url+"/"+childList, data)
		return
	}
}
<|endoftext|>


<commit_before>// Copyright 2016 The nvim-go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package command

import (
	"fmt"

	"github.com/zchee/nvim-go/src/nvimutil"
)

func (c *Command) cmdBuffers() error {
	bufs, _ := c.Nvim.Buffers()
	var b []string
	for _, buf := range bufs {
		nr, _ := c.Nvim.BufferNumber(buf)
		b = append(b, fmt.Sprintf("%d", nr))
	}
	return nvimutil.Echomsg(c.Nvim, "Buffers:", b)
}

func (c *Command) cmdWindows() error {
	wins, _ := c.Nvim.Windows()
	var w []string
	for _, win := range wins {
		w = append(w, win.String())
	}
	return nvimutil.Echomsg(c.Nvim, "Windows:", w)
}

func (c *Command) cmdTabpagas() error {
	tabs, _ := c.Nvim.Tabpages()
	var t []string
	for _, tab := range tabs {
		t = append(t, tab.String())
	}
	return nvimutil.Echomsg(c.Nvim, "Tabpages:", t)
}

func (c *Command) cmdByteOffset() error {
	b, err := c.Nvim.CurrentBuffer()
	if err != nil {
		return err
	}
	w, err := c.Nvim.CurrentWindow()
	if err != nil {
		return err
	}

	offset, _ := nvimutil.ByteOffset(c.Nvim, b, w)
	return nvimutil.Echomsg(c.Nvim, offset)
}
<commit_msg>command/util: add zap logging to cmdByteOffset<commit_after>// Copyright 2016 The nvim-go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package command

import (
	"fmt"

	"github.com/zchee/nvim-go/src/logger"
	"github.com/zchee/nvim-go/src/nvimutil"
	"go.uber.org/zap"
)

func (c *Command) cmdBuffers() error {
	bufs, _ := c.Nvim.Buffers()
	var b []string
	for _, buf := range bufs {
		nr, _ := c.Nvim.BufferNumber(buf)
		b = append(b, fmt.Sprintf("%d", nr))
	}
	return nvimutil.Echomsg(c.Nvim, "Buffers:", b)
}

func (c *Command) cmdWindows() error {
	wins, _ := c.Nvim.Windows()
	var w []string
	for _, win := range wins {
		w = append(w, win.String())
	}
	return nvimutil.Echomsg(c.Nvim, "Windows:", w)
}

func (c *Command) cmdTabpagas() error {
	tabs, _ := c.Nvim.Tabpages()
	var t []string
	for _, tab := range tabs {
		t = append(t, tab.String())
	}
	return nvimutil.Echomsg(c.Nvim, "Tabpages:", t)
}

func (c *Command) cmdByteOffset() error {
	b, err := c.Nvim.CurrentBuffer()
	if err != nil {
		return err
	}
	w, err := c.Nvim.CurrentWindow()
	if err != nil {
		return err
	}

	offset, _ := nvimutil.ByteOffset(c.Nvim, b, w)
	logger.FromContext(c.ctx).Info("cmdByteOffset", zap.Int("offset", offset))

	return nvimutil.Echomsg(c.Nvim, offset)
}
<|endoftext|>


<commit_before>// Copyright 2012 Aaron Jacobs. All Rights Reserved.
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// The C code in this file was pulled on 2012-09-04 from the proposed SIV
// implementation for OpenSSL hosted on lounge.org:
//
//     http://www.lounge.org/siv_for_openssl.tgz
//
// It was modified by Aaron Jacobs to suit the gencases tool. These
// modifications and the Go code are copyright Aaron Jacobs. The original
// copyright notice is below.

package main

/*
 * Copyright (c) The Industrial Lounge, 2007
 *
 *  Copyright holder grants permission for redistribution and use in source
 *  and binary forms, with or without modification, provided that the
 *  following conditions are met:
 *     1. Redistribution of source code must retain the above copyright
 *        notice, this list of conditions, and the following disclaimer
 *        in all source files.
 *     2. Redistribution in binary form must retain the above copyright
 *        notice, this list of conditions, and the following disclaimer
 *        in the documentation and/or other materials provided with the
 *        distribution.
 *     3. All advertising materials and documentation mentioning features
 *	  or use of this software must display the following acknowledgement:
 *
 *        "This product includes software written by
 *         Dan Harkins (dharkins at lounge dot org)"
 *
 *  "DISCLAIMER OF LIABILITY
 *
 *  THIS SOFTWARE IS PROVIDED BY THE INDUSTRIAL LOUNGE ``AS IS''
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 *  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INDUSTRIAL LOUNGE BE LIABLE
 *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 *  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 *  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 *  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 *  SUCH DAMAGE."
 *
 * This license and distribution terms cannot be changed. In other words,
 * this code cannot simply be copied and put under another distribution
 * license (including the GNU public license).
 */

/*
#include <stdio.h>
#include <string.h>
#include <openssl/crypto.h>
#include <openssl/evp.h>
#include <openssl/aes.h>
#include "siv.h"
#include "aes_locl.h"

#define Rb		0x87

unsigned char zero[AES_BLOCK_SIZE] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

static void
xor (unsigned char *output, const unsigned char *input)
{
    int i;

    i = AES_BLOCK_SIZE - 1;
    do {
	output[i] ^= input[i];
	i--;
    } while (i >= 0);
    return;
}

static void
times_two (unsigned char *output, unsigned char *input)
{
    int i;
    unsigned char *out = output, *in = input;
    unsigned char carry = 0;

    out = output + AES_BLOCK_SIZE - 1;
    in = input + AES_BLOCK_SIZE - 1;
    for (i = 0; i < AES_BLOCK_SIZE; i++) {
	*(out--) = (*in << 1) | carry;
	carry = (*(in--) & 0x80) ? 1 : 0;
    }

    if (carry) {
	output[AES_BLOCK_SIZE-1] ^= Rb;
    }
    return;
}

static void
pad (unsigned char *buf, int len)
{
    int i;

    i = len;
    buf[i++] = 0x80;
    if (i < AES_BLOCK_SIZE) {
	memset(buf + i, 0, AES_BLOCK_SIZE - i);
    }
}

void
aes_cmac (siv_ctx *ctx, const unsigned char *msg, int mlen, unsigned char *C)
{
    int n, i, slop;
    unsigned char Mn[AES_BLOCK_SIZE], *ptr;

    memcpy(C, zero, AES_BLOCK_SIZE);

    n = (mlen+(AES_BLOCK_SIZE-1))/AES_BLOCK_SIZE;

    ptr = (unsigned char *)msg;
    for (i = 0; i < (n-1); i++) {
	xor(C, ptr);
	AES_ecb_encrypt(C, C, &ctx->s2v_sched, AES_ENCRYPT);
	ptr += AES_BLOCK_SIZE;
    }

    memset(Mn, 0, AES_BLOCK_SIZE);
    if ((slop = (mlen % AES_BLOCK_SIZE)) != 0) {
	memcpy(Mn, ptr, slop);
	pad(Mn, slop);
	xor(Mn, ctx->K2);
    } else {
	if (msg != NULL && mlen != 0) {
	    memcpy(Mn, ptr, AES_BLOCK_SIZE);
	    xor(Mn, ctx->K1);
	} else {
	    pad(Mn, 0);
	    xor(Mn, ctx->K2);
	}
    }
    xor(C, Mn);
    AES_ecb_encrypt(C, C, &ctx->s2v_sched, AES_ENCRYPT);
    return;
}

int
s2v_final (siv_ctx *ctx, const unsigned char *X, int xlen, unsigned char *digest)
{
    unsigned char T[AES_BLOCK_SIZE], C[AES_BLOCK_SIZE];
    unsigned char padX[AES_BLOCK_SIZE], *ptr;
    int blocks, i, slop;

    if (xlen < AES_BLOCK_SIZE) {
	memcpy(padX, X, xlen);
	pad(padX, xlen);

	times_two(T, ctx->T);
	xor(T, padX);
	aes_cmac(ctx, T, AES_BLOCK_SIZE, digest);
    } else {
        if (xlen == AES_BLOCK_SIZE) {
            memcpy(T, X, AES_BLOCK_SIZE);
            xor(T, ctx->T);
            aes_cmac(ctx, T, AES_BLOCK_SIZE, digest);
        } else {
            blocks = (xlen+(AES_BLOCK_SIZE-1))/AES_BLOCK_SIZE - 1;
            ptr = (unsigned char *)X;
            memcpy(C, zero, AES_BLOCK_SIZE);
            if (blocks > 1) {
                for (i = 0; i < (blocks-1); i++) {
                    xor(C, ptr);
                    AES_ecb_encrypt(C, C, &ctx->s2v_sched, AES_ENCRYPT);
                    ptr += AES_BLOCK_SIZE;
                }
            }
            memcpy(T, ptr, AES_BLOCK_SIZE);
            slop = xlen % AES_BLOCK_SIZE;
            if (slop) {
                for (i = 0; i < AES_BLOCK_SIZE - slop; i++) {
                    T[i + slop] ^= ctx->T[i];
                }
                xor(C, T);
                AES_ecb_encrypt(C, C, &ctx->s2v_sched, AES_ENCRYPT);
                ptr += AES_BLOCK_SIZE;
                memset(T, 0, AES_BLOCK_SIZE);
                memcpy(T, ptr, slop);
                for (i = 0; i < slop; i++) {
                    T[i] ^= ctx->T[(AES_BLOCK_SIZE-slop)+i];
                }
                pad(T, slop);
                xor(T, ctx->K2);
            } else {
                xor(C, ptr);
                AES_ecb_encrypt(C, C, &ctx->s2v_sched, AES_ENCRYPT);
                ptr += AES_BLOCK_SIZE;
                memcpy(T, ptr, AES_BLOCK_SIZE);
                xor(T, ctx->T);
                xor(T, ctx->K1);
            }
            xor(C, T);
            AES_ecb_encrypt(C, digest, &ctx->s2v_sched, AES_ENCRYPT);
        }

    }
    return 0;
}

void
s2v_add (siv_ctx *ctx, const unsigned char *Y)
{
    unsigned char T[AES_BLOCK_SIZE];

    memcpy(T, ctx->T, AES_BLOCK_SIZE);
    times_two(ctx->T, T);
    xor(ctx->T, Y);
}

void
s2v_update (siv_ctx *ctx, const unsigned char *X, int xlen)
{
    unsigned char Y[AES_BLOCK_SIZE];

    aes_cmac(ctx, X, xlen, Y);
    s2v_add(ctx, Y);
}

int
siv_init (siv_ctx *ctx, const unsigned char *key, int keylen)
{
    unsigned char L[AES_BLOCK_SIZE];

    memset((char *)ctx, 0, sizeof(siv_ctx));
    switch (keylen) {
        case SIV_512:
            AES_set_encrypt_key(key, 256, &ctx->s2v_sched);
            AES_set_encrypt_key(key+AES_256_BYTES, 256, &ctx->ctr_sched);
            break;
        case SIV_384:
            AES_set_encrypt_key(key, 192, &ctx->s2v_sched);
            AES_set_encrypt_key(key+AES_192_BYTES, 192, &ctx->ctr_sched);
            break;
        case SIV_256:
            AES_set_encrypt_key(key, 128, &ctx->s2v_sched);
            AES_set_encrypt_key(key+AES_128_BYTES, 128, &ctx->ctr_sched);
            break;
        default:
            return -1;
    }

    AES_ecb_encrypt(zero, L, &ctx->s2v_sched, AES_ENCRYPT);
    times_two(ctx->K1, L);
    times_two(ctx->K2, ctx->K1);

    memset(ctx->benchmark, 0, AES_BLOCK_SIZE);
    aes_cmac(ctx, zero, AES_BLOCK_SIZE, ctx->T);
    return 1;
}

void
siv_restart (siv_ctx *ctx)
{
    memset(ctx->benchmark, 0, AES_BLOCK_SIZE);
    memset(ctx->T, 0, AES_BLOCK_SIZE);
    aes_cmac(ctx, zero, AES_BLOCK_SIZE, ctx->T);
}

void
s2v_benchmark (siv_ctx *ctx)
{
    memcpy(ctx->benchmark, ctx->T, AES_BLOCK_SIZE);
}

void
s2v_reset (siv_ctx *ctx)
{
    memcpy(ctx->T, ctx->benchmark, AES_BLOCK_SIZE);
}

void
siv_aes_ctr (siv_ctx *ctx, const unsigned char *p, const int lenp,
             unsigned char *c, const unsigned char *iv)
{
    int i, j;
    unsigned char ctr[AES_BLOCK_SIZE], ecr[AES_BLOCK_SIZE];
    unsigned long inc;

    memcpy(ctr, iv, AES_BLOCK_SIZE);
    ctr[12] &= 0x7f; ctr[8] &= 0x7f;
    inc = GETU32(ctr + 12);
    for (i = 0; i < lenp; i+=AES_BLOCK_SIZE) {
        AES_ecb_encrypt(ctr, ecr, &ctx->ctr_sched, AES_ENCRYPT);
        for (j = 0; j < AES_BLOCK_SIZE; j++) {
            if ((i + j) == lenp) {
                return;
            }
            c[i+j] = p[i+j] ^ ecr[j];
        }
        inc++; inc &= 0xffffffff;
        PUTU32(ctr + 12, inc);
    }
}

int
siv_encrypt (siv_ctx *ctx, const unsigned char *p, unsigned char *c,
             const int len, unsigned char *counter,
             const int nad, ...)
{
    va_list ap;
    unsigned char *ad;
    int adlen, numad = nad;
    unsigned char ctr[AES_BLOCK_SIZE];

    if (numad) {
        va_start(ap, nad);
        while (numad) {
            ad = va_arg(ap, char *);
            adlen = va_arg(ap, int);
            s2v_update(ctx, ad, adlen);
            numad--;
        }
    }
    s2v_final(ctx, p, len, ctr);
    memcpy(counter, ctr, AES_BLOCK_SIZE);
    siv_aes_ctr(ctx, p, len, c, ctr);
    siv_restart(ctx);
    return 1;
}

int
siv_decrypt (siv_ctx *ctx, const unsigned char *c, unsigned char *p,
             const int len, unsigned char *counter,
             const int nad, ...)
{
    va_list ap;
    unsigned char *ad;
    int adlen, numad = nad;
    unsigned char ctr[AES_BLOCK_SIZE];

    memcpy(ctr, counter, AES_BLOCK_SIZE);
    siv_aes_ctr(ctx, c, len, p, ctr);
    if (numad) {
        va_start(ap, nad);
        while (numad) {
            ad = va_arg(ap, char *);
            adlen = va_arg(ap, int);
            s2v_update(ctx, ad, adlen);
            numad--;
        }
    }
    s2v_final(ctx, p, len, ctr);

    siv_restart(ctx);
    if (memcmp(ctr, counter, AES_BLOCK_SIZE)) {
        memset(p, 0, len);
        return -1;
    } else {
        return 1;
    }
}
*/
import "C"
<commit_msg>Implemented reference dbl function.<commit_after>// Copyright 2012 Aaron Jacobs. All Rights Reserved.
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// The C code in this file was pulled on 2012-09-04 from the proposed SIV
// implementation for OpenSSL hosted on lounge.org:
//
//     http://www.lounge.org/siv_for_openssl.tgz
//
// It was modified by Aaron Jacobs to suit the gencases tool. These
// modifications and the Go code are copyright Aaron Jacobs. The original
// copyright notice is below.

package main

/*
 * Copyright (c) The Industrial Lounge, 2007
 *
 *  Copyright holder grants permission for redistribution and use in source
 *  and binary forms, with or without modification, provided that the
 *  following conditions are met:
 *     1. Redistribution of source code must retain the above copyright
 *        notice, this list of conditions, and the following disclaimer
 *        in all source files.
 *     2. Redistribution in binary form must retain the above copyright
 *        notice, this list of conditions, and the following disclaimer
 *        in the documentation and/or other materials provided with the
 *        distribution.
 *     3. All advertising materials and documentation mentioning features
 *	  or use of this software must display the following acknowledgement:
 *
 *        "This product includes software written by
 *         Dan Harkins (dharkins at lounge dot org)"
 *
 *  "DISCLAIMER OF LIABILITY
 *
 *  THIS SOFTWARE IS PROVIDED BY THE INDUSTRIAL LOUNGE ``AS IS''
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 *  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INDUSTRIAL LOUNGE BE LIABLE
 *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 *  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 *  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 *  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 *  SUCH DAMAGE."
 *
 * This license and distribution terms cannot be changed. In other words,
 * this code cannot simply be copied and put under another distribution
 * license (including the GNU public license).
 */

/*
#include <stdio.h>
#include <string.h>
#include <openssl/crypto.h>
#include <openssl/evp.h>
#include <openssl/aes.h>
#include "siv.h"
#include "aes_locl.h"

#define Rb		0x87

unsigned char zero[AES_BLOCK_SIZE] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

static void
xor (unsigned char *output, const unsigned char *input)
{
    int i;

    i = AES_BLOCK_SIZE - 1;
    do {
	output[i] ^= input[i];
	i--;
    } while (i >= 0);
    return;
}

static void
times_two (unsigned char *output, unsigned char *input)
{
    int i;
    unsigned char *out = output, *in = input;
    unsigned char carry = 0;

    out = output + AES_BLOCK_SIZE - 1;
    in = input + AES_BLOCK_SIZE - 1;
    for (i = 0; i < AES_BLOCK_SIZE; i++) {
	*(out--) = (*in << 1) | carry;
	carry = (*(in--) & 0x80) ? 1 : 0;
    }

    if (carry) {
	output[AES_BLOCK_SIZE-1] ^= Rb;
    }
    return;
}

static void
pad (unsigned char *buf, int len)
{
    int i;

    i = len;
    buf[i++] = 0x80;
    if (i < AES_BLOCK_SIZE) {
	memset(buf + i, 0, AES_BLOCK_SIZE - i);
    }
}

void
aes_cmac (siv_ctx *ctx, const unsigned char *msg, int mlen, unsigned char *C)
{
    int n, i, slop;
    unsigned char Mn[AES_BLOCK_SIZE], *ptr;

    memcpy(C, zero, AES_BLOCK_SIZE);

    n = (mlen+(AES_BLOCK_SIZE-1))/AES_BLOCK_SIZE;

    ptr = (unsigned char *)msg;
    for (i = 0; i < (n-1); i++) {
	xor(C, ptr);
	AES_ecb_encrypt(C, C, &ctx->s2v_sched, AES_ENCRYPT);
	ptr += AES_BLOCK_SIZE;
    }

    memset(Mn, 0, AES_BLOCK_SIZE);
    if ((slop = (mlen % AES_BLOCK_SIZE)) != 0) {
	memcpy(Mn, ptr, slop);
	pad(Mn, slop);
	xor(Mn, ctx->K2);
    } else {
	if (msg != NULL && mlen != 0) {
	    memcpy(Mn, ptr, AES_BLOCK_SIZE);
	    xor(Mn, ctx->K1);
	} else {
	    pad(Mn, 0);
	    xor(Mn, ctx->K2);
	}
    }
    xor(C, Mn);
    AES_ecb_encrypt(C, C, &ctx->s2v_sched, AES_ENCRYPT);
    return;
}

int
s2v_final (siv_ctx *ctx, const unsigned char *X, int xlen, unsigned char *digest)
{
    unsigned char T[AES_BLOCK_SIZE], C[AES_BLOCK_SIZE];
    unsigned char padX[AES_BLOCK_SIZE], *ptr;
    int blocks, i, slop;

    if (xlen < AES_BLOCK_SIZE) {
	memcpy(padX, X, xlen);
	pad(padX, xlen);

	times_two(T, ctx->T);
	xor(T, padX);
	aes_cmac(ctx, T, AES_BLOCK_SIZE, digest);
    } else {
        if (xlen == AES_BLOCK_SIZE) {
            memcpy(T, X, AES_BLOCK_SIZE);
            xor(T, ctx->T);
            aes_cmac(ctx, T, AES_BLOCK_SIZE, digest);
        } else {
            blocks = (xlen+(AES_BLOCK_SIZE-1))/AES_BLOCK_SIZE - 1;
            ptr = (unsigned char *)X;
            memcpy(C, zero, AES_BLOCK_SIZE);
            if (blocks > 1) {
                for (i = 0; i < (blocks-1); i++) {
                    xor(C, ptr);
                    AES_ecb_encrypt(C, C, &ctx->s2v_sched, AES_ENCRYPT);
                    ptr += AES_BLOCK_SIZE;
                }
            }
            memcpy(T, ptr, AES_BLOCK_SIZE);
            slop = xlen % AES_BLOCK_SIZE;
            if (slop) {
                for (i = 0; i < AES_BLOCK_SIZE - slop; i++) {
                    T[i + slop] ^= ctx->T[i];
                }
                xor(C, T);
                AES_ecb_encrypt(C, C, &ctx->s2v_sched, AES_ENCRYPT);
                ptr += AES_BLOCK_SIZE;
                memset(T, 0, AES_BLOCK_SIZE);
                memcpy(T, ptr, slop);
                for (i = 0; i < slop; i++) {
                    T[i] ^= ctx->T[(AES_BLOCK_SIZE-slop)+i];
                }
                pad(T, slop);
                xor(T, ctx->K2);
            } else {
                xor(C, ptr);
                AES_ecb_encrypt(C, C, &ctx->s2v_sched, AES_ENCRYPT);
                ptr += AES_BLOCK_SIZE;
                memcpy(T, ptr, AES_BLOCK_SIZE);
                xor(T, ctx->T);
                xor(T, ctx->K1);
            }
            xor(C, T);
            AES_ecb_encrypt(C, digest, &ctx->s2v_sched, AES_ENCRYPT);
        }

    }
    return 0;
}

void
s2v_add (siv_ctx *ctx, const unsigned char *Y)
{
    unsigned char T[AES_BLOCK_SIZE];

    memcpy(T, ctx->T, AES_BLOCK_SIZE);
    times_two(ctx->T, T);
    xor(ctx->T, Y);
}

void
s2v_update (siv_ctx *ctx, const unsigned char *X, int xlen)
{
    unsigned char Y[AES_BLOCK_SIZE];

    aes_cmac(ctx, X, xlen, Y);
    s2v_add(ctx, Y);
}

int
siv_init (siv_ctx *ctx, const unsigned char *key, int keylen)
{
    unsigned char L[AES_BLOCK_SIZE];

    memset((char *)ctx, 0, sizeof(siv_ctx));
    switch (keylen) {
        case SIV_512:
            AES_set_encrypt_key(key, 256, &ctx->s2v_sched);
            AES_set_encrypt_key(key+AES_256_BYTES, 256, &ctx->ctr_sched);
            break;
        case SIV_384:
            AES_set_encrypt_key(key, 192, &ctx->s2v_sched);
            AES_set_encrypt_key(key+AES_192_BYTES, 192, &ctx->ctr_sched);
            break;
        case SIV_256:
            AES_set_encrypt_key(key, 128, &ctx->s2v_sched);
            AES_set_encrypt_key(key+AES_128_BYTES, 128, &ctx->ctr_sched);
            break;
        default:
            return -1;
    }

    AES_ecb_encrypt(zero, L, &ctx->s2v_sched, AES_ENCRYPT);
    times_two(ctx->K1, L);
    times_two(ctx->K2, ctx->K1);

    memset(ctx->benchmark, 0, AES_BLOCK_SIZE);
    aes_cmac(ctx, zero, AES_BLOCK_SIZE, ctx->T);
    return 1;
}

void
siv_restart (siv_ctx *ctx)
{
    memset(ctx->benchmark, 0, AES_BLOCK_SIZE);
    memset(ctx->T, 0, AES_BLOCK_SIZE);
    aes_cmac(ctx, zero, AES_BLOCK_SIZE, ctx->T);
}

void
s2v_benchmark (siv_ctx *ctx)
{
    memcpy(ctx->benchmark, ctx->T, AES_BLOCK_SIZE);
}

void
s2v_reset (siv_ctx *ctx)
{
    memcpy(ctx->T, ctx->benchmark, AES_BLOCK_SIZE);
}

void
siv_aes_ctr (siv_ctx *ctx, const unsigned char *p, const int lenp,
             unsigned char *c, const unsigned char *iv)
{
    int i, j;
    unsigned char ctr[AES_BLOCK_SIZE], ecr[AES_BLOCK_SIZE];
    unsigned long inc;

    memcpy(ctr, iv, AES_BLOCK_SIZE);
    ctr[12] &= 0x7f; ctr[8] &= 0x7f;
    inc = GETU32(ctr + 12);
    for (i = 0; i < lenp; i+=AES_BLOCK_SIZE) {
        AES_ecb_encrypt(ctr, ecr, &ctx->ctr_sched, AES_ENCRYPT);
        for (j = 0; j < AES_BLOCK_SIZE; j++) {
            if ((i + j) == lenp) {
                return;
            }
            c[i+j] = p[i+j] ^ ecr[j];
        }
        inc++; inc &= 0xffffffff;
        PUTU32(ctr + 12, inc);
    }
}

int
siv_encrypt (siv_ctx *ctx, const unsigned char *p, unsigned char *c,
             const int len, unsigned char *counter,
             const int nad, ...)
{
    va_list ap;
    unsigned char *ad;
    int adlen, numad = nad;
    unsigned char ctr[AES_BLOCK_SIZE];

    if (numad) {
        va_start(ap, nad);
        while (numad) {
            ad = va_arg(ap, unsigned char *);
            adlen = va_arg(ap, int);
            s2v_update(ctx, ad, adlen);
            numad--;
        }
    }
    s2v_final(ctx, p, len, ctr);
    memcpy(counter, ctr, AES_BLOCK_SIZE);
    siv_aes_ctr(ctx, p, len, c, ctr);
    siv_restart(ctx);
    return 1;
}

int
siv_decrypt (siv_ctx *ctx, const unsigned char *c, unsigned char *p,
             const int len, unsigned char *counter,
             const int nad, ...)
{
    va_list ap;
    unsigned char *ad;
    int adlen, numad = nad;
    unsigned char ctr[AES_BLOCK_SIZE];

    memcpy(ctr, counter, AES_BLOCK_SIZE);
    siv_aes_ctr(ctx, c, len, p, ctr);
    if (numad) {
        va_start(ap, nad);
        while (numad) {
            ad = va_arg(ap, unsigned char *);
            adlen = va_arg(ap, int);
            s2v_update(ctx, ad, adlen);
            numad--;
        }
    }
    s2v_final(ctx, p, len, ctr);

    siv_restart(ctx);
    if (memcmp(ctr, counter, AES_BLOCK_SIZE)) {
        memset(p, 0, len);
        return -1;
    } else {
        return 1;
    }
}
*/
import "C"

import (
	"unsafe"
)

func dbl(buf []byte) []byte {
	if len(buf) != 16 {
		panic("Invalid length.")
	}

	cOutput := (*C.uchar)(C.malloc(16))
	defer C.free(unsafe.Pointer(cOutput))

	C.times_two((*C.uchar)(&buf[0]), cOutput)

	return C.GoBytes(unsafe.Pointer(cOutput), 16)
}
<|endoftext|>


<commit_before>package gallium

/*
#cgo CFLAGS: -mmacosx-version-min=10.8
#cgo LDFLAGS: -mmacosx-version-min=10.8

#include <stdlib.h>
#include "lib/api/gallium.h"
#include "lib/api/menu.h"

//#include "_cgo_export.h"

extern void cgo_onMenuClicked(void*);

static inline gallium_nsmenuitem_t* helper_NSMenu_AddMenuItem(
	gallium_nsmenu_t* menu,
	const char* title,
	const char* keyEquivalent,
	int id) {

	int *idholder = (int*)malloc(sizeof(int));
	*idholder = id;
	return NSMenu_AddMenuItem(menu, title, keyEquivalent, &cgo_onMenuClicked, idholder);
}

*/
import "C"
import "unsafe"

type MenuEntry interface {
	menu()
}

type MenuItem struct {
	Title    string
	Shortcut string
	OnClick  func()
}

func (MenuItem) menu() {}

type Menu struct {
	Title   string
	Entries []MenuEntry
}

func (Menu) menu() {}

var menu *menuManager

func SetMenu(menus []Menu) {
	menu = newMenuManager()
	root := C.NSMenu_New(C.CString("<root>"))
	for _, m := range menus {
		menu.add(m, root)
	}
	C.NSApplication_SetMainMenu(C.NSApplication_SharedApplication(), root)
}

//export cgo_onMenuClicked
func cgo_onMenuClicked(data unsafe.Pointer) {
	logger.Println("in cgo_onMenuClicked")

	if menu == nil {
		logger.Println("onMenuClicked called but menu manager was nil")
		return
	}

	if data == nil {
		logger.Println("onMenuClicked called but data parameter was nil")
		return
	}

	id := *(*int)(data)
	logger.Printf("cgo_onMenuClicked: id=%d", id)

	item, found := menu.items[id]
	if !found {
		logger.Printf("onMenuClicked received non-existent ID %d", id)
		return
	}

	if item.OnClick == nil {
		logger.Printf("onMenuClicked found item with nil OnClick: %s", item.Title)
		return
	}

	item.OnClick()
}

type menuManager struct {
	items map[int]MenuItem
}

func newMenuManager() *menuManager {
	return &menuManager{make(map[int]MenuItem)}
}

func (m *menuManager) add(menu MenuEntry, parent *C.gallium_nsmenu_t) {
	switch menu := menu.(type) {
	case Menu:
		item := C.NSMenu_AddMenuItem(parent, C.CString(menu.Title), C.CString(""), nil, nil)
		submenu := C.NSMenu_New(C.CString(menu.Title))
		C.NSMenuItem_SetSubmenu(item, submenu)
		for _, entry := range menu.Entries {
			m.add(entry, submenu)
		}
	case MenuItem:
		id := len(m.items)
		m.items[id] = menu
		C.helper_NSMenu_AddMenuItem(parent, C.CString(menu.Title), C.CString(menu.Shortcut), C.int(id))
	default:
		logger.Printf("unexpected menu entry: %T", menu)
	}
}

func RunApplication() {
	logger.Println("in RunApplication")
	C.NSApplication_Run(C.NSApplication_SharedApplication())
}
<commit_msg>allocate ID in go<commit_after>package gallium

/*
#cgo CFLAGS: -mmacosx-version-min=10.8
#cgo LDFLAGS: -mmacosx-version-min=10.8

#include <stdlib.h>
#include "lib/api/gallium.h"
#include "lib/api/menu.h"

// It does not seem that we can import "_cgo_export.h" from here
extern void cgo_onMenuClicked(void*);

// This is a wrapper around NSMenu_AddMenuItem that adds the function pointer
// argument, since this does not seem to be possible from Go directly.
static inline gallium_nsmenuitem_t* helper_NSMenu_AddMenuItem(
	gallium_nsmenu_t* menu,
	const char* title,
	const char* keyEquivalent,
	void *callbackArg) {

	return NSMenu_AddMenuItem(menu, title, keyEquivalent, &cgo_onMenuClicked, callbackArg);
}

*/
import "C"
import "unsafe"

type MenuEntry interface {
	menu()
}

type MenuItem struct {
	Title    string
	Shortcut string
	OnClick  func()
}

func (MenuItem) menu() {}

type Menu struct {
	Title   string
	Entries []MenuEntry
}

func (Menu) menu() {}

var menu *menuManager

func SetMenu(menus []Menu) {
	menu = newMenuManager()
	root := C.NSMenu_New(C.CString("<root>"))
	for _, m := range menus {
		menu.add(m, root)
	}
	C.NSApplication_SetMainMenu(C.NSApplication_SharedApplication(), root)
}

//export cgo_onMenuClicked
func cgo_onMenuClicked(data unsafe.Pointer) {
	logger.Println("in cgo_onMenuClicked")

	if menu == nil {
		logger.Println("onMenuClicked called but menu manager was nil")
		return
	}

	if data == nil {
		logger.Println("onMenuClicked called but data parameter was nil")
		return
	}

	id := *(*int)(data)
	logger.Printf("cgo_onMenuClicked: id=%d", id)

	item, found := menu.items[id]
	if !found {
		logger.Printf("onMenuClicked received non-existent ID %d", id)
		return
	}

	if item.OnClick == nil {
		logger.Printf("onMenuClicked found item with nil OnClick: %s", item.Title)
		return
	}

	item.OnClick()
}

type menuManager struct {
	items map[int]MenuItem
}

func newMenuManager() *menuManager {
	return &menuManager{make(map[int]MenuItem)}
}

func (m *menuManager) add(menu MenuEntry, parent *C.gallium_nsmenu_t) {
	switch menu := menu.(type) {
	case Menu:
		item := C.NSMenu_AddMenuItem(parent, C.CString(menu.Title), C.CString(""), nil, nil)
		submenu := C.NSMenu_New(C.CString(menu.Title))
		C.NSMenuItem_SetSubmenu(item, submenu)
		for _, entry := range menu.Entries {
			m.add(entry, submenu)
		}
	case MenuItem:
		id := len(m.items)
		m.items[id] = menu

		callbackArg := C.malloc(C.sizeof_int)
		*(*C.int)(callbackArg) = C.int(id)

		C.helper_NSMenu_AddMenuItem(parent, C.CString(menu.Title), C.CString(menu.Shortcut), callbackArg)
	default:
		logger.Printf("unexpected menu entry: %T", menu)
	}
}

func RunApplication() {
	logger.Println("in RunApplication")
	C.NSApplication_Run(C.NSApplication_SharedApplication())
}
<|endoftext|>


<commit_before>package aws

import (
	"fmt"
	"log"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/cloudfront"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/helper/schema"
)

func resourceAwsCloudFrontPublicKey() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsCloudFrontPublicKeyCreate,
		Read:   resourceAwsCloudFrontPublicKeyRead,
		Update: resourceAwsCloudFrontPublicKeyUpdate,
		Delete: resourceAwsCloudFrontPublicKeyDelete,

		Schema: map[string]*schema.Schema{
			"name": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
				//ForceNew:      true,
				ConflictsWith: []string{"name_prefix"},
				ValidateFunc:  validateCloudFrontPublicKeyName,
			},
			"name_prefix": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
				//ForceNew:      true,
				ConflictsWith: []string{"name"},
				ValidateFunc:  validateCloudFrontPublicKeyNamePrefix,
			},
			"encoded_key": {
				Type:     schema.TypeString,
				Required: true,
				//ForceNew: true,
			},
			"comment": {
				Type:     schema.TypeString,
				Optional: true,
			},
			"etag": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"id": {
				Type:     schema.TypeString,
				Computed: true,
			},
		},
	}
}

func resourceAwsCloudFrontPublicKeyCreate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).cloudfrontconn

	if v, ok := d.GetOk("name"); ok {
		d.Set("name", v.(string))
	} else if v, ok := d.GetOk("name_prefix"); ok {
		d.Set("name", resource.PrefixedUniqueId(v.(string)))
	} else {
		d.Set("name", resource.PrefixedUniqueId("tf-"))
	}

	request := &cloudfront.CreatePublicKeyInput{
		PublicKeyConfig: expandPublicKeyConfig(d),
	}

	log.Println("[DEBUG] Create CloudFront PublicKey:", request)

	output, err := conn.CreatePublicKey(request)
	if err != nil {
		return fmt.Errorf("error creating CloudFront PublicKey: %s", err)
	}

	d.SetId(aws.StringValue(output.PublicKey.Id))
	return resourceAwsCloudFrontPublicKeyRead(d, meta)
}

func resourceAwsCloudFrontPublicKeyRead(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).cloudfrontconn
	request := &cloudfront.GetPublicKeyInput{
		Id: aws.String(d.Id()),
	}

	output, err := conn.GetPublicKey(request)
	if err != nil {
		if isAWSErr(err, cloudfront.ErrCodeNoSuchPublicKey, "") {
			log.Printf("[WARN] No PublicKey found: %s, removing from state", d.Id())
			d.SetId("")
			return nil
		}
		return err
	}

	var publicKeyConfig *cloudfront.PublicKeyConfig
	publicKeyConfig = output.PublicKey.PublicKeyConfig

	d.Set("encoded_key", publicKeyConfig.EncodedKey)
	d.Set("name", publicKeyConfig.Name)
	if publicKeyConfig.Comment != nil {
		d.Set("comment", publicKeyConfig.Comment)
	}

	d.Set("etag", output.ETag)

	return nil
}

func resourceAwsCloudFrontPublicKeyUpdate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).cloudfrontconn
	request := &cloudfront.UpdatePublicKeyInput{
		Id:              aws.String(d.Id()),
		PublicKeyConfig: expandPublicKeyConfig(d),
		IfMatch:         aws.String(d.Get("etag").(string)),
	}

	_, err := conn.UpdatePublicKey(request)
	if err != nil {
		return fmt.Errorf("error updating CloudFront PublicKey (%s): %s", d.Id(), err)
	}

	return resourceAwsCloudFrontPublicKeyRead(d, meta)
}

func expandPublicKeyConfig(d *schema.ResourceData) *cloudfront.PublicKeyConfig {
	publicKeyConfig := &cloudfront.PublicKeyConfig{
		CallerReference: aws.String(resource.UniqueId()),
		EncodedKey:      aws.String(d.Get("encoded_key").(string)),
		Name:            aws.String(d.Get("name").(string)),
	}

	if v, ok := d.GetOk("comment"); ok {
		publicKeyConfig.Comment = aws.String(v.(string))
	}

	return publicKeyConfig
}
<commit_msg>add delete func<commit_after>package aws

import (
	"fmt"
	"log"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/cloudfront"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/helper/schema"
)

func resourceAwsCloudFrontPublicKey() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsCloudFrontPublicKeyCreate,
		Read:   resourceAwsCloudFrontPublicKeyRead,
		Update: resourceAwsCloudFrontPublicKeyUpdate,
		Delete: resourceAwsCloudFrontPublicKeyDelete,

		Schema: map[string]*schema.Schema{
			"name": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
				//ForceNew:      true,
				ConflictsWith: []string{"name_prefix"},
				ValidateFunc:  validateCloudFrontPublicKeyName,
			},
			"name_prefix": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
				//ForceNew:      true,
				ConflictsWith: []string{"name"},
				ValidateFunc:  validateCloudFrontPublicKeyNamePrefix,
			},
			"encoded_key": {
				Type:     schema.TypeString,
				Required: true,
				//ForceNew: true,
			},
			"comment": {
				Type:     schema.TypeString,
				Optional: true,
			},
			"etag": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"id": {
				Type:     schema.TypeString,
				Computed: true,
			},
		},
	}
}

func resourceAwsCloudFrontPublicKeyCreate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).cloudfrontconn

	if v, ok := d.GetOk("name"); ok {
		d.Set("name", v.(string))
	} else if v, ok := d.GetOk("name_prefix"); ok {
		d.Set("name", resource.PrefixedUniqueId(v.(string)))
	} else {
		d.Set("name", resource.PrefixedUniqueId("tf-"))
	}

	request := &cloudfront.CreatePublicKeyInput{
		PublicKeyConfig: expandPublicKeyConfig(d),
	}

	log.Println("[DEBUG] Create CloudFront PublicKey:", request)

	output, err := conn.CreatePublicKey(request)
	if err != nil {
		return fmt.Errorf("error creating CloudFront PublicKey: %s", err)
	}

	d.SetId(aws.StringValue(output.PublicKey.Id))
	return resourceAwsCloudFrontPublicKeyRead(d, meta)
}

func resourceAwsCloudFrontPublicKeyRead(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).cloudfrontconn
	request := &cloudfront.GetPublicKeyInput{
		Id: aws.String(d.Id()),
	}

	output, err := conn.GetPublicKey(request)
	if err != nil {
		if isAWSErr(err, cloudfront.ErrCodeNoSuchPublicKey, "") {
			log.Printf("[WARN] No PublicKey found: %s, removing from state", d.Id())
			d.SetId("")
			return nil
		}
		return err
	}

	var publicKeyConfig *cloudfront.PublicKeyConfig
	publicKeyConfig = output.PublicKey.PublicKeyConfig

	d.Set("encoded_key", publicKeyConfig.EncodedKey)
	d.Set("name", publicKeyConfig.Name)
	if publicKeyConfig.Comment != nil {
		d.Set("comment", publicKeyConfig.Comment)
	}

	d.Set("etag", output.ETag)

	return nil
}

func resourceAwsCloudFrontPublicKeyUpdate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).cloudfrontconn

	request := &cloudfront.UpdatePublicKeyInput{
		Id:              aws.String(d.Id()),
		PublicKeyConfig: expandPublicKeyConfig(d),
		IfMatch:         aws.String(d.Get("etag").(string)),
	}

	_, err := conn.UpdatePublicKey(request)
	if err != nil {
		return fmt.Errorf("error updating CloudFront PublicKey (%s): %s", d.Id(), err)
	}

	return resourceAwsCloudFrontPublicKeyRead(d, meta)
}

func resourceAwsCloudFrontPublicKeyDelete(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).cloudfrontconn

	request := &cloudfront.DeletePublicKeyInput{
		Id:      aws.String(d.Id()),
		IfMatch: aws.String(d.Get("etag").(string)),
	}

	_, err := conn.DeletePublicKey(request)
	if err != nil {
		if isAWSErr(err, cloudfront.ErrCodeNoSuchPublicKey, "") {
			log.Printf("[WARN] No PublicKey found: %s, removing from state", d.Id())
			d.SetId("")
			return nil
		}
		return err
	}

	return nil
}

func expandPublicKeyConfig(d *schema.ResourceData) *cloudfront.PublicKeyConfig {
	publicKeyConfig := &cloudfront.PublicKeyConfig{
		CallerReference: aws.String(resource.UniqueId()),
		EncodedKey:      aws.String(d.Get("encoded_key").(string)),
		Name:            aws.String(d.Get("name").(string)),
	}

	if v, ok := d.GetOk("comment"); ok {
		publicKeyConfig.Comment = aws.String(v.(string))
	}

	return publicKeyConfig
}
<|endoftext|>


<commit_before>package aws

import (
	"fmt"
	"testing"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/guardduty"
	"github.com/hashicorp/terraform/helper/acctest"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
	"regexp"
	"strconv"
)

func testAccAwsGuardDutyMember_basic(t *testing.T) {
	resourceName := "aws_guardduty_member.test"
	accountID := "111111111111"
	email := "required@example.com"
	invitationMessage := "inviting"

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAwsGuardDutyMemberDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccGuardDutyMemberConfig_basic1(accountID, email),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAwsGuardDutyMemberExists(resourceName),
					resource.TestCheckResourceAttr(resourceName, "account_id", accountID),
					resource.TestCheckResourceAttrSet(resourceName, "detector_id"),
					resource.TestCheckResourceAttr(resourceName, "email", email),
					resource.TestCheckResourceAttr(resourceName, "invite", strconv.FormatBool(true)),
				),
			},
			{
				Config: testAccGuardDutyMemberConfig_basic2(accountID, email, invitationMessage, false),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAwsGuardDutyMemberExists(resourceName),
					resource.TestCheckResourceAttr(resourceName, "account_id", accountID),
					resource.TestCheckResourceAttrSet(resourceName, "detector_id"),
					resource.TestCheckResourceAttr(resourceName, "email", email),
					resource.TestCheckResourceAttr(resourceName, "invite", strconv.FormatBool(false)),
					resource.TestCheckResourceAttr(resourceName, "invitation_message", invitationMessage),
				),
			},
		},
	})
}

func testAccAwsGuardDutyMember_import(t *testing.T) {
	resourceName := "aws_guardduty_member.test"

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAwsGuardDutyMemberDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccGuardDutyMemberConfig_basic1("111111111111", "required@example.com"),
			},

			{
				ResourceName:      resourceName,
				ImportState:       true,
				ImportStateVerify: true,
			},
		},
	})
}

func testAccAwsGuardDutyMemberInvitation_timeout(t *testing.T) {

	rEmail := acctest.RandString(10) + "@" + acctest.RandString(5) + ".com"

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAwsGuardDutyMemberDestroy,
		Steps: []resource.TestStep{
			{
				Config:      testAccGuardDutyMemberConfig_basic2("111111111111", rEmail, "test", true),
				ExpectError: regexp.MustCompile("Expected member to be invited but was in state: EmailVerificationFailed"),
			},
		},
	})
}

func testAccCheckAwsGuardDutyMemberDestroy(s *terraform.State) error {
	conn := testAccProvider.Meta().(*AWSClient).guarddutyconn

	for _, rs := range s.RootModule().Resources {
		if rs.Type != "aws_guardduty_member" {
			continue
		}

		accountID, detectorID, err := decodeGuardDutyMemberID(rs.Primary.ID)
		if err != nil {
			return err
		}

		input := &guardduty.GetMembersInput{
			AccountIds: []*string{aws.String(accountID)},
			DetectorId: aws.String(detectorID),
		}

		gmo, err := conn.GetMembers(input)
		if err != nil {
			if isAWSErr(err, guardduty.ErrCodeBadRequestException, "The request is rejected because the input detectorId is not owned by the current account.") {
				return nil
			}
			return err
		}

		if len(gmo.Members) < 1 {
			continue
		}

		return fmt.Errorf("Expected GuardDuty Detector to be destroyed, %s found", rs.Primary.ID)
	}

	return nil
}

func testAccCheckAwsGuardDutyMemberExists(name string) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		rs, ok := s.RootModule().Resources[name]
		if !ok {
			return fmt.Errorf("Not found: %s", name)
		}

		accountID, detectorID, err := decodeGuardDutyMemberID(rs.Primary.ID)
		if err != nil {
			return err
		}

		input := &guardduty.GetMembersInput{
			AccountIds: []*string{aws.String(accountID)},
			DetectorId: aws.String(detectorID),
		}

		conn := testAccProvider.Meta().(*AWSClient).guarddutyconn
		gmo, err := conn.GetMembers(input)
		if err != nil {
			return err
		}

		if len(gmo.Members) < 1 {
			return fmt.Errorf("Not found: %s", name)
		}

		return nil
	}
}

func testAccGuardDutyMemberConfig_basic1(accountID, email string) string {
	return fmt.Sprintf(`
%[1]s

resource "aws_guardduty_member" "test" {
  account_id  = "%[2]s"
  detector_id = "${aws_guardduty_detector.test.id}"
  email       = "%[3]s"
}
`, testAccGuardDutyDetectorConfig_basic1, accountID, email)
}

func testAccGuardDutyMemberConfig_basic2(accountID, email, invitationMessage string, invite bool) string {
	return fmt.Sprintf(`
%[1]s

resource "aws_guardduty_member" "test" {
  account_id  = "%[2]s"
  detector_id = "${aws_guardduty_detector.test.id}"
  email       = "%[3]s"
  invite      = "%[4]s"
  invite      = "%[5]s"
}
`, testAccGuardDutyDetectorConfig_basic1, accountID, email, strconv.FormatBool(invite), invitationMessage)
}
<commit_msg>simplified testcase<commit_after>package aws

import (
	"fmt"
	"testing"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/guardduty"
	"github.com/hashicorp/terraform/helper/acctest"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
	"regexp"
)

func TestAccAwsGuardDutyMember_basic(t *testing.T) {
	resourceName := "aws_guardduty_member.test"
	accountID := "111111111111"
	email := "required@example.com"
	invite := "true"
	invitationMessage := "inviting"

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAwsGuardDutyMemberDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccGuardDutyMemberConfig_basic1(accountID, email),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAwsGuardDutyMemberExists(resourceName),
					resource.TestCheckResourceAttr(resourceName, "account_id", accountID),
					resource.TestCheckResourceAttrSet(resourceName, "detector_id"),
					resource.TestCheckResourceAttr(resourceName, "email", email),
				),
			},
			{
				Config: testAccGuardDutyMemberConfig_basic2(accountID, email, invitationMessage, invite),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAwsGuardDutyMemberExists(resourceName),
					resource.TestCheckResourceAttr(resourceName, "account_id", accountID),
					resource.TestCheckResourceAttrSet(resourceName, "detector_id"),
					resource.TestCheckResourceAttr(resourceName, "email", email),
					resource.TestCheckResourceAttr(resourceName, "invite", invite),
					resource.TestCheckResourceAttr(resourceName, "invitation_message", invitationMessage),
				),
			},
		},
	})
}

func testAccAwsGuardDutyMember_import(t *testing.T) {
	resourceName := "aws_guardduty_member.test"

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAwsGuardDutyMemberDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccGuardDutyMemberConfig_basic1("111111111111", "required@example.com"),
			},

			{
				ResourceName:      resourceName,
				ImportState:       true,
				ImportStateVerify: true,
			},
		},
	})
}

func testAccAwsGuardDutyMemberInvitation_timeout(t *testing.T) {

	rEmail := acctest.RandString(10) + "@" + acctest.RandString(5) + ".com"

	resource.Test(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAwsGuardDutyMemberDestroy,
		Steps: []resource.TestStep{
			{
				Config:      testAccGuardDutyMemberConfig_basic2("111111111111", rEmail, "test", "true"),
				ExpectError: regexp.MustCompile("Expected member to be invited but was in state: EmailVerificationFailed"),
			},
		},
	})
}

func testAccCheckAwsGuardDutyMemberDestroy(s *terraform.State) error {
	conn := testAccProvider.Meta().(*AWSClient).guarddutyconn

	for _, rs := range s.RootModule().Resources {
		if rs.Type != "aws_guardduty_member" {
			continue
		}

		accountID, detectorID, err := decodeGuardDutyMemberID(rs.Primary.ID)
		if err != nil {
			return err
		}

		input := &guardduty.GetMembersInput{
			AccountIds: []*string{aws.String(accountID)},
			DetectorId: aws.String(detectorID),
		}

		gmo, err := conn.GetMembers(input)
		if err != nil {
			if isAWSErr(err, guardduty.ErrCodeBadRequestException, "The request is rejected because the input detectorId is not owned by the current account.") {
				return nil
			}
			return err
		}

		if len(gmo.Members) < 1 {
			continue
		}

		return fmt.Errorf("Expected GuardDuty Detector to be destroyed, %s found", rs.Primary.ID)
	}

	return nil
}

func testAccCheckAwsGuardDutyMemberExists(name string) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		rs, ok := s.RootModule().Resources[name]
		if !ok {
			return fmt.Errorf("Not found: %s", name)
		}

		accountID, detectorID, err := decodeGuardDutyMemberID(rs.Primary.ID)
		if err != nil {
			return err
		}

		input := &guardduty.GetMembersInput{
			AccountIds: []*string{aws.String(accountID)},
			DetectorId: aws.String(detectorID),
		}

		conn := testAccProvider.Meta().(*AWSClient).guarddutyconn
		gmo, err := conn.GetMembers(input)
		if err != nil {
			return err
		}

		if len(gmo.Members) < 1 {
			return fmt.Errorf("Not found: %s", name)
		}

		return nil
	}
}

func testAccGuardDutyMemberConfig_basic1(accountID, email string) string {
	return fmt.Sprintf(`
%[1]s

resource "aws_guardduty_member" "test" {
  account_id  = "%[2]s"
  detector_id = "${aws_guardduty_detector.test.id}"
  email       = "%[3]s"
}
`, testAccGuardDutyDetectorConfig_basic1, accountID, email)
}

func testAccGuardDutyMemberConfig_basic2(accountID, email, invite, invitationMessage string) string {
	return fmt.Sprintf(`
%[1]s

resource "aws_guardduty_member" "test" {
  account_id  = "%[2]s"
  detector_id = "${aws_guardduty_detector.test.id}"
  email       = "%[3]s"
  invite      = "%[4]s"
  invite      = "%[5]s"
}
`, testAccGuardDutyDetectorConfig_basic1, accountID, email, invite, invitationMessage)
}
<|endoftext|>


<commit_before>package aws

import (
	"fmt"
	"log"
	"regexp"
	"time"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/awserr"
	"github.com/aws/aws-sdk-go/service/organizations"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/helper/schema"
	"github.com/hashicorp/terraform/helper/validation"
)

func resourceAwsOrganizationsAccount() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsOrganizationsAccountCreate,
		Read:   resourceAwsOrganizationsAccountRead,
		Delete: resourceAwsOrganizationsAccountDelete,
		Importer: &schema.ResourceImporter{
			State: schema.ImportStatePassthrough,
		},

		Schema: map[string]*schema.Schema{
			"arn": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"joined_method": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"joined_timestamp": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"status": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"name": {
				ForceNew:     true,
				Type:         schema.TypeString,
				Required:     true,
				ValidateFunc: validation.StringLenBetween(1, 50),
			},
			"email": {
				ForceNew:     true,
				Type:         schema.TypeString,
				Required:     true,
				ValidateFunc: validateAwsOrganizationsAccountEmail,
			},
			"iam_user_access_to_billing": {
				ForceNew:     true,
				Type:         schema.TypeString,
				Optional:     true,
				ValidateFunc: validation.StringInSlice([]string{organizations.IAMUserAccessToBillingAllow, organizations.IAMUserAccessToBillingDeny}, true),
			},
			"role_name": {
				ForceNew:     true,
				Type:         schema.TypeString,
				Optional:     true,
				ValidateFunc: validateAwsOrganizationsAccountRoleName,
			},
		},
	}
}

func resourceAwsOrganizationsAccountCreate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).organizationsconn

	// Create the account
	createOpts := &organizations.CreateAccountInput{
		AccountName: aws.String(d.Get("name").(string)),
		Email:       aws.String(d.Get("email").(string)),
	}
	if role, ok := d.GetOk("role_name"); ok {
		createOpts.RoleName = aws.String(role.(string))
	}

	if iam_user, ok := d.GetOk("iam_user_access_to_billing"); ok {
		createOpts.IamUserAccessToBilling = aws.String(iam_user.(string))
	}

	log.Printf("[DEBUG] Account create config: %#v", createOpts)

	var err error
	var resp *organizations.CreateAccountOutput
	err = resource.Retry(4*time.Minute, func() *resource.RetryError {
		resp, err = conn.CreateAccount(createOpts)

		if err != nil {
			ec2err, ok := err.(awserr.Error)
			if !ok {
				return resource.NonRetryableError(err)
			}
			if isAWSErr(ec2err, organizations.ErrCodeFinalizingOrganizationException, "") {
				log.Printf("[DEBUG] Trying to create account again: %q", ec2err.Message())
				return resource.RetryableError(err)
			}

			return resource.NonRetryableError(err)
		}

		return nil
	})

	if err != nil {
		return fmt.Errorf("Error creating account: %s", err)
	}
	log.Printf("[DEBUG] Account create response: %#v", resp)

	requestId := *resp.CreateAccountStatus.Id

	// Wait for the account to become available
	log.Printf("[DEBUG] Waiting for account request (%s) to succeed", requestId)

	stateConf := &resource.StateChangeConf{
		Pending:      []string{organizations.CreateAccountStateInProgress},
		Target:       []string{organizations.CreateAccountStateSucceeded},
		Refresh:      resourceAwsOrganizationsAccountStateRefreshFunc(conn, requestId),
		PollInterval: 10 * time.Second,
		Timeout:      5 * time.Minute,
	}
	stateResp, stateErr := stateConf.WaitForState()
	if stateErr != nil {
		return fmt.Errorf(
			"Error waiting for account request (%s) to become available: %s",
			requestId, stateErr)
	}

	// Store the ID
	accountId := stateResp.(*organizations.CreateAccountStatus).AccountId
	d.SetId(*accountId)

	return resourceAwsOrganizationsAccountRead(d, meta)
}

func resourceAwsOrganizationsAccountRead(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).organizationsconn
	describeOpts := &organizations.DescribeAccountInput{
		AccountId: aws.String(d.Id()),
	}
	resp, err := conn.DescribeAccount(describeOpts)
	if err != nil {
		if isAWSErr(err, organizations.ErrCodeAccountNotFoundException, "") {
			log.Printf("[WARN] Account does not exist, removing from state: %s", d.Id())
			d.SetId("")
			return nil
		}
		return err
	}

	d.Set("arn", resp.Account.Arn)
	d.Set("joined_method", resp.Account.JoinedMethod)
	d.Set("joined_timestamp", resp.Account.JoinedTimestamp)
	d.Set("name", resp.Account.Name)
	d.Set("status", resp.Account.Status)
	return nil
}

func resourceAwsOrganizationsAccountDelete(d *schema.ResourceData, meta interface{}) error {
	log.Printf("[WARN] Organization member accounts must be deleted from the web console.")
	return nil
}

// resourceAwsOrganizationsAccountStateRefreshFunc returns a resource.StateRefreshFunc
// that is used to watch a CreateAccount request
func resourceAwsOrganizationsAccountStateRefreshFunc(conn *organizations.Organizations, id string) resource.StateRefreshFunc {
	return func() (interface{}, string, error) {
		opts := &organizations.DescribeCreateAccountStatusInput{
			CreateAccountRequestId: aws.String(id),
		}
		resp, err := conn.DescribeCreateAccountStatus(opts)
		if err != nil {
			if isAWSErr(err, organizations.ErrCodeCreateAccountStatusNotFoundException, "") {
				resp = nil
			} else {
				log.Printf("Error on OrganizationAccountStateRefresh: %s", err)
				return nil, "", err
			}
		}

		if resp == nil {
			// Sometimes AWS just has consistency issues and doesn't see
			// our account yet. Return an empty state.
			return nil, "", nil
		}

		accountStatus := resp.CreateAccountStatus
		if *accountStatus.State == organizations.CreateAccountStateFailed {
			return nil, *accountStatus.State, fmt.Errorf(*accountStatus.FailureReason)
		}
		return accountStatus, *accountStatus.State, nil
	}
}

func validateAwsOrganizationsAccountEmail(v interface{}, k string) (ws []string, errors []error) {
	value := v.(string)
	if !regexp.MustCompile(`^[^\s@]+@[^\s@]+\.[^\s@]+$`).MatchString(value) {
		errors = append(errors, fmt.Errorf(
			"%q must be a valid email address", value))
	}

	if len(value) < 6 {
		errors = append(errors, fmt.Errorf(
			"%q cannot be less than 6 characters", value))
	}

	if len(value) > 64 {
		errors = append(errors, fmt.Errorf(
			"%q cannot be greater than 64 characters", value))
	}

	return
}

func validateAwsOrganizationsAccountRoleName(v interface{}, k string) (ws []string, errors []error) {
	value := v.(string)
	if !regexp.MustCompile(`^[\w+=,.@-]{1,64}$`).MatchString(value) {
		errors = append(errors, fmt.Errorf(
			"%q must consist of uppercase letters, lowercase letters, digits with no spaces, and any of the following characters: =,.@-", value))
	}

	return
}
<commit_msg>Fix refactoring gone wrong. Should have just used isAWSErr helper but accidentally left in the old awserr check.<commit_after>package aws

import (
	"fmt"
	"log"
	"regexp"
	"time"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/organizations"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/helper/schema"
	"github.com/hashicorp/terraform/helper/validation"
)

func resourceAwsOrganizationsAccount() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsOrganizationsAccountCreate,
		Read:   resourceAwsOrganizationsAccountRead,
		Delete: resourceAwsOrganizationsAccountDelete,
		Importer: &schema.ResourceImporter{
			State: schema.ImportStatePassthrough,
		},

		Schema: map[string]*schema.Schema{
			"arn": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"joined_method": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"joined_timestamp": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"status": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"name": {
				ForceNew:     true,
				Type:         schema.TypeString,
				Required:     true,
				ValidateFunc: validation.StringLenBetween(1, 50),
			},
			"email": {
				ForceNew:     true,
				Type:         schema.TypeString,
				Required:     true,
				ValidateFunc: validateAwsOrganizationsAccountEmail,
			},
			"iam_user_access_to_billing": {
				ForceNew:     true,
				Type:         schema.TypeString,
				Optional:     true,
				ValidateFunc: validation.StringInSlice([]string{organizations.IAMUserAccessToBillingAllow, organizations.IAMUserAccessToBillingDeny}, true),
			},
			"role_name": {
				ForceNew:     true,
				Type:         schema.TypeString,
				Optional:     true,
				ValidateFunc: validateAwsOrganizationsAccountRoleName,
			},
		},
	}
}

func resourceAwsOrganizationsAccountCreate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).organizationsconn

	// Create the account
	createOpts := &organizations.CreateAccountInput{
		AccountName: aws.String(d.Get("name").(string)),
		Email:       aws.String(d.Get("email").(string)),
	}
	if role, ok := d.GetOk("role_name"); ok {
		createOpts.RoleName = aws.String(role.(string))
	}

	if iam_user, ok := d.GetOk("iam_user_access_to_billing"); ok {
		createOpts.IamUserAccessToBilling = aws.String(iam_user.(string))
	}

	log.Printf("[DEBUG] Account create config: %#v", createOpts)

	var err error
	var resp *organizations.CreateAccountOutput
	err = resource.Retry(4*time.Minute, func() *resource.RetryError {
		resp, err = conn.CreateAccount(createOpts)

		if err != nil {
			if isAWSErr(err, organizations.ErrCodeFinalizingOrganizationException, "") {
				log.Printf("[DEBUG] Trying to create account again: %q", err.Error())
				return resource.RetryableError(err)
			}

			return resource.NonRetryableError(err)
		}

		return nil
	})

	if err != nil {
		return fmt.Errorf("Error creating account: %s", err)
	}
	log.Printf("[DEBUG] Account create response: %#v", resp)

	requestId := *resp.CreateAccountStatus.Id

	// Wait for the account to become available
	log.Printf("[DEBUG] Waiting for account request (%s) to succeed", requestId)

	stateConf := &resource.StateChangeConf{
		Pending:      []string{organizations.CreateAccountStateInProgress},
		Target:       []string{organizations.CreateAccountStateSucceeded},
		Refresh:      resourceAwsOrganizationsAccountStateRefreshFunc(conn, requestId),
		PollInterval: 10 * time.Second,
		Timeout:      5 * time.Minute,
	}
	stateResp, stateErr := stateConf.WaitForState()
	if stateErr != nil {
		return fmt.Errorf(
			"Error waiting for account request (%s) to become available: %s",
			requestId, stateErr)
	}

	// Store the ID
	accountId := stateResp.(*organizations.CreateAccountStatus).AccountId
	d.SetId(*accountId)

	return resourceAwsOrganizationsAccountRead(d, meta)
}

func resourceAwsOrganizationsAccountRead(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).organizationsconn
	describeOpts := &organizations.DescribeAccountInput{
		AccountId: aws.String(d.Id()),
	}
	resp, err := conn.DescribeAccount(describeOpts)
	if err != nil {
		if isAWSErr(err, organizations.ErrCodeAccountNotFoundException, "") {
			log.Printf("[WARN] Account does not exist, removing from state: %s", d.Id())
			d.SetId("")
			return nil
		}
		return err
	}

	d.Set("arn", resp.Account.Arn)
	d.Set("joined_method", resp.Account.JoinedMethod)
	d.Set("joined_timestamp", resp.Account.JoinedTimestamp)
	d.Set("name", resp.Account.Name)
	d.Set("status", resp.Account.Status)
	return nil
}

func resourceAwsOrganizationsAccountDelete(d *schema.ResourceData, meta interface{}) error {
	log.Printf("[WARN] Organization member accounts must be deleted from the web console.")
	return nil
}

// resourceAwsOrganizationsAccountStateRefreshFunc returns a resource.StateRefreshFunc
// that is used to watch a CreateAccount request
func resourceAwsOrganizationsAccountStateRefreshFunc(conn *organizations.Organizations, id string) resource.StateRefreshFunc {
	return func() (interface{}, string, error) {
		opts := &organizations.DescribeCreateAccountStatusInput{
			CreateAccountRequestId: aws.String(id),
		}
		resp, err := conn.DescribeCreateAccountStatus(opts)
		if err != nil {
			if isAWSErr(err, organizations.ErrCodeCreateAccountStatusNotFoundException, "") {
				resp = nil
			} else {
				log.Printf("Error on OrganizationAccountStateRefresh: %s", err)
				return nil, "", err
			}
		}

		if resp == nil {
			// Sometimes AWS just has consistency issues and doesn't see
			// our account yet. Return an empty state.
			return nil, "", nil
		}

		accountStatus := resp.CreateAccountStatus
		if *accountStatus.State == organizations.CreateAccountStateFailed {
			return nil, *accountStatus.State, fmt.Errorf(*accountStatus.FailureReason)
		}
		return accountStatus, *accountStatus.State, nil
	}
}

func validateAwsOrganizationsAccountEmail(v interface{}, k string) (ws []string, errors []error) {
	value := v.(string)
	if !regexp.MustCompile(`^[^\s@]+@[^\s@]+\.[^\s@]+$`).MatchString(value) {
		errors = append(errors, fmt.Errorf(
			"%q must be a valid email address", value))
	}

	if len(value) < 6 {
		errors = append(errors, fmt.Errorf(
			"%q cannot be less than 6 characters", value))
	}

	if len(value) > 64 {
		errors = append(errors, fmt.Errorf(
			"%q cannot be greater than 64 characters", value))
	}

	return
}

func validateAwsOrganizationsAccountRoleName(v interface{}, k string) (ws []string, errors []error) {
	value := v.(string)
	if !regexp.MustCompile(`^[\w+=,.@-]{1,64}$`).MatchString(value) {
		errors = append(errors, fmt.Errorf(
			"%q must consist of uppercase letters, lowercase letters, digits with no spaces, and any of the following characters: =,.@-", value))
	}

	return
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"gopkg.in/mgo.v2"
	"log"
	"net/http"
	"runtime"
)

const (
	connectionString = "localhost"
	helloWorldString = "Hello, world!"
	worldRowCount    = 10000
)

var (
	collection *mgo.Collection
)

type Message struct {
	Message string `json:"message"`
}

type World struct {
	Id           uint16 `json:"id"`
	RandomNumber uint16 `json:"randomNumber"`
}

type Fortune struct {
	Id      uint16 `json:"id"`
	Message string `json:"message"`
}

func main() {
	port := ":8228"
	runtime.GOMAXPROCS(runtime.NumCPU())
	session, err := mgo.Dial(connectionString)
	if err != nil {
		log.Fatalf("Error opening database: %v", err)
	}
	defer session.Close()
	session.SetPoolLimit(5)
	collection = session.DB("hello_world").C("world")
	http.HandleFunc("/db", dbHandler)
	http.HandleFunc("/json", jsonHandler)
	fmt.Println("Serving on http://localhost" + port)
	http.ListenAndServe(port, nil)
}

// Test 1: JSON serialization
func jsonHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/javascript")
	json.NewEncoder(w).Encode(&Message{helloWorldString})
}

func dbHandler(w http.ResponseWriter, r *http.Request) {
	var world World
	var randomNumber = rand.Intn(worldRowCount) + 1
	query := bson.M{
		"id": randomNumber,
	}
	if collection != nil {
		if err := collection.Find(query).One(&World); err != nil {
			log.Fatalf("Error finding world with id: %s", err.Error())
			return
		} else {
			w.Header().Set("Content-Type", "application/json")
			json.NewEncoder(w).Encode(&world)
			return
		}
	} else {
		log.Fatal("Collection not initialized properly")
	}
}
<commit_msg>Added queries handler function<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"gopkg.in/mgo.v2"
	"gopkg.in/mgo.v2/bson"
	"log"
	"math/rand"
	"net/http"
	"runtime"
	"strconv"
)

const (
	connectionString = "localhost"
	helloWorldString = "Hello, world!"
	worldRowCount    = 10000
)

var (
	collection *mgo.Collection
	database   *mgo.Database
)

type Message struct {
	Message string `json:"message"`
}

type World struct {
	Id           uint16 `json:"id"`
	RandomNumber uint16 `json:"randomNumber"`
}

type Fortune struct {
	Id      uint16 `json:"id"`
	Message string `json:"message"`
}

func main() {
	port := ":8228"
	runtime.GOMAXPROCS(runtime.NumCPU())
	if session, err := mgo.Dial(connectionString); err != nil {
		log.Fatalf("Error opening database: %v", err)
	} else {
		defer session.Close()
		session.SetPoolLimit(5)
		database = session.DB("hello_world")
		collection = database.C("world")
		http.HandleFunc("/db", dbHandler)
		http.HandleFunc("/json", jsonHandler)
		fmt.Println("Serving on http://localhost" + port)
		http.ListenAndServe(port, nil)
	}
}

// Test 1: JSON serialization
func jsonHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/javascript")
	json.NewEncoder(w).Encode(&Message{helloWorldString})
}

func dbHandler(w http.ResponseWriter, r *http.Request) {
	var world World
	query := bson.M{
		"id": rand.Intn(worldRowCount) + 1,
	}
	if collection != nil {
		if err := collection.Find(query).One(&world); err != nil {
			log.Fatalf("Error finding world with id: %s", err.Error())
			return
		} else {
			w.Header().Set("Content-Type", "application/json")
			json.NewEncoder(w).Encode(&world)
			return
		}
	} else {
		log.Fatal("Collection not initialized properly")
	}
}

func queriesHandler(w http.ResponseWriter, r *http.Request) {
	n := 1
	if nStr := r.URL.Query().Get("queries"); len(nStr) > 0 {
		n, _ = strconv.Atoi(nStr)
	}

	if n <= 1 {
		dbHandler(w, r)
		return
	} else if n > 500 {
		n = 500
	}

	worlds := make([]World, n)
	for _, world := range worlds {
		query := bson.M{
			"id": rand.Intn(worldRowCount) + 1,
		}
		if err := collection.Find(query).One(&world); err != nil {
			log.Fatalf("Error finding world with id: %s", err.Error())
			return
		}
	}

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(worlds)
}
<|endoftext|>