Commit Graph

266 Commits

Author SHA1 Message Date
Levi Neely 63d8685240
Fix psync_my_pass wipe to use strlen instead of sizeof pointer (#338)
In psync_unlink(), putil_wipe(psync_my_pass, sizeof(psync_my_pass))
only wiped 8 bytes (pointer size) instead of the full password string.
Changed to strlen(psync_my_pass) and added NULL check.

Fixes pcl-zqv.9.1 (partial)
GH #276

Co-authored-by: Levi Neely <lkn@darkstar.example.net>
2026-03-03 17:11:10 +01:00
Levi Neely 7175636e49
Add .kiro and .claude to .gitignore (#337)
Co-authored-by: Levi Neely <lkn@darkstar.example.net>
2026-03-03 17:01:27 +01:00
Levi Neely d31b009acd
Fix data race on lastseed in prand_seed() (#330)
Mutex protects lastseed read/write
2026-03-03 16:43:59 +01:00
Levi Neely 72ef56652d
Fix race condition in pfs_reopen_file_for_writing encoder state (#329)
Crypto folder operations tested, no regression
2026-03-03 16:18:16 +01:00
Levi Neely 3e777665b6
Fix race condition in pfs_dec_of_refcnt (#328)
File operations tested, no regression
2026-03-03 16:13:22 +01:00
Levi Neely cb938aa128
Fix memory leak in pfs_update_openfile on collision (#327)
File operations tested, no regression
2026-03-03 16:10:18 +01:00
Levi Neely 07cbef9b88
Add write-permission check in pfs_write and pfs_ftruncate (#326)
Write and truncate operations tested, work correctly
2026-03-03 16:05:28 +01:00
Levi Neely c03a37527f
Fix NULL-deref in pfs_rename_openfile_locked (#325)
File rename tested, works correctly
2026-03-03 15:58:07 +01:00
Levi Neely 6ce166a0a5
Fix integer overflow in fake fileid calculation (#324)
Filesystem tested, file creation and removal work
2026-03-03 15:54:50 +01:00
Levi Neely a5b09c73c6
Add upper bound check in check_peer_pubkey() (#323)
Daemon tested, TLS works, crypto folder works
2026-03-03 15:51:54 +01:00
Levi Neely c9bb7685b7
Add POVERLAY_BUFSIZE bounds check in prpc.c read loop (#322)
RPC commands tested, sync list works
2026-03-03 15:49:18 +01:00
Levi Neely 0ae4882ada
Fix integer overflow in prpc.c response->length calculation (#321)
RPC commands tested, daemon works
2026-03-03 15:46:39 +01:00
Levi Neely d0d9ac2d77
Fix ptree_for_each_element loop termination condition (#319)
Daemon tested, starts successfully
2026-03-03 15:29:44 +01:00
Levi Neely ac25de2831
Add integer overflow checks in psync_list_builder_finalize() (#318)
Daemon tested, starts successfully
2026-03-03 15:27:07 +01:00
Levi Neely 00b4824961
Replace sprintf with snprintf in ptools.c (#317)
First login tested, no crash
2026-03-03 15:24:10 +01:00
Levi Neely 465d5b9fb6
Fix ptevent: memory leak, NULL-deref, and race condition (#316)
Upload tested, no crash
2026-03-03 15:15:22 +01:00
Levi Neely 2f733a5025
Add MAX_API_RESPONSE_SIZE bounds check in papi.c (#315)
API calls tested and working
2026-03-03 15:10:27 +01:00
Levi Neely 3240c033bb
Fix use-after-free: heap-allocate socket fd for RPC threads (#314)
RPC commands tested and working
2026-03-03 15:08:29 +01:00
Levi Neely bc943e5b69
Remove legacy Unix fallbacks from pmem.c (#312)
Code cleanup, no functional change
2026-03-03 14:55:20 +01:00
Levi Neely ebda4df468
Add HTTP Content-Length upper-bound check (#309)
HTTP Content-Length bounds check tested with file downloads
2026-03-03 13:54:17 +01:00
Levi Neely c73bcaf871
Fix FUSE channel cleanup and error logging (#311)
FUSE fixes tested and verified
2026-03-03 13:53:50 +01:00
Levi Neely 93153273f7
Fix timing side-channel in check_peer_pubkey (#308)
strcmp() at line 315 short-circuits on first differing byte, leaking
timing info about trusted fingerprints.

Replace with constant-time comparison using memcmp and bitwise OR
accumulation across all trusted entries.

Fixes GH #239

Co-authored-by: Levi Neely <lkn@darkstar.example.net>
2026-03-03 12:53:29 +01:00
Levi Neely fb8d0fc608
Fix unchecked malloc in papi_result_async (#307)
reader->data = malloc(reader->respsize) at line 462 is not checked
for NULL before goto again continues the loop and dereferences it.

Add NULL check and return ASYNC_RES_READY with result=NULL on failure.

Fixes GH #238

Co-authored-by: Levi Neely <lkn@darkstar.example.net>
2026-03-03 12:41:27 +01:00
Levi Neely 87ab65b68c
Fix integer underflow in prpc.c handler dispatch (#306)
cbidx = request->type - 20 computed before checking lower bound.
If request->type < calbacks_lower_band, cbidx wraps to large value
causing out-of-bounds array access.

Move bounds check before subtraction and use calbacks_lower_band
instead of hardcoded 20.

Fixes GH #235

Co-authored-by: Levi Neely <lkn@darkstar.example.net>
2026-03-03 12:37:13 +01:00
Levi Neely 838b826b90
Fix char[] passed as char** in ptools_set_backend_file_dates (#305)
msgErr was declared as char[1024] but cast to char** and passed to
ptools_backend_call(). The function writes a char* into *err,
corrupting the first sizeof(char*) bytes of the array.

Change to char *errPtr = NULL and free it after use.

Fixes GH #216

Co-authored-by: Levi Neely <lkn@darkstar.example.net>
2026-03-03 12:34:18 +01:00
Levi Neely 3c096565ea
Fix optional params always using index 0 in ptools_backend_call (#304)
Loop variable j was declared inside the loop and reset to 0 on every
iteration. All branches had early continue, so j++ never executed.

Change j to i - reqParCnt to correctly index into optionalParams array.
Also fix paramtype check to use j instead of i.

Fixes GH #215

Co-authored-by: Levi Neely <lkn@darkstar.example.net>
2026-03-03 12:31:01 +01:00
Levi Neely 8d203a4f97
Fix swapped struct sizes in pqevent_queue_sync_event_path (#303)
When eventid has PEVENT_TYPE_FOLDER set, the code allocated
psync_file_event_t size but cast to psync_folder_event_t.

Swap the sizeof() calls to match the actual struct types used.

Fixes GH #229

Co-authored-by: Levi Neely <lkn@darkstar.example.net>
2026-03-03 12:27:37 +01:00
Levi Neely 98ebd10c86
Fix typo: rename psync_list_bulder_* to psync_list_builder_* (#302)
Three functions had a consistent typo (missing 'i' in builder):
- psync_list_bulder_push_num
- psync_list_bulder_pop_num
- psync_list_bulder_add_element

Renamed to correct spelling in plist.h, plist.c, and all callers.

Fixes GH #219

Co-authored-by: Levi Neely <lkn@darkstar.example.net>
2026-03-03 12:23:16 +01:00
Levi Neely 81ad3d3846
Fix data race on excepions in ptimer_do_notify_exception (#301)
excepions is read without holding timer_ex_mutex, but
ptimer_exception_handler() modifies it under the mutex.

Move the read inside the critical section to prevent the race.

Fixes GH #227

Co-authored-by: Levi Neely <lkn@darkstar.example.net>
2026-03-03 12:18:31 +01:00
Levi Neely b902d47706
Fix pthread_create return unchecked in prun.c (#300)
pthread_create() return value is ignored. If it fails, the allocated
thread_data is leaked.

Check return value; on error, log and free the data.

Fixes GH #221

Co-authored-by: Levi Neely <lkn@darkstar.example.net>
2026-03-03 12:16:30 +01:00
Levi Neely beaa76adfb
Fix uninitialized keyParams in ptools_create_backend_event (#299)
keyParams is only allocated when pCnt > 0 but freed unconditionally.
When pCnt == 0, free() is called on an uninitialized pointer (UB).

Initialize to NULL so free() is a no-op when allocation is skipped.

Fixes GH #214

Co-authored-by: Levi Neely <lkn@darkstar.example.net>
2026-03-03 12:10:44 +01:00
Levi Neely c514fa1a29
Fix MAP_FAILED detection in pmem_mmap (#298)
mmap(2) returns MAP_FAILED ((void*)-1) on error, not NULL. The check
'if (likely(ret))' treats MAP_FAILED as truthy, so the emergency retry
path is never reached and callers receive MAP_FAILED as a valid pointer.

Normalize pmem_mmap() to return NULL on failure (converting MAP_FAILED
to NULL in the mmap path). This confines the platform-specific error
handling to one place and eliminates the need for preprocessor checks
in pmem_mmap_safe() and psync_mmap_anon_emergency().

Fixes GH #226

Co-authored-by: Levi Neely <lkn@darkstar.example.net>
2026-03-03 12:03:30 +01:00
Levi Neely 0f23a32793
Fix input validation: stoull exception and buffer bounds (#297)
- Wrap std::stoull() in try/catch to prevent daemon crash on invalid folder ID
- Add proper read loop for RPC messages to handle partial reads
- Validate msg->length before memcpy to prevent heap over-read
- Handle daemon bugs gracefully (EOF before full message)
- Fix operator precedence in sync remove command

Fixes #205, #206

Co-authored-by: Levi Neely <lkn@darkstar.example.net>
2026-03-03 11:55:54 +01:00
Levi Neely 73a57c994b
Fix exception handling and operator precedence bugs (#296)
- Add return statement in catch(...) block to prevent fallthrough
- Fix operator precedence in GetState() to capture Call() return value

Fixes #201, #202

Co-authored-by: Levi Neely <lkn@darkstar.example.net>
2026-03-03 11:55:36 +01:00
Levi Neely 175a46a109
Fix exception handling and operator precedence bugs (#295)
- Add return statement in catch(...) block to prevent fallthrough
- Fix operator precedence in GetState() to capture Call() return value

Fixes #201, #202

Co-authored-by: Levi Neely <lkn@darkstar.example.net>
2026-03-03 11:25:25 +01:00
Levi Neely c0cc893cc7
Fix umask and password memory wipe (#294)
* Fix debug build segfault: add strong overrides for psql_lock/unlock functions

The weak/strong symbol approach requires that psql.c undefs the debug
macros to define function implementations. This means functions in psql.c
call psql_lock()/psql_unlock() as functions, not macros.

In debug builds, these must be strong overrides that call the _do_
variants to properly maintain lockctr/rdlockctr. Without these overrides,
the weak stubs are used which don't update counters, causing assertion
failures in psql_unlock().

Added strong overrides in psql_debug.c for:
- psql_lock() -> psql_do_lock(__FILE__, __LINE__)
- psql_rdlock() -> psql_do_rdlock(__FILE__, __LINE__)
- psql_statement() (calls psql_do_lock directly)

Also made psql_statement, psql_start, and all query/prepare functions
weak in psql.c to allow debug overrides.

Fixes #138

* Fix umask and password memory wipe

- Set umask(0077) in daemonize() to prevent world-readable files
- Wipe password from memory after psync_set_user_pass()

Fixes #203, #204

---------

Co-authored-by: Levi Neely <lkn@darkstar.example.net>
2026-03-03 11:20:07 +01:00
Levi Neely 61259858c8
Fix debug build segfault: add strong overrides for psql_lock/unlock functions (#177)
The weak/strong symbol approach requires that psql.c undefs the debug
macros to define function implementations. This means functions in psql.c
call psql_lock()/psql_unlock() as functions, not macros.

In debug builds, these must be strong overrides that call the _do_
variants to properly maintain lockctr/rdlockctr. Without these overrides,
the weak stubs are used which don't update counters, causing assertion
failures in psql_unlock().

Added strong overrides in psql_debug.c for:
- psql_lock() -> psql_do_lock(__FILE__, __LINE__)
- psql_rdlock() -> psql_do_rdlock(__FILE__, __LINE__)
- psql_statement() (calls psql_do_lock directly)

Also made psql_statement, psql_start, and all query/prepare functions
weak in psql.c to allow debug overrides.

Fixes #138

Co-authored-by: Levi Neely <lkn@darkstar.example.net>
2026-03-03 07:59:30 +01:00
Levi Neely 4d64b645a1
Increase maintainability: namespace refactors for putil, pfs, and pfs sub-modules (#176)
* Fix #103: Refactor putil to use putil_ namespace and enforce encapsulation

All public functions in putil now use the putil_ prefix (e.g., putil_strdup,
putil_strcat, putil_time_format, putil_base64_encode, etc.). Internal
variables (normalize_table, base64_reverse_table) and the constructor remain
static. Updated all 34 call-site files across pclsync accordingly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Fix #96: Refactor pfs to use pfs_ namespace and enforce encapsulation

All public functions in the pfs module renamed from psync_fs_ to pfs_
(e.g., pfs_update_openfile, pfs_refresh, pfs_start, pfs_stop, etc.).
Extern vars psync_fake_prefix/psync_fake_prefix_len renamed to
pfs_fake_prefix/pfs_fake_prefix_len. Functions only used within pfs.c
(pfs_update_openfile_fileid_locked, pfs_chown) made static. Updated all
call sites across 17 files including pclsync_lib.cpp.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Refactor pfsxattr to use pfs_xattr_ namespace

All psync_fs_ prefixed functions in the pfsxattr module renamed to
pfs_xattr_ (e.g., pfs_xattr_set, pfs_xattr_get, pfs_xattr_list,
pfs_xattr_remove, pfs_xattr_file_deleted, pfs_xattr_task_to_file, etc.).
Local macro psync_fs_set_thread_name renamed to pfs_xattr_set_thread_name.
Internal static helpers (delete_object_id, update_object_id,
xattr_get_object_id_locked) remain static and unchanged.
Updated all call sites in pfs.c, pfsupload.c, and pdiff.c.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Rename pfs_xattr_ namespace to pfs_xatr_

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Refactor pfs sub-modules to use namespaced function prefixes

- pfscrypto_* → pfs_crpt_*
- psync_fsstatic_* → pfs_stat_*
- psync_fsupload_* → pfs_upld_*
- psync_fstask_* → pfs_task_* (functions only; typedefs unchanged)
- psync_fsfolder_*/psync_fsfolderid_*/psync_fsfolderflags_*/
  get_decname_for_folder/psync_get_folderid → pfs_fldr_*

Type names, macro constants, and typedef aliases are unchanged.
Updated all call sites across 17 files.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Levi Neely <lkn@darkstar.example.net>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 22:51:25 +01:00
Levi Neely d6858a0166
Fix #90, #109: Support 2FA when running as a daemon (#175)
* Fix #90: Support 2FA when running as a daemon

In daemon mode, when PSTATUS_TFA_REQUIRED fires:
- Automatically send an SMS 2FA code via psync_tfa_send_sms()
- Log delivery details to syslog with instructions to use
  `echo 'tfa CODE' | pcloudcc -k`
- Block on a condition variable until the code arrives via RPC

Add a new `tfa <code>` command to the pcloudcc -k control interface.
This sends the code to the daemon over the existing Unix socket RPC
channel (SENDTFA message type).

Bad codes (PSTATUS_BAD_TFA_CODE) are handled: the daemon logs a syslog
warning and waits for a corrected code without re-sending SMS.

Devices are trusted by default (trusted=1 in psync_tfa_set_code) so
repeated 2FA prompts are avoided for the configured trust period.
TFA codes are wiped from memory after use.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Add auth command: supply password to running daemon

Mirrors the tfa command pattern. When PSTATUS_LOGIN_REQUIRED fires in
daemon mode, read_password() now logs a syslog notice and blocks on a
condition variable rather than calling exit(1).

The new `auth <password>` control command (SENDAUTH RPC type) signals
the condvar and unblocks the daemon. Usage:

  echo 'auth PASSWORD' | pcloudcc -k

The password is wiped from the CLI-side buffer immediately after the
RPC call. putil_wipe() is used for both the tfa and auth transient
strings on the sending side.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Add status command: show current sync state from CLI

Adds a `status` (alias `st`) command to the interactive CLI and to the
pcloudcc -k control interface. The daemon-side handler calls
psync_get_status(), formats the status name plus download/upload
strings, and writes the result to shared memory. The client reads and
prints it.

Example output:
  Status:   READY
  Download: idle
  Upload:   idle

Also works non-interactively:
  echo 'status' | pcloudcc -k

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Levi Neely <lkn@darkstar.example.net>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 21:36:33 +01:00
Levi Neely e3b9f7bfd8
Remove obsolete Pending Transfers section from README (#174)
* Fix #67: Add sync pause and sync resume commands

Wire psync_pause() and psync_resume() from the C library into the RPC
command layer, registering SYNCPAUSE and SYNCRESUME handlers and exposing
them as 'sync pause' and 'sync resume' CLI subcommands.

Note: daemon quit is already handled by the existing 'finalize' command,
which calls psync_destroy() and exits the daemon process cleanly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Remove obsolete Pending Transfers section from README

The pending command now provides a proper way to check for pending
transfers, making the manual cache-inspection workaround obsolete.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Levi Neely <lkn@darkstar.example.net>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 20:17:10 +01:00
Levi Neely 79371d9aac
Fix #67: Add sync pause and sync resume commands (#173)
Wire psync_pause() and psync_resume() from the C library into the RPC
command layer, registering SYNCPAUSE and SYNCRESUME handlers and exposing
them as 'sync pause' and 'sync resume' CLI subcommands.

Note: daemon quit is already handled by the existing 'finalize' command,
which calls psync_destroy() and exits the daemon process cleanly.

Co-authored-by: Levi Neely <lkn@darkstar.example.net>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 20:12:53 +01:00
Levi Neely 0a697794dd
Add new pCloud SSL certificate fingerprint (#172)
Add SHA256 fingerprint 1b1b4d26a98774c84709c5400cd5c0b5e2f0bc7d46ef6053c9a872efe825b116 to fix OFFLINE status after pCloud SSL key rotation.

Fixes #171

Co-authored-by: Levi Neely <lkn@darkstar.example.net>
2026-03-01 09:14:29 +01:00
Levi Neely 4a870f8835
Add reference to pcloudcc-service (#170)
* Fix #162: Add distro-agnostic mbedtls detection

- Use pkg-config to dynamically detect mbedtls variants (mbedtls3.x, mbedtls)
- Fallback to /usr/local if pkg-config unavailable
- Tested on Fedora 41 (mbedtls3.6), Arch Linux (mbedtls 3.6.5), Debian Bookworm, and Slackware
- Eliminates need for hardcoded version-specific paths

* Add reference to pcloudcc-service

Closes #159

---------

Co-authored-by: Levi Neely <lkn@darkstar.example.net>
2026-02-27 09:26:46 +01:00
Levi Neely 63d650b6c8
Fix #162: Add distro-agnostic mbedtls detection (#169)
- Use pkg-config to dynamically detect mbedtls variants (mbedtls3.x, mbedtls)
- Fallback to /usr/local if pkg-config unavailable
- Tested on Fedora 41 (mbedtls3.6), Arch Linux (mbedtls 3.6.5), Debian Bookworm, and Slackware
- Eliminates need for hardcoded version-specific paths

Co-authored-by: Levi Neely <lkn@darkstar.example.net>
2026-02-27 09:20:06 +01:00
Levi Neely 0900f742bb
Fix MBEDTLS-3.x.md: Add LIBLDFLAGS update to linker path (#168)
Co-authored-by: Levi Neely <lkn@darkstar.example.net>
2026-02-27 08:44:38 +01:00
Chris82111 29b45cf218
Retry opening without the O_NOATIME flag (#167)
Change looks good, much appreciated! :) Merged.
2026-02-27 08:40:38 +01:00
Jonathan Senkerik 441a0d69ed
Refactor logging, add cache-size, fs-event-log (#163)
Much appreciated! Merged. :)
2026-02-27 08:38:28 +01:00
Levi Neely b9ea6ca4c9 Remove unused psync_status_file/folder wrappers
- Both functions were pure aliases to psync_filesystem_status()
- Never called anywhere in the codebase
- Simplified API documentation to reference only psync_filesystem_status()
2026-02-14 20:08:01 +01:00
Levi Neely 2c5e32e910 Fix #95: Remove unused get_token() wrapper from pclsync_lib
- Eliminates thin wrapper that just called psync_get_token()
- Function was declared but never used
- Simplifies pclsync_lib API as per issue #95
2026-02-14 20:08:01 +01:00
Levi Neely 11074655db Fix #8: Add pending transfer check feature
- Add new 'pending' command (alias 'p') to check for pending transfers
- Enhance 'finalize' command to warn about pending transfers
- Prompt for confirmation in interactive mode before shutdown
- Use psync_get_status() API for reliable transfer detection
- Shows upload/download counts separately
- Fix mbedtls 3.6 compatibility issues in pssl.c
- Update Makefile for mbedtls 3.x static linking
2026-02-14 19:43:13 +01:00