Skip to content

Conversation

@Vrihub
Copy link
Contributor

@Vrihub Vrihub commented Oct 28, 2025

Proposed changes

This fixes #3869, when one wants to log into an ftp server only providing username and hostname, and relies on mc to retrieve the password from the .netrc file. Without this, mc retrieves the password from the .netrc file, but doesn't actually use it to login, and asks the user for a password instead.

Please review, this works for me, but I'm not 100% sure it's the best solution.

Checklist

👉 Our coding style can be found here: https://midnight-commander.org/coding-style/ 👈

  • I have referenced the issue(s) resolved by this PR (if any)
  • I have signed-off my contribution with git commit --amend -s
  • Lint and unit tests pass locally with my changes (make indent && make check)
  • I have added tests that prove my fix is effective or that my feature works
  • I have added the necessary documentation (if appropriate)

@github-actions github-actions bot added this to the Future Releases milestone Oct 28, 2025
@github-actions github-actions bot added needs triage Needs triage by maintainers prio: medium Has the potential to affect progress labels Oct 28, 2025
@Vrihub Vrihub marked this pull request as ready for review October 28, 2025 10:46
MC_PTR_FREE (path_element->password);

if (path_element->password == NULL)
path_element->password = g_strdup (new_passwd);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no reason to duplicate new_passwd that is just free'd below.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, I think this is the safest and easiest way to code that, isn't it? What would be your way of doing it?

I'm more concerned about this introducing a logical mistake. I think this if-block should go above the previous one. Otherwise, it just reverts the effect of the previous condition, but not only for the same user but also for a different user.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, there's a logical error, but I think the correct way is using else, see my latest fixup commit. I've tested the following cases and mc behaves as expected:

  • ftp://host: uses user and passwd from .netrc
  • ftp://user@host: uses user's passwd from .netrc
  • ftp://user_not_in_netrc@host: asks for user_not_in_netrc's password

Please just confirm that it's ok to use g_strdup(), I'm not sure about that, I've used it in analogy with line 364 path_element->user = g_strdup ("anonymous");

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please just confirm that it's ok to use g_strdup(), I'm not sure about that, I've used it in analogy with line 364 path_element->user = g_strdup ("anonymous");

Well, if I just do path_element->password = new_passwd;, the ftp login fails, and mc segfaults.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, if I just do path_element->password = new_passwd;, the ftp login fails, and mc segfaults.

Because of use-after-free. You can take new_passwd in the one branch and free it in the other one.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually think that branching free is less safe than duplicating the string. The performance penalty of a few microseconds is negligible, because it isn't in a loop, but if later more code is added, whether to free or not has to be correctly considered in all branches. As we can see, we have a lot of bugs creeping in due to subtle errors in conditions. Using g_strdup always, even if it's not really needed, is more like ownership transfer semantics in C++. So it's harder to make a mistake when the code is modified later.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually think that branching free is less safe than duplicating the string. The performance penalty of a few microseconds is negligible, because it isn't in a loop, but if later more code is added, whether to free or not has to be correctly considered in all branches. As we can see, we have a lot of bugs creeping in due to subtle errors in conditions. Using g_strdup always, even if it's not really needed, is more like ownership transfer semantics in C++. So it's harder to make a mistake when the code is modified later.

I disagree.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So how do you want to have it? Like in the first or second fixup?

@zyv zyv added area: vfs Virtual File System support and removed needs triage Needs triage by maintainers labels Oct 28, 2025
@zyv
Copy link
Member

zyv commented Nov 1, 2025

/rebase

…tp vfs

Signed-off-by: Vrihub <Vrihub@users.noreply.github.com>
Signed-off-by: Yury V. Zaytsev <yury@shurup.com>
@zyv zyv changed the title Fix for #3869, actually use the .netrc password Ticket #3869: actually use the .netrc password for ftp vfs Nov 1, 2025
@zyv zyv modified the milestones: Future Releases, 4.8.34 Nov 1, 2025
@zyv
Copy link
Member

zyv commented Nov 5, 2025

@mc-worker ok?

zyv added 2 commits November 5, 2025 11:46
…d for ftp vfs

Signed-off-by: Yury V. Zaytsev <yury@shurup.com>
…password for ftp vfs

Signed-off-by: Yury V. Zaytsev <yury@shurup.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: vfs Virtual File System support prio: medium Has the potential to affect progress

Development

Successfully merging this pull request may close these issues.

ftp: fail to retrieve password from .netrc when user is in URL

3 participants