mirror of
https://github.com/hashicorp/vault.git
synced 2025-08-15 11:07:00 +02:00
* Added HANA dynamic secret backend * Added acceptance tests for HANA secret backend * Add HANA backend as a logical backend to server * Added documentation to HANA secret backend * Added vendored libraries * Go fmt * Migrate hana credential creation to plugin * Removed deprecated hana logical backend * Migrated documentation for HANA database plugin * Updated HANA DB plugin to use role name in credential generation * Update HANA plugin tests * If env vars are not configured, tests will skip rather than succeed * Fixed some improperly named string variables * Removed unused import * Import SAP hdb driver
317 lines
5.9 KiB
Go
317 lines
5.9 KiB
Go
/*
|
|
Copyright 2014 SAP SE
|
|
|
|
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 protocol
|
|
|
|
import (
|
|
"database/sql/driver"
|
|
"fmt"
|
|
|
|
"github.com/SAP/go-hdb/internal/bufio"
|
|
)
|
|
|
|
type parameterOptions int8
|
|
|
|
const (
|
|
poMandatory parameterOptions = 0x01
|
|
poOptional parameterOptions = 0x02
|
|
poDefault parameterOptions = 0x04
|
|
)
|
|
|
|
var parameterOptionsText = map[parameterOptions]string{
|
|
poMandatory: "mandatory",
|
|
poOptional: "optional",
|
|
poDefault: "default",
|
|
}
|
|
|
|
func (k parameterOptions) String() string {
|
|
t := make([]string, 0, len(parameterOptionsText))
|
|
|
|
for option, text := range parameterOptionsText {
|
|
if (k & option) != 0 {
|
|
t = append(t, text)
|
|
}
|
|
}
|
|
return fmt.Sprintf("%v", t)
|
|
}
|
|
|
|
type parameterMode int8
|
|
|
|
const (
|
|
pmIn parameterMode = 0x01
|
|
pmInout parameterMode = 0x02
|
|
pmOut parameterMode = 0x04
|
|
)
|
|
|
|
var parameterModeText = map[parameterMode]string{
|
|
pmIn: "in",
|
|
pmInout: "inout",
|
|
pmOut: "out",
|
|
}
|
|
|
|
func (k parameterMode) String() string {
|
|
t := make([]string, 0, len(parameterModeText))
|
|
|
|
for mode, text := range parameterModeText {
|
|
if (k & mode) != 0 {
|
|
t = append(t, text)
|
|
}
|
|
}
|
|
return fmt.Sprintf("%v", t)
|
|
}
|
|
|
|
type parameterField struct {
|
|
parameterOptions parameterOptions
|
|
tc typeCode
|
|
mode parameterMode
|
|
fraction int16
|
|
length int16
|
|
nameOffset uint32
|
|
}
|
|
|
|
func newParameterField() *parameterField {
|
|
return ¶meterField{}
|
|
}
|
|
|
|
func (f *parameterField) String() string {
|
|
return fmt.Sprintf("parameterOptions %s typeCode %s mode %s fraction %d length %d nameOffset %d",
|
|
f.parameterOptions,
|
|
f.tc,
|
|
f.mode,
|
|
f.fraction,
|
|
f.length,
|
|
f.nameOffset,
|
|
)
|
|
}
|
|
|
|
// field interface
|
|
func (f *parameterField) typeCode() typeCode {
|
|
return f.tc
|
|
}
|
|
|
|
func (f *parameterField) in() bool {
|
|
return f.mode == pmInout || f.mode == pmIn
|
|
}
|
|
|
|
func (f *parameterField) out() bool {
|
|
return f.mode == pmInout || f.mode == pmOut
|
|
}
|
|
|
|
func (f *parameterField) name(names map[uint32]string) string {
|
|
return names[f.nameOffset]
|
|
}
|
|
|
|
func (f *parameterField) nameOffsets() []uint32 {
|
|
return []uint32{f.nameOffset}
|
|
}
|
|
|
|
//
|
|
|
|
func (f *parameterField) read(rd *bufio.Reader) error {
|
|
var err error
|
|
|
|
if po, err := rd.ReadInt8(); err == nil {
|
|
f.parameterOptions = parameterOptions(po)
|
|
} else {
|
|
return err
|
|
}
|
|
if tc, err := rd.ReadInt8(); err == nil {
|
|
f.tc = typeCode(tc)
|
|
} else {
|
|
return err
|
|
}
|
|
if mode, err := rd.ReadInt8(); err == nil {
|
|
f.mode = parameterMode(mode)
|
|
} else {
|
|
return err
|
|
}
|
|
if err := rd.Skip(1); err != nil { //filler
|
|
return err
|
|
}
|
|
if f.nameOffset, err = rd.ReadUint32(); err != nil {
|
|
return err
|
|
}
|
|
if f.length, err = rd.ReadInt16(); err != nil {
|
|
return err
|
|
}
|
|
if f.fraction, err = rd.ReadInt16(); err != nil {
|
|
return err
|
|
}
|
|
if err := rd.Skip(4); err != nil { //filler
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// parameter metadata
|
|
type parameterMetadata struct {
|
|
fieldSet *FieldSet
|
|
numArg int
|
|
}
|
|
|
|
func (m *parameterMetadata) String() string {
|
|
return fmt.Sprintf("parameter metadata: %s", m.fieldSet.fields)
|
|
}
|
|
|
|
func (m *parameterMetadata) kind() partKind {
|
|
return pkParameterMetadata
|
|
}
|
|
|
|
func (m *parameterMetadata) setNumArg(numArg int) {
|
|
m.numArg = numArg
|
|
}
|
|
|
|
func (m *parameterMetadata) read(rd *bufio.Reader) error {
|
|
|
|
for i := 0; i < m.numArg; i++ {
|
|
field := newParameterField()
|
|
if err := field.read(rd); err != nil {
|
|
return err
|
|
}
|
|
m.fieldSet.fields[i] = field
|
|
}
|
|
|
|
pos := uint32(0)
|
|
for _, offset := range m.fieldSet.nameOffsets() {
|
|
if diff := int(offset - pos); diff > 0 {
|
|
rd.Skip(diff)
|
|
}
|
|
|
|
b, size, err := readShortUtf8(rd)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
m.fieldSet.names[offset] = string(b)
|
|
|
|
pos += uint32(1 + size)
|
|
}
|
|
|
|
if trace {
|
|
outLogger.Printf("read %s", m)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// parameters
|
|
type parameters struct {
|
|
fields []field //input fields
|
|
args []driver.Value
|
|
}
|
|
|
|
func newParameters(fieldSet *FieldSet, args []driver.Value) *parameters {
|
|
m := ¶meters{
|
|
fields: make([]field, 0, len(fieldSet.fields)),
|
|
args: args,
|
|
}
|
|
for _, field := range fieldSet.fields {
|
|
if field.in() {
|
|
m.fields = append(m.fields, field)
|
|
}
|
|
}
|
|
return m
|
|
}
|
|
|
|
func (m *parameters) kind() partKind {
|
|
return pkParameters
|
|
}
|
|
|
|
func (m *parameters) size() (int, error) {
|
|
|
|
size := len(m.args)
|
|
cnt := len(m.fields)
|
|
|
|
for i, arg := range m.args {
|
|
|
|
if arg == nil { // null value
|
|
continue
|
|
}
|
|
|
|
// mass insert
|
|
field := m.fields[i%cnt]
|
|
|
|
fieldSize, err := fieldSize(field.typeCode(), arg)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
size += fieldSize
|
|
}
|
|
|
|
return size, nil
|
|
}
|
|
|
|
func (m *parameters) numArg() int {
|
|
cnt := len(m.fields)
|
|
|
|
if cnt == 0 { // avoid divide-by-zero (e.g. prepare without parameters)
|
|
return 0
|
|
}
|
|
|
|
return len(m.args) / cnt
|
|
}
|
|
|
|
func (m parameters) write(wr *bufio.Writer) error {
|
|
|
|
cnt := len(m.fields)
|
|
|
|
for i, arg := range m.args {
|
|
|
|
//mass insert
|
|
field := m.fields[i%cnt]
|
|
|
|
if err := writeField(wr, field.typeCode(), arg); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
if trace {
|
|
outLogger.Printf("parameters: %s", m)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// output parameter
|
|
type outputParameters struct {
|
|
numArg int
|
|
fieldSet *FieldSet
|
|
fieldValues *FieldValues
|
|
}
|
|
|
|
func (r *outputParameters) String() string {
|
|
return fmt.Sprintf("output parameters: %v", r.fieldValues)
|
|
}
|
|
|
|
func (r *outputParameters) kind() partKind {
|
|
return pkOutputParameters
|
|
}
|
|
|
|
func (r *outputParameters) setNumArg(numArg int) {
|
|
r.numArg = numArg // should always be 1
|
|
}
|
|
|
|
func (r *outputParameters) read(rd *bufio.Reader) error {
|
|
if err := r.fieldValues.read(r.numArg, r.fieldSet, rd); err != nil {
|
|
return err
|
|
}
|
|
if trace {
|
|
outLogger.Printf("read %s", r)
|
|
}
|
|
return nil
|
|
}
|