Skip to content

Commit be3c5d4

Browse files
shueybubblesDavid Shiflet (from Dev Box)
andauthored
Feat: Add HostNameInCertificate for strict encryption (#589)
Co-authored-by: David Shiflet (from Dev Box) <[email protected]>
1 parent b7ec634 commit be3c5d4

File tree

19 files changed

+984
-740
lines changed

19 files changed

+984
-740
lines changed

.vscode/launch.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
"request": "launch",
2525
"mode" : "auto",
2626
"program": "${workspaceFolder}/cmd/modern",
27-
"args" : ["-S", "davidshi-2022", "-g", "-Q", "select nvarcharcol from encrypt.dbo.encrypted", "--driver-logging-level=65"],
27+
"args" : ["-S", ".", "-Q", "select top 8 name from sys.all_objects"],
2828
},
2929
{
3030
"name" : "Run file query",

.vscode/settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"go.lintTool": "golangci-lint",
33
"go.lintOnSave": "workspace",
4-
"azure-pipelines.1ESPipelineTemplatesSchemaFile": true
4+
"azure-pipelines.1ESPipelineTemplatesSchemaFile": true,
5+
"sarif-viewer.connectToGithubCodeScanning": "on"
56
}

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ The following switches have different behavior in this version of `sqlcmd` compa
130130
- If `-N` is provided but `-C` is not, sqlcmd will require validation of the server certificate. Note that a `false` value for encryption could still lead to encryption of the login packet.
131131
- `-C` has no effect when `strict` value is specified for `-N`.
132132
- If both `-N` and `-C` are provided, sqlcmd will use their values for encryption negotiation.
133+
- To provide the value of the host name in the server certificate when using strict encryption, pass the host name with `-F`. Example: `-Ns -F myhost.domain.com`
133134
- More information about client/server encryption negotiation can be found at <https://docs.microsoft.com/openspecs/windows_protocols/ms-tds/60f56408-0188-4cd5-8b90-25c6f2423868>
134135
- `-u` The generated Unicode output file will have the UTF16 Little-Endian Byte-order mark (BOM) written to it.
135136
- Some behaviors that were kept to maintain compatibility with `OSQL` may be changed, such as alignment of column headers for some data types.
@@ -152,7 +153,7 @@ switches are most important to you to have implemented next in the new sqlcmd.
152153
- Console output coloring (see below)
153154
- `:Connect` now has an optional `-G` parameter to select one of the authentication methods for Azure SQL Database - `SqlAuthentication`, `ActiveDirectoryDefault`, `ActiveDirectoryIntegrated`, `ActiveDirectoryServicePrincipal`, `ActiveDirectoryManagedIdentity`, `ActiveDirectoryPassword`. If `-G` is not provided, either Integrated security or SQL Authentication will be used, dependent on the presence of a `-U` username parameter.
154155
- The new `--driver-logging-level` command line parameter allows you to see traces from the `go-mssqldb` client driver. Use `64` to see all traces.
155-
- Sqlcmd can now print results using a vertical format. Use the new `-F vertical` command line option to set it. It's also controlled by the `SQLCMDFORMAT` scripting variable.
156+
- Sqlcmd can now print results using a vertical format. Use the new `--vertical` command line option to set it. It's also controlled by the `SQLCMDFORMAT` scripting variable.
156157

