fscan/plugins/services/memcached/connector.go
ZacharyZcR 4a3f281b6b refactor: 统一Plugins目录大小写为小写
- 将所有Plugins路径重命名为plugins
- 修复Git索引与实际文件系统大小写不一致问题
- 确保跨平台兼容性和路径一致性
2025-08-12 13:08:06 +08:00

109 lines
2.7 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package memcached
import (
"context"
"fmt"
"net"
"strings"
"time"
"github.com/shadow1ng/fscan/common"
"github.com/shadow1ng/fscan/plugins/base"
)
// MemcachedConnection Memcached连接包装器
type MemcachedConnection struct {
client net.Conn
target string
}
// MemcachedConnector Memcached连接器实现
type MemcachedConnector struct {
host string
port string
}
// NewMemcachedConnector 创建Memcached连接器
func NewMemcachedConnector() *MemcachedConnector {
return &MemcachedConnector{}
}
// Connect 连接到Memcached服务
func (c *MemcachedConnector) Connect(ctx context.Context, info *common.HostInfo) (interface{}, error) {
c.host = info.Host
c.port = info.Ports
target := fmt.Sprintf("%s:%s", c.host, c.port)
timeout := time.Duration(common.Timeout) * time.Second
// 建立TCP连接
client, err := common.WrapperTcpWithTimeout("tcp", target, timeout)
if err != nil {
return nil, fmt.Errorf("Memcached连接失败: %v", err)
}
return &MemcachedConnection{
client: client,
target: target,
}, nil
}
// Authenticate 认证 - Memcached通常无认证检查未授权访问
func (c *MemcachedConnector) Authenticate(ctx context.Context, conn interface{}, cred *base.Credential) error {
memcachedConn, ok := conn.(*MemcachedConnection)
if !ok {
return fmt.Errorf("无效的连接类型")
}
// 在goroutine中进行操作支持Context取消
resultChan := make(chan error, 1)
go func() {
// 设置操作超时
timeout := time.Duration(common.Timeout) * time.Second
if err := memcachedConn.client.SetDeadline(time.Now().Add(timeout)); err != nil {
resultChan <- fmt.Errorf("设置超时失败: %v", err)
return
}
// 发送stats命令测试连接
if _, err := memcachedConn.client.Write([]byte("stats\n")); err != nil {
resultChan <- fmt.Errorf("发送命令失败: %v", err)
return
}
// 读取响应
buffer := make([]byte, 1024)
n, err := memcachedConn.client.Read(buffer)
if err != nil {
resultChan <- fmt.Errorf("读取响应失败: %v", err)
return
}
// 检查响应是否包含Memcached统计信息
response := string(buffer[:n])
if strings.Contains(response, "STAT") {
// 未授权访问成功
resultChan <- nil
return
}
resultChan <- fmt.Errorf("Memcached服务无响应或不可访问")
}()
// 等待操作结果或Context取消
select {
case err := <-resultChan:
return err
case <-ctx.Done():
return fmt.Errorf("Memcached操作超时: %v", ctx.Err())
}
}
// Close 关闭连接
func (c *MemcachedConnector) Close(conn interface{}) error {
if memcachedConn, ok := conn.(*MemcachedConnection); ok && memcachedConn.client != nil {
return memcachedConn.client.Close()
}
return nil
}