crdb代码阅读03——客户端连接认证流程

两种认证流程

pkg/server/config.go

1
2
cfg.UseLegacyConnHandling = envutil.EnvOrDefaultBool(
"COCKROACH_USE_LEGACY_CONN_HANDLING", false)

pkg/server/server.go

1
2
3
4
5
if !s.cfg.UseLegacyConnHandling {
serveFn = s.pgServer.ServeConn2
} else {
serveFn = s.pgServer.ServeConn
}

ServeConn是原始的处理方式,单routine for循环处理请求,已经不是默认处理方式。
ServeConn2是最新的处理方式,双routine处理逻辑.

双goroutine处理请求

  1. 负责接受客户端请求
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Loop:
for {
var typ pgwirebase.ClientMessageType
var n int
typ, n, err = c.readBuf.ReadTypedMsg(&c.rd)
c.metrics.BytesInCount.Inc(int64(n))
if err != nil {
break Loop
}
if log.V(2) {
log.Infof(ctx, "pgwire: processing %s", typ)
}
timeReceived := timeutil.Now()
switch typ {
case pgwirebase.ClientMsgSimpleQuery:
if doingExtendedQueryMessage {
  1. 负责处理请求
1
2
3
4
5
6
7
8
9
10
11
if sqlServer != nil {
wg.Add(1)
go func() {
writerErr = sqlServer.ServeConn(
processorCtx, c.sessionArgs, c.stmtBuf, c, reserved, &c.metrics.SQLMemMetrics, stopProcessor)
// TODO(andrei): Should we sometimes transmit the writerErr's to the
// client?
wg.Done()
stopReader()
}()
}

认证方式

  1. –insecure
    测试使用,不需要密码,不走TLS
  2. –certs-dir
    • 使用密码: 如果没有client.username.crt和client.username.key,则需要输入密码
    • 不使用密码: 如果存在client.username.crt/key,则不需要输入密码

pkg/sql/pgwire/server.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
func (c *v3Conn) handleAuthentication(ctx context.Context, insecure bool) error {
...
if len(tlsState.PeerCertificates) == 0 {
password, err := c.sendAuthPasswordRequest()
if err != nil {
return c.sendError(err)
}
authenticationHook = security.UserAuthPasswordHook(
insecure, password, hashedPassword,
)
} else {
// Normalize the username contained in the certificate.
tlsState.PeerCertificates[0].Subject.CommonName = tree.Name(
tlsState.PeerCertificates[0].Subject.CommonName,
).Normalize()
var err error
authenticationHook, err = security.UserAuthCertHook(insecure, &tlsState)
if err != nil {
return c.sendError(err)
}
}
if err := authenticationHook(c.sessionArgs.User, true /* public */); err != nil {
return c.sendError(err)
}

本文标题:crdb代码阅读03——客户端连接认证流程

文章作者:Louis

发布时间:2018年04月16日 - 19:04

最后更新:2018年04月18日 - 11:04

原始链接:/2018/04/16/crdb03-connect/

许可协议: Louis-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。