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

116 lines
2.3 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 ftp
import (
"context"
"fmt"
"time"
ftplib "github.com/jlaffaye/ftp"
"github.com/shadow1ng/fscan/common"
"github.com/shadow1ng/fscan/plugins/base"
)
// FTPConnector FTP连接器实现
type FTPConnector struct {
host string
port string
}
// NewFTPConnector 创建FTP连接器
func NewFTPConnector() *FTPConnector {
return &FTPConnector{}
}
// Connect 连接到FTP服务
func (c *FTPConnector) 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)
// 创建FTP连接配置
config := &FTPConfig{
Target: target,
Timeout: time.Duration(common.Timeout) * time.Second,
}
return config, nil
}
// Authenticate 认证
func (c *FTPConnector) Authenticate(ctx context.Context, conn interface{}, cred *base.Credential) error {
config, ok := conn.(*FTPConfig)
if !ok {
return fmt.Errorf("无效的连接类型")
}
// 在goroutine中建立FTP连接支持Context取消
resultChan := make(chan struct {
ftpConn *ftplib.ServerConn
err error
}, 1)
go func() {
ftpConn, err := ftplib.DialTimeout(config.Target, config.Timeout)
select {
case <-ctx.Done():
if ftpConn != nil {
ftpConn.Quit()
}
case resultChan <- struct {
ftpConn *ftplib.ServerConn
err error
}{ftpConn, err}:
}
}()
// 等待连接结果或Context取消
var ftpConn *ftplib.ServerConn
var err error
select {
case result := <-resultChan:
ftpConn, err = result.ftpConn, result.err
if err != nil {
return fmt.Errorf("FTP连接失败: %v", err)
}
case <-ctx.Done():
return fmt.Errorf("FTP连接超时: %v", ctx.Err())
}
defer ftpConn.Quit()
// 在goroutine中进行登录认证
loginChan := make(chan error, 1)
go func() {
err := ftpConn.Login(cred.Username, cred.Password)
select {
case <-ctx.Done():
case loginChan <- err:
}
}()
// 等待登录结果或Context取消
select {
case err := <-loginChan:
if err != nil {
return fmt.Errorf("FTP认证失败: %v", err)
}
return nil
case <-ctx.Done():
return fmt.Errorf("FTP认证超时: %v", ctx.Err())
}
}
// Close 关闭连接
func (c *FTPConnector) Close(conn interface{}) error {
// FTP配置无需显式关闭
return nil
}
// FTPConfig FTP连接配置
type FTPConfig struct {
Target string
Timeout time.Duration
}