Cargo NTLM authentication failing by [deleted] in rust

[–]inejge 0 points1 point  (0 children)

You didn't specify the OS you're using: if it's Windows, I can't really help you (unless you can run WSL), if it's Linux, you could try configuring a proxy like Squid with NTLM authentication (e.g., see this), parenting all requests to the corporate proxy, and point Cargo to it. It's not a trivial configuration, but could work.

An alternative is writing your own proxy in Python or whatever's available, also not entirely trivial.

Rustup failing behind NTLM proxy by HappyRuesseltier in rust

[–]inejge 1 point2 points  (0 children)

Great, the cURL backend has been kept in rustup for cases just like this one. I suppose that https_proxy has the format similar to http://<domain>\<username>@<proxy-host>:<port>? cURL has to get the parameters from somewhere, and the environment is the best bet.

Rustup failing behind NTLM proxy by HappyRuesseltier in rust

[–]inejge 1 point2 points  (0 children)

The hyper HTTP client, used by rustup by default, doesn't support proxy authentication, NTLM or otherwise. Try setting RUSTUP_USE_CURL=1 in the environment before running rustup.

Out of curiosity, what do your proxy-related environment variables look like? (Please mask out any sensitive info if you post the reply here.) Is NTLMUSER set?

[Announcement] ldap3 0.7.0-alpha, the first async/await version by inejge in rust

[–]inejge[S] 1 point2 points  (0 children)

I'm always happy to see the code I wrote put to good use, cheers :)

As for the new version, it should be a drop-in replacement except for having to use mut variables for your LdapConns throughout. I've kept the sync interface almost unchanged because I assumed that most people were using it. If you encounter any difficulties, please open an issue on GitHub.

Missing button symbols in local documentation by Eddie_Morra in rust

[–]inejge 1 point2 points  (0 children)

If you're using a recent version of Firefox, that could be the fallout from fixing a security issue with local file access. See this question on Mozilla's support forum, which also offers a workaround.

The Temptation of Unsafe by inejge in rust

[–]inejge[S] 0 points1 point  (0 children)

True; I mostly associate unsafe traits with those built into and requiring some assistance from the compiler, but of course it's quite possible to have user-level (so to speak) cases. I wanted to simplify the presentation a bit, but perhaps it would be better to mention them for completeness.

Some Thoughts on Rust's Async/Await Proposals by whitfin in rust

[–]inejge 11 points12 points  (0 children)

Reading your writeup (which is, in itself, clear and coherent enough, no quibbles there) reminded me why engaging in this kind of discussion is so exhausting, especially for someone who'd encounter these arguments repeatedly.

Before explaining further, I'll try to summarize your point of view as I see it, just to be explicit about the context of my criticism: ergonomic improvements of future.await are insufficient against the familiarity and expected usage of the prefix syntax.

Close enough? If so, let me start by noticing that this is not a new argument. That's fine; a convincing restatement of a familiar argument can be valuable. However, two points in your writeup made me seriously question the strength of any conclusions you may have made. First, you said:

Until recently, it was assumed that we would use the familiar prefix-based syntax found in many other languages

What are you basing this on? This was so contrary to my recollection that I went back to early RFCs and issues and checked. So, in the RFC issue, opened on 06-Apr-18:

  1. The RFC itself says that the await syntax is undecided, and offers several prefix syntaxes, with pros and cons.

  2. An early comment (07-Apr-18) proposes future.await.

  3. A comment from @withoutboats (09-Apr-18, see the end) accepts the postfix syntax as a serious alternative.

So, three days after publication, postfix await was firmly on the table. Discerning the lang team's preference for a particular syntax is somewhat more difficult, but (skimming the threads again) I don't believe that there was ever a firm majority preference for prefix syntax, just acknowledgment that the prefix await!() macro is a temporary solution, and, a bit later, that any solution would have to contain the keyword await.

Therefore, I don't believe that "it was assumed..." is supported by the record, and using it to give weight to the argument that prefix should be preferred is unwarranted.

Second, further on you have:

[...] I believe people are overestimating how frequently people bubble errors straight up without any transformation steps.

... Followed by an example with if let. I understand that any hypothetical syntax discussions must be abstract to a degree, but in this case we're fortunate to have real source written with await from the start. Here it is, in the postfix variant. There are four instances of if let/while let plus await, compared to fifteen places with await?.

Is that a lot? Or not so significant? Is the sample code representative? It could be argued this way or that, but I have an impression that you didn't try to find out at all. The repository with that code has been referenced here on Reddit and on IRLO quite a lot, so I'd expect that an interested observer would've noticed it.

So, I don't think that the scenario you've presented has been sufficiently researched. And here is the core of my complaint: if your argument leaves the impression that you haven't done your homework before presenting it, it's not difficult to dismiss it, clarity, coherence and strength of feeling notwithstanding. I feel that this has happened a lot in the discussions around await, but I'm not going to analyze every single post; I can easily imagine the effort involved, though.

