Skip to content

Commit e4bd994

Browse files
committed
Improve error handling and validation in acquisition module also handle
apk verification in memory instead of using temporary files
1 parent 107d15d commit e4bd994

File tree

6 files changed

+314
-230
lines changed

6 files changed

+314
-230
lines changed

acquisition/acquisition.go

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ func New(path string) (*Acquisition, error) {
103103

104104
// Initialize streaming puller for direct operations
105105
acq.StreamingPuller = NewStreamingPuller(adb.Client.ExePath, adb.Client.Serial, 100) // 100MB max memory
106+
106107
}
107108

108109
return &acq, nil
@@ -264,37 +265,51 @@ func (a *Acquisition) StoreInfo() error {
264265

265266
// StreamAPKToZip streams an APK file directly to encrypted zip with certificate processing
266267
func (a *Acquisition) StreamAPKToZip(remotePath, zipPath string, processFunc func(io.Reader) error) error {
267-
if !a.StreamingMode || a.EncryptedWriter == nil {
268-
return fmt.Errorf("streaming mode not available")
268+
if err := a.validateStreamingMode(); err != nil {
269+
return err
270+
}
271+
272+
if remotePath == "" {
273+
return fmt.Errorf("remote path cannot be empty")
274+
}
275+
if zipPath == "" {
276+
return fmt.Errorf("zip path cannot be empty")
269277
}
270278

271279
// Pull APK data to memory buffer
272280
buffer, err := a.StreamingPuller.PullToBuffer(remotePath)
273281
if err != nil {
274-
return fmt.Errorf("failed to pull APK %s: %v", remotePath, err)
282+
return fmt.Errorf("failed to pull APK %q: %v", remotePath, err)
275283
}
276284

277285
// Process APK if processor provided (e.g., certificate verification)
278286
if processFunc != nil {
279287
err = processFunc(buffer.Reader())
280288
if err != nil {
281-
return fmt.Errorf("failed to process APK %s: %v", remotePath, err)
289+
return fmt.Errorf("failed to process APK %q: %v", remotePath, err)
282290
}
283291
}
284292

285293
// Stream to encrypted zip
286294
err = a.EncryptedWriter.CreateFileFromReader(zipPath, buffer.Reader())
287295
if err != nil {
288-
return fmt.Errorf("failed to add APK %s to encrypted zip: %v", remotePath, err)
296+
return fmt.Errorf("failed to add APK %q to encrypted zip: %v", remotePath, err)
289297
}
290298

291299
return nil
292300
}
293301

294302
// StreamBackupToZip streams a backup directly to encrypted zip
295303
func (a *Acquisition) StreamBackupToZip(arg, zipPath string) error {
296-
if !a.StreamingMode || a.EncryptedWriter == nil {
297-
return fmt.Errorf("streaming mode not available")
304+
if err := a.validateStreamingMode(); err != nil {
305+
return err
306+
}
307+
308+
if arg == "" {
309+
return fmt.Errorf("backup argument cannot be empty")
310+
}
311+
if zipPath == "" {
312+
return fmt.Errorf("zip path cannot be empty")
298313
}
299314

300315
// Create zip entry writer
@@ -306,16 +321,20 @@ func (a *Acquisition) StreamBackupToZip(arg, zipPath string) error {
306321
// Stream backup directly to zip
307322
err = a.StreamingPuller.BackupToWriter(arg, writer)
308323
if err != nil {
309-
return fmt.Errorf("failed to stream backup to zip: %v", err)
324+
return fmt.Errorf("failed to stream backup %q to zip: %v", arg, err)
310325
}
311326

312327
return nil
313328
}
314329

315330
// StreamBugreportToZip streams a bugreport directly to encrypted zip
316331
func (a *Acquisition) StreamBugreportToZip(zipPath string) error {
317-
if !a.StreamingMode || a.EncryptedWriter == nil {
318-
return fmt.Errorf("streaming mode not available")
332+
if err := a.validateStreamingMode(); err != nil {
333+
return err
334+
}
335+
336+
if zipPath == "" {
337+
return fmt.Errorf("zip path cannot be empty")
319338
}
320339

321340
// Create zip entry writer
@@ -332,3 +351,17 @@ func (a *Acquisition) StreamBugreportToZip(zipPath string) error {
332351

333352
return nil
334353
}
354+
355+
// validateStreamingMode checks if streaming mode is properly initialized
356+
func (a *Acquisition) validateStreamingMode() error {
357+
if !a.StreamingMode {
358+
return fmt.Errorf("streaming mode not enabled")
359+
}
360+
if a.EncryptedWriter == nil {
361+
return fmt.Errorf("encrypted writer not initialized")
362+
}
363+
if a.StreamingPuller == nil {
364+
return fmt.Errorf("streaming puller not initialized")
365+
}
366+
return nil
367+
}

acquisition/encrypted_stream.go

Lines changed: 33 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ package acquisition
77

88
import (
99
"archive/zip"
10+
"bytes"
1011
"fmt"
1112
"io"
1213
"os"
@@ -65,6 +66,7 @@ func NewEncryptedZipWriter(uuid string) (*EncryptedZipWriter, error) {
6566
encWriter, err := age.Encrypt(file, recipient)
6667
if err != nil {
6768
file.Close()
69+
os.Remove(outputPath) // Clean up the created file
6870
return nil, fmt.Errorf("failed to create encrypted writer: %v", err)
6971
}
7072

@@ -84,8 +86,12 @@ func NewEncryptedZipWriter(uuid string) (*EncryptedZipWriter, error) {
8486

8587
// CreateFile creates a new file in the encrypted zip and returns a writer
8688
func (ezw *EncryptedZipWriter) CreateFile(name string) (io.Writer, error) {
87-
if ezw.closed {
88-
return nil, fmt.Errorf("encrypted zip writer is closed")
89+
if err := ezw.checkClosed(); err != nil {
90+
return nil, err
91+
}
92+
93+
if name == "" {
94+
return nil, fmt.Errorf("file name cannot be empty")
8995
}
9096

9197
header := &zip.FileHeader{
@@ -99,8 +105,8 @@ func (ezw *EncryptedZipWriter) CreateFile(name string) (io.Writer, error) {
99105

100106
// CreateFileFromReader copies data from a reader to a file in the encrypted zip
101107
func (ezw *EncryptedZipWriter) CreateFileFromReader(name string, src io.Reader) error {
102-
if ezw.closed {
103-
return fmt.Errorf("encrypted zip writer is closed")
108+
if src == nil {
109+
return fmt.Errorf("source reader cannot be nil")
104110
}
105111

106112
writer, err := ezw.CreateFile(name)
@@ -118,112 +124,57 @@ func (ezw *EncryptedZipWriter) CreateFileFromReader(name string, src io.Reader)
118124

119125
// CreateFileFromString creates a file with string content in the encrypted zip
120126
func (ezw *EncryptedZipWriter) CreateFileFromString(name, content string) error {
121-
if ezw.closed {
122-
return fmt.Errorf("encrypted zip writer is closed")
123-
}
124-
125-
writer, err := ezw.CreateFile(name)
126-
if err != nil {
127-
return fmt.Errorf("failed to create file in zip: %v", err)
128-
}
129-
130-
_, err = writer.Write([]byte(content))
131-
if err != nil {
132-
return fmt.Errorf("failed to write content to zip file: %v", err)
133-
}
134-
135-
return nil
127+
return ezw.CreateFileFromReader(name, strings.NewReader(content))
136128
}
137129

138130
// CreateFileFromBytes creates a file with byte content in the encrypted zip
139131
func (ezw *EncryptedZipWriter) CreateFileFromBytes(name string, content []byte) error {
140-
if ezw.closed {
141-
return fmt.Errorf("encrypted zip writer is closed")
142-
}
143-
144-
writer, err := ezw.CreateFile(name)
145-
if err != nil {
146-
return fmt.Errorf("failed to create file in zip: %v", err)
147-
}
148-
149-
_, err = writer.Write(content)
150-
if err != nil {
151-
return fmt.Errorf("failed to write content to zip file: %v", err)
152-
}
153-
154-
return nil
132+
return ezw.CreateFileFromReader(name, bytes.NewReader(content))
155133
}
156134

157135
// CreateFileFromPath reads a file from disk and adds it to the encrypted zip
158136
func (ezw *EncryptedZipWriter) CreateFileFromPath(name, filePath string) error {
159-
if ezw.closed {
160-
return fmt.Errorf("encrypted zip writer is closed")
161-
}
162-
163137
file, err := os.Open(filePath)
164138
if err != nil {
165-
return fmt.Errorf("failed to open source file: %v", err)
139+
return fmt.Errorf("failed to open source file %q: %v", filePath, err)
166140
}
167141
defer file.Close()
168142

169143
return ezw.CreateFileFromReader(name, file)
170144
}
171145

172-
// AddDirectory recursively adds all files from a directory to the encrypted zip
173-
func (ezw *EncryptedZipWriter) AddDirectory(dirPath, basePath string) error {
174-
if ezw.closed {
175-
return fmt.Errorf("encrypted zip writer is closed")
176-
}
177-
178-
return filepath.Walk(dirPath, func(path string, info os.FileInfo, err error) error {
179-
if err != nil {
180-
return err
181-
}
182-
183-
// Skip directories
184-
if info.IsDir() {
185-
return nil
186-
}
187-
188-
// Calculate relative path for zip entry
189-
relPath, err := filepath.Rel(basePath, path)
190-
if err != nil {
191-
return fmt.Errorf("failed to get relative path: %v", err)
192-
}
193-
194-
// Use forward slashes for zip paths
195-
zipPath := filepath.ToSlash(relPath)
196-
197-
// Add file to zip
198-
return ezw.CreateFileFromPath(zipPath, path)
199-
})
200-
}
201-
202146
// Close finalizes and closes the encrypted zip
203147
func (ezw *EncryptedZipWriter) Close() error {
204148
if ezw.closed {
205149
return nil
206150
}
207151

208152
ezw.closed = true
153+
var lastErr error
209154

210155
// Close zip writer first
211156
if err := ezw.zipWriter.Close(); err != nil {
212-
return fmt.Errorf("failed to close zip writer: %v", err)
157+
lastErr = fmt.Errorf("failed to close zip writer: %v", err)
213158
}
214159

215160
// Close encryption writer
216161
if err := ezw.encWriter.Close(); err != nil {
217-
return fmt.Errorf("failed to close encryption writer: %v", err)
162+
if lastErr == nil {
163+
lastErr = fmt.Errorf("failed to close encryption writer: %v", err)
164+
}
218165
}
219166

220167
// Close file
221168
if err := ezw.file.Close(); err != nil {
222-
return fmt.Errorf("failed to close output file: %v", err)
169+
if lastErr == nil {
170+
lastErr = fmt.Errorf("failed to close output file: %v", err)
171+
}
223172
}
224173

225-
log.Infof("Encrypted archive created successfully at %s", ezw.outputPath)
226-
return nil
174+
if lastErr == nil {
175+
log.Infof("Encrypted archive created successfully at %s", ezw.outputPath)
176+
}
177+
return lastErr
227178
}
228179

229180
// GetOutputPath returns the path to the encrypted zip file
@@ -235,3 +186,11 @@ func (ezw *EncryptedZipWriter) GetOutputPath() string {
235186
func (ezw *EncryptedZipWriter) IsClosed() bool {
236187
return ezw.closed
237188
}
189+
190+
// checkClosed is a helper method to check if the writer is closed
191+
func (ezw *EncryptedZipWriter) checkClosed() error {
192+
if ezw.closed {
193+
return fmt.Errorf("encrypted zip writer is closed")
194+
}
195+
return nil
196+
}

0 commit comments

Comments
 (0)