157158
```
158159
1> select session_id, client_interface_name, program_name from sys.dm_exec_sessions where session_id=@@spid

cmd/sqlcmd/sqlcmd.go

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,12 @@ type SQLCmdArguments struct {
5656
WorkstationName string
5757
ApplicationIntent string
5858
EncryptConnection string
59+
HostNameInCertificate string
5960
DriverLoggingLevel int
6061
ExitOnError bool
6162
ErrorSeverityLevel uint8
6263
ErrorLevel int
63-
Format string
64+
Vertical bool
6465
ErrorsToStderr *int
6566
Headers int
6667
UnicodeOutputFile bool
@@ -117,7 +118,6 @@ const (
117118
sqlcmdErrorPrefix = "Sqlcmd: "
118119
applicationIntent = "application-intent"
119120
errorsToStderr = "errors-to-stderr"
120-
format = "format"
121121
encryptConnection = "encrypt-connection"
122122
screenWidth = "screen-width"
123123
fixedTypeWidth = "fixed-type-width"
@@ -316,14 +316,16 @@ func checkDefaultValue(args []string, i int) (val string) {
316316
'k': "0",
317317
'L': "|", // | is the sentinel for no value since users are unlikely to use it. It's "reserved" in most shells
318318
'X': "0",
319-
'N': "true",
320319
}
321320
if isFlag(args[i]) && len(args[i]) == 2 && (len(args) == i+1 || args[i+1][0] == '-') {
322321
if v, ok := flags[rune(args[i][1])]; ok {
323322
val = v
324323
return
325324
}
326325
}
326+
if args[i] == "-N" && (len(args) == i+1 || args[i+1][0] == '-') {
327+
val = "true"
328+
}
327329
return
328330
}
329331

@@ -426,9 +428,10 @@ func setFlags(rootCmd *cobra.Command, args *SQLCmdArguments) {
426428

427429
rootCmd.Flags().StringVarP(&args.ApplicationIntent, applicationIntent, "K", "default", localizer.Sprintf("Declares the application workload type when connecting to a server. The only currently supported value is ReadOnly. If %s is not specified, the sqlcmd utility will not support connectivity to a secondary replica in an Always On availability group", localizer.ApplicationIntentFlagShort))
428430
rootCmd.Flags().StringVarP(&args.EncryptConnection, encryptConnection, "N", "default", localizer.Sprintf("This switch is used by the client to request an encrypted connection"))
431+
rootCmd.Flags().StringVarP(&args.HostNameInCertificate, "host-name-in-certificate", "F", "", localizer.Sprintf("Specifies the host name in the server certificate."))
429432
// Can't use NoOptDefVal until this fix: https://github.com/spf13/cobra/issues/866
430433
//rootCmd.Flags().Lookup(encryptConnection).NoOptDefVal = "true"
431-
rootCmd.Flags().StringVarP(&args.Format, format, "F", "horiz", localizer.Sprintf("Specifies the formatting for results"))
434+
rootCmd.Flags().BoolVarP(&args.Vertical, "vertical", "", false, localizer.Sprintf("Prints the output in vertical format. This option sets the sqlcmd scripting variable %s to '%s'. The default is false", sqlcmd.SQLCMDFORMAT, "vert"))
432435
_ = rootCmd.Flags().IntP(errorsToStderr, "r", -1, localizer.Sprintf("%s Redirects error messages with severity >= 11 output to stderr. Pass 1 to to redirect all errors including PRINT.", "-r[0 | 1]"))
433436
rootCmd.Flags().IntVar(&args.DriverLoggingLevel, "driver-logging-level", 0, localizer.Sprintf("Level of mssql driver messages to print"))
434437
rootCmd.Flags().BoolVarP(&args.ExitOnError, "exit-on-error", "b", false, localizer.Sprintf("Specifies that sqlcmd exits and returns a %s value when an error occurs", localizer.DosErrorLevel))
@@ -492,15 +495,6 @@ func normalizeFlags(cmd *cobra.Command) error {
492495
err = invalidParameterError("-N", v, "m[andatory]", "yes", "1", "t[rue]", "disable", "o[ptional]", "no", "0", "f[alse]", "s[trict]")
493496
return pflag.NormalizedName("")
494497
}
495-
case format:
496-
value := strings.ToLower(v)
497-
switch value {
498-
case "horiz", "horizontal", "vert", "vertical":
499-
return pflag.NormalizedName(name)
500-
default:
501-
err = invalidParameterError("-F", v, "horiz", "horizontal", "vert", "vertical")
502-
return pflag.NormalizedName("")
503-
}
504498
case errorsToStderr:
505499
switch v {
506500
case "0", "1":
@@ -670,7 +664,12 @@ func setVars(vars *sqlcmd.Variables, args *SQLCmdArguments) {
670664
}
671665
return ""
672666
},
673-
sqlcmd.SQLCMDFORMAT: func(a *SQLCmdArguments) string { return a.Format },
667+
sqlcmd.SQLCMDFORMAT: func(a *SQLCmdArguments) string {
668+
if a.Vertical {
669+
return "vert"
670+
}
671+
return "horizontal"
672+
},
674673
}
675674
for varname, set := range varmap {
676675
val := set(args)
@@ -721,6 +720,7 @@ func setConnect(connect *sqlcmd.ConnectSettings, args *SQLCmdArguments, vars *sq
721720
default:
722721
connect.Encrypt = args.EncryptConnection
723722
}
723+
connect.HostNameInCertificate = args.HostNameInCertificate
724724
connect.PacketSize = args.PacketSize
725725
connect.WorkstationName = args.WorkstationName
726726
connect.LogLevel = args.DriverLoggingLevel

cmd/sqlcmd/sqlcmd_test.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@ func TestValidCommandLineToArgsConversion(t *testing.T) {
6363
{[]string{"-b", "-m", "15", "-V", "20"}, func(args SQLCmdArguments) bool {
6464
return args.ExitOnError && args.ErrorLevel == 15 && args.ErrorSeverityLevel == 20
6565
}},
66-
{[]string{"-F", "vert"}, func(args SQLCmdArguments) bool {
67-
return args.Format == "vert"
66+
{[]string{"--vertical"}, func(args SQLCmdArguments) bool {
67+
return args.Vertical
6868
}},
6969
{[]string{"-r", "1"}, func(args SQLCmdArguments) bool {
7070
return *args.ErrorsToStderr == 1
@@ -108,6 +108,9 @@ func TestValidCommandLineToArgsConversion(t *testing.T) {
108108
{[]string{"-ifoo.sql", "bar.sql", "-V10"}, func(args SQLCmdArguments) bool {
109109
return args.ErrorSeverityLevel == 10 && args.InputFile[0] == "foo.sql" && args.InputFile[1] == "bar.sql"
110110
}},
111+
{[]string{"-N", "s", "-F", "myserver.domain.com"}, func(args SQLCmdArguments) bool {
112+
return args.EncryptConnection == "s" && args.HostNameInCertificate == "myserver.domain.com"
113+
}},
111114
}
112115

113116
for _, test := range commands {
@@ -151,7 +154,6 @@ func TestInvalidCommandLine(t *testing.T) {
151154
{[]string{"-E", "-U", "someuser"}, "The -E and the -U/-P options are mutually exclusive."},
152155
{[]string{"-L", "-q", `"select 1"`}, "The -L parameter can not be used in combination with other parameters."},
153156
{[]string{"-i", "foo.sql", "-q", `"select 1"`}, "The i and the -Q/-q options are mutually exclusive."},
154-
{[]string{"-F", "what"}, "'-F what': Unexpected argument. Argument value has to be one of [horiz horizontal vert vertical]."},
155157
{[]string{"-r", "5"}, `'-r 5': Unexpected argument. Argument value has to be one of [0 1].`},
156158
{[]string{"-w", "x"}, "'-w x': value must be greater than 8 and less than 65536."},
157159
{[]string{"-y", "111111"}, "'-y 111111': value must be greater than or equal to 0 and less than or equal to 8000."},

0 commit comments

Comments
 (0)