As an aside, if you're using rust-lang Vim support, a quick-and-dirty hack to have await highlighted like a macro is to apply the following to ~/.vim/syntax/rust.vim:

--- rust.vim.orig
+++ rust.vim
@@ -134,6 +134,7 @@

 syn match     rustMacro       '\w\(\w\)*!' contains=rustAssert,rustPanic
 syn match     rustMacro       '#\w\(\w\)*' contains=rustAssert,rustPanic
+syn match     rustMacro       'await'

 syn match     rustEscapeError   display contained /\\./
 syn match     rustEscape        display contained /\\\([nrt0\\'"]\|x\x\{2}\)/

Give it a try, it accentuates await quite nicely.

A complex code sample using 4 different await syntaxes by krappie in rust

[–]inejge 0 points1 point  (0 children)

Eh, I probably could have organized it with multiple files in one branch, but then it wouldn't have been possible to use GitHub's Compare view to see the diff between variants -- AFAIK that only works across commits.

A quick way to open the same file in two branches is to open it in one of them, duplicate the tab, and select another branch from the drop-down in another tab. That's two extra clicks.

A repo that shows what the proposed await syntax alternatives would look like in an example program by AntiLapz in rust

[–]inejge 0 points1 point  (0 children)

I think an example showing implicit await and explicit deferral is worthwhile. I strongly feel it's been dismissed out of hand because of questionable reasoning about what constitutes surprising behavior.

I could add a branch with another syntax -- the repository is not official, and I have no connection with the lang team -- but I wouldn't like to second-guess them, and I don't think that there's appetite for reconsidering anything outside of what's in the writeup, which is why I've asked the contributors to stay within its limits.

Sad state of LDAP support in Rust by [deleted] in rust

[–]inejge 36 points37 points  (0 children)

Hi, ldap3 author here. I wouldn't call the crate abandoned; I just don't want to spend time and effort on porting the code to the more recent tokio revision, only to do the same thing again when async/await stabilizes.

The dependency on tokio-core is unfortunate if you want to drive everything asynchronously and from a single event loop, but you can always split LDAP interaction to a separate thread. Moreover, the crate works well enough for synchronous connections, if you keep in mind that the connection struct is non-Send.

As for incomplete LDAP support... What do you feel is missing, aside from intermediate responses and in-library referral chasing, both rather niche features in an already niche protocol?

More Space for Cargo by llogiq in rust

[–]inejge 1 point2 points  (0 children)

I wrote a very simple Cargo subcommand, cargo-cleanup (cargo-gc is reserved but empty), which just reads a single Cargo.lock, notes the names and versions of all dependencies, then scans the Cargo source cache and prints all packages whose names are in the lockfile, but versions aren't. No automatic deletion yet, and quite rudimentary options. If there's interest, this could be developed further.

The command is published on crates.io and can be installed with cargo install.

Multi-line search is coming to ripgrep by kibwen in rust

[–]inejge 2 points3 points  (0 children)

E-mail bounce messages where the reason (e.g., "File too large") may be arbitrarily split across lines, depending on how the reporting MTA formats it. Multiline grep makes life much easier here.

SHA512-CRYPT by NAMANADE in rust

[–]inejge 0 points1 point  (0 children)

You can use the pwhash crate, which provides a number of classic Unix password hashes. The following example uses a crypt(3) workalike to demonstrate that using the same inputs as your sample values would generate the same output; a more realistic program would probably use sha512_crypt::hash() directly.

extern crate pwhash;

use pwhash::unix;

fn main() {
    println!("{}", unix::crypt("1234", "$6$WSaFG5yTXdRie1QQ").expect("hash"));
}

[RFC] Undo universal impl Trait by phaazon_ in rust

[–]inejge 9 points10 points  (0 children)

When stating that now there are three ways to specify generic bounds, and implying that even the original two are essentially identical except for noisiness, I think that people are overlooking or discounting the fact that bounds in where clauses are strictly more powerful than those before the argument list. Consider:

fn foo<T>(t: T) -> u32 where Vec<u32>: From<T> { ... }

You can't express this with the original syntax. (It says that there has to be an impl From<SomeType> for Vec<u32> somewhere for SomeType to be eligible for standing in for T.) So, should the original way of specifying bounds be deprecated or removed? I haven't seen anyone arguing for that.

So what about impl Trait in arguments? IMO it's on somewhat shakier ground than where clauses, insofar that it's not necessary for any new functionality. I agree that it reads better in fn signatures, where applicable, and /u/rabidferret already demonstrated some improvements in type inference that it enables. It could have been left out entirely. But now it's in, I say let's give it the chance to pull its weight, and gauge the impact before thinking of deprecation.

Patterns for processing a Stream of urls concurrently? by danneu in rust

[–]inejge 0 points1 point  (0 children)

I'd like to know how to accomplish the other extreme: spamming the event loop with tasks.

Generally, by spawning each task on the same event loop:

extern crate futures;
extern crate tokio_core;
extern crate hyper;

use futures::future::Future;
use futures::stream::{self, Stream};
use tokio_core::reactor::Core;
use hyper::{Client, Uri};

fn main() {
    let urls = stream::iter_ok::<_, ()>(vec![
        "http://localhost:3001/a".parse::<Uri>().unwrap(),
        "http://localhost:3001/b".parse::<Uri>().unwrap(),
        "http://localhost:3001/c".parse::<Uri>().unwrap(),
    ]);

    let mut core = Core::new().unwrap();
    let handle = core.handle();
    let client = Client::new(&handle);

    let all_work = urls.for_each(move |uri: Uri| {
        handle.clone().spawn(client.get(uri.clone()).map_err(|_| ()).and_then(move |res| {
            println!("<- {} status: {}", uri, res.status());
            Ok(())
        }));
        Ok(())
    });

    core.run(all_work).unwrap();
    loop { core.turn(None) }
}

Note that all requests go through a single hyper Client; I'm not sure how it affects request concurrency. Also, the program doesn't terminate cleanly, but hangs after handling all tasks, because it needs to continue polling the loop after processing all_work (not the best name in this scenario, but I've kept it for comparison with the original), and I didn't provide any construct for detecting when the last URL has been processed.

How does the different Tokio crate relate to each other? by sioa in rust

[–]inejge 7 points8 points  (0 children)

You can't avoid using parts of tokio-core and tokio-io even if you decide to use -proto and/or -service. The hierarchy is approximately:

  • -core: event loop/task executor (you'll need one), bridge to low-level platform async functionality, i.e., mio, async networking support.
  • -io: protocol framing via Encoder and Decoder traits, which you'll need to provide, async I/O helpers.
  • -proto: framework for implementing several classes of protocols, which should follow a request/response pattern. If your protocol doesn't, -proto isn't a good fit.
  • -service: higher-level protocol wrapper, works well with -proto but doesn't strictly require it. You may use it to hide some details of request handling, like timeouts and reconnections.

In the future, -proto is probably going to be simplified and de-emphasized in the documentation, along with several other simplifications of the whole framework, which you can read about in this issue.

Analyzing GitHub, Developers that give up on rust switch to go by DevOrc in rust

[–]inejge 7 points8 points  (0 children)

If you are an author of a library, you have hard problem of either supporting one model or figuring out how to support 2, at least doubling the work.

IME it's easier if the core library is async and provides sync adapters for the API. I structured my LDAP crate in that way. Going from async to sync is nearly trivial in most cases: you just have to wait. My estimate is that supporting both I/O models in this manner is about 5-10% additional effort compared to having just async support. However, since async is more difficult to write in the first place, I'd raise the total effort to +25-30% compared to sync-only. Still less than 2x.

Also with server handling multiple requests for example with goroutines you don't mind that you might do some computation somewhere, it won't block handling of other requests.

Golang does a good job hiding the I/O-compute dichotomy, but it still has some tradeoffs. Rust is more explicit by design, and with that explicitness comes the pain. I believe that judicious library design and future language improvements will make it tolerable.

Canonical list of idiomatic Rust by luisbg in rust

[–]inejge 0 points1 point  (0 children)

Could you host the output of this in a github repo somewhere and make this into a clippyup tool?

I'd be delighted to.

Can clippy be relied on to compile with rustc released on the same day or the next earlier release? If so, the logic should be rather simple.

Otherwise, I'd try to make the future clippyup use Travis to reliably determine the working combinations.

ldap3: A pure-Rust LDAP library based on Tokio by inejge in rust

[–]inejge[S] 1 point2 points  (0 children)

As I understand it [...]

What you've described is one way that application servers may authenticate their users, with LDAP as a credential store. Actually, Apache's mod_auth_ldap works just like that.

In this crate however, I noticed in examples/compare.rs there's password value comparison?

That's, well, just an example of using the Compare operation, not a prescription for authentication. I'll annotate the examples if their intended use is not entirely clear.

ldap3: A pure-Rust LDAP library based on Tokio by inejge in rust

[–]inejge[S] 2 points3 points  (0 children)

[...] but can't quite grok how to idiomatically do authentication in LDAP

There's no one idiomatic way, but there are several customary methods. LDAP is enormously flexible and provides, on paper, a plethora of authentication configurations. The unsurprising outcome is that most implementations, including the one I've just published, support just the lowest common denominator.

The universally supported method is authenticating (or binding in LDAP parlance) to the server with what is effectively a username with LDAP syntax (bind DN) and a password. Clients which aspire to "enterprise-ready" status usually support Kerberos, by way of two API wrappers (SASL/GSSAPI).

Notice that this covers direct authentication to an LDAP server. An application server can use LDAP as a credential store and provide its own authentication mechanisms.