-
Notifications
You must be signed in to change notification settings - Fork 891
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Sign LibGit2Sharp.dll by a strong name #212
Comments
@kostrse Hmm. I'm really not sure about this... It looks like the community hasn't reach a clear-cut agreement on this:
I'm very far from being an expert on this subject, so provided some agreement is being reached on this topic, I'll be really thankful for all the help you'll be able to provide this project with :) |
If you need strongly named assemblies, you'll have to do it yourself. Strong Naming causes a ton of issues with open-source software and impedes contribution. Think of the kittens Sergey. The kittens. |
So, on a more helpful and less "Nope"y note, the easiest way for you to get this working is to fork and It's also a reasonable idea because libgit2 / libgit2sharp move at a pretty quick rate of development, so it's nice to have new features faster (and to be able to request bug fixes then quickly incorporate them). Let me know if the submodule stuff doesn't make any sense and we can help you out to get this working |
How to keep the most people happy: Sign the assembly, don't change the AssemblyVersionAttribute and use AssemblyFileVersionAttribute to represent the current version instead. No assembly binding redirect issues and people who need a strong named assembly have it. |
@kostrse the Visual Studio Package infrastructure doesn't require a strong name. The default template for packages creates one but it's actually unnecessary. Once the wizard finishes you can open up the project and delete all references to strong naming and the project will continue to run. There are indeed cases where strong naming is necessary in a Visual Studio extension. But this is generally only if you have a utility library that is versioned. Even then the package consuming the library doesn't need to be versioned, only the library itself does |
In order to do a "consecutive" fetch, we need to know what commits there are locally. Provide a delegate and event for the caller to be able to tell the Remote what commits there are locally. References libgit2#212
Add a Lookup 'event' for asking the plastic DB whether a commit is available locally, letting us know whether we should even download a packfile. References libgit2#212, libgit2#217
For others who encounter this issue and are disappointed too, this is how you can sign the assembly yourself: http://www.codeproject.com/Tips/341645/Referenced-assembly-does-not-have-a-strong-name |
I also offer strong naming as a service, should you not want to handle this issue yourself: http://log.paulbetts.org/a-modest-proposal-strong-naming-carbon-offsets/ |
Turns out that every few builds the assembly would somehow lose it's strongly signed status for some reason and I would have to strongly sign it again. I ended up just adding the following code to the "Pre-build event command line:" box in the project property page's Build Events tab to sign the assembly before every build.
Notice that the LibGit2Sharp NuGet package version is hard-coded in here, so this code will need to be updated each time you update the NuGet package. Also, the paths for ildasm.exe, sn.exe, and ilasm.exe are where they were located on my machine; they may be located somewhere else on your machine. |
@deadlydog Thanks for sharing this with us ✨ @paulcbetts 🆒 Do you foresee any price cut for Black Friday? |
@nulltoken Prices are double on Black Friday |
I'd also very much like to see this library strong-name signed so that it can be used from other strong-name signed projects. But I wouldn't go to any of the trouble originally proposed to "transparently sign on the CI". Just check in the unencrypted private key with the source. That way, everyone can continue to build and use the source in place of the "official" one, as open source folks like. I challenge anyone who disagrees to please state the concrete things that break (or @paulcbetts, show me the kittens) or become harder to deal with if this project were to be strong-name signed. |
I agree with @AArnott. In fact, checking in the key is inline with our official guidance now:
|
As we don't care about the GAC, there's only two things that SN would do for us. One is allow SN assemblies to depend on libgit2sharp, and the other is loading multiple versions of libgit2sharp in the same process. We however absolutely do not want to allow multiple libgit2sharp versions to be loaded into the same process. That involves loading multiple versions of libgit2 into the process, which is either going to crash upon load, or (if the OS allows the functions in C's flat namespace to be overridden) it's going to crash because the structs aren't the right size or the functions have different signatures. |
But now you're talking about working around the SN features and changing how the release works. If we can't bump the assembly version, is there a way for the tools to keep track of which is the right version to load? The API hasn't stabilised. If a method gets extra parameters or gets removed, what do you use to know you're in the right version? Not loading multiple versions isn't just a non-goal, it's something that must be avoided. |
Strong naming doesn't mean multi versions can be loaded (as far as I know) When I wrote what I said previously I wasn't aware that when you're strong named and there is a version in the GAC it will always take prescidence over what is in the bin. Something to keep in mind. |
Yes, if it's in the GAC with the same assembly version, the GAC always wins. So clearly, for this scheme to work, you want to keep it out of the GAC, which is normally what happens in the NuGet world. Note that if you have multiple versions in the GAC, you can in fact load them both, but it's rarely a good thing. |
I wonder why you keep the same assembly version across releases when your API hasn't stabilized. Wouldn't you want to rev the version so folks know there are changes and encourage them to recompile to accommodate the breaking changes? |
Each release does bump the version to indicate a change in the API. It's the SN proposal which has libgit2sharp fixing its assembly version. |
@carlosmn Would that be to try to prevent apps from loading the assembly twice? You might be losing more than you're winning there. You can't prevent an app from loading your assembly twice, even by keeping the strong name the same. They can use two app domains, for example. I think it would be a misuse of assembly versions to try to use it to prevent multiple loads at once. I think documenting that folks shouldn't do it is sufficient deterrent, without getting in the way of what apps do need to do, and creating other real technical problems by keeping your version the same between releases. |
@AArnott and that is one of the many reasons the CLR is abandoning the concept of AppDomains. They are a kludge for a problem that never really existed. There's really no good reason for this library to be strong name signed other to show loading into strong name signed execution space. Since libraries can be signed after the fact, I recommend the consumer sign as needed. |
@whoisj The consumer signing as needed doesn't work very well (if at all) in a nuget world, IMO. Scenario 1: consumption Scenario 2: libgit2sharp as an indirect dependency In a world where the consumer is checking in binaries, and using nuget only as a library of DLLs that they download and then check in, yes, signing is not that out-of-the-way. But for the more modern developer (quite likely open source) who relies on nuget packages to avoid checking in binaries for their dependencies and keep them updated, packages with assemblies that are not strong-name signed make them very expensive to adopt and maintain a dependency on. |
@shana Just for my understanding, provided we took the decision to go the strongly-sign path, what would be the point of releasing both signed and unsigned NuGet packages? |
I'm working on providing a managed SSH implementation for libgit2sharp, but the new dependency isn't signed. If we always sign libgit2sharp, we cannot make use of this dependency, or we'll have to go and annoy them enough for them to sign it. |
@nulltoken No real point, technically. Once a library is signed, it can be consumed by signed and unsigned apps and libraries, so there's no real need for an unsigned variant from a consumer's point of view. I just added both in my comment because I know that there's feels about this that go beyond the strictly technical arguments. In scenarios where an app loads plugins, dependency loading is seriously broken when assemblies are not signed. Versions are not enough to distinguish assemblies from each other, and the only way to make sure that the libgit2sharp assembly that I want loaded is the one that actually gets loaded is for everything to be signed. This is the reality of .NET, and there's no way around it, unfortunately. |
Is this not the reality of any kind of dependency loading?
^^ this is my primary concern about signing LG2#. We're going to end up with two variants: one signed but limited and one unsigned and complete. As I understand it, the assembly can be signed after the fact and therefore I'm confused as to why the consumer cannot sign the assembly they want after we publish? |
Not really. In other dependency loading/tracking systems, name+version is the key to identify which dependency to load (the best example of which is the debian packager, but msi installers is another). In .NET, it's name+version+token.
Assemblies cannot be signed after the fact and still be useful without a key. When delay-signing is activated, .NET will refuse to load the assembly until the signing is complete. Delay-signing serves a different purpose, which is mostly pretend-security - i.e., using signing as a way to ensure that what you're loading has not been tampered with. Developers sign with temporary development keys, and when you release, you replace things with the permanent key. Unfortunately, this is all make-believe, because the runtime doesn't validate that the hashes encoded in the assemblies match the key (that would cost too many cycles when loading the class libraries and make .net slower in general), so signed assemblies can be rewritten and keys regenerated after the fact. All in all, delay signing is not an option (did I mention the whole .NET versioning/signing architecture is #$#$%$%? Again, it's the reality we have to live with) In the case of the SSH dependency mentioned above, that SSH library faces the exact same problem libgit2sharp faces: if it's not signed, anyone that requires signing due to how .NET versioning and dependency tracking is implemented will be forced to fork and sign it; if it's signed, everyone can use it. |
Just to say that, since I can not depend on any official LibGit2Sharp dll (because I am signed), my current workaround is to locally sign it and ILMerge it to my dlls. One of this merge is mandatory (MSBuild task library), but the other one (a Cake build extension) is just stupid.. but it works. |
Up to this point, nine days and lots of time have been spent discussing this. That's only the time spend trying to convince LibGit2Sharp to add a strong-name - the same amount of time would have to be spent trying to convince all other non-signed dependencies you have to sign. That's a lot of wasted time. Time that could have been spend doing other things (one suggestions follows shortly). All this because, in it's essence, this is a poison that is being caused because somewhere along the tech stack (be it VS to allow you to author plugins or what not) that you use, someone decided to involve a strong name, this forcing the rest of the stack to follow suite (or end up with this discussion over and over again - this must be my 10th time). I'm going to go out on a limb and say that for a vast (like realllly vast) majority this only comes down to "I'm using X that is signed so I need Y and Z" to also be signed" and nothing to do with security or to authenticate the origin of the dependencies Here is my suggestion on what to do instead sign them yourself! Really. Hear me out. You don't need my key.. you need A key .. that's a huge difference. Don't burden me with your problems (really). Hard to do? No, but it sure if going to be a bit tedious to do over and over again (and in reality, how often does you dependencies bump their version? And do you really have to upgrade those dependencies to the latest version all the time? Could it be done in a more controlled fashion?) so why not automate it?
Or make it easy for yourself
Seriously you can run a Team City instance on pretty much any box and you can even host it on Azure for peanuts (if you have MSDN you might even have free monthly azure credits to spend). The point is, this is not hard and would
We (NancyFx) must have gotten this request 20+ times over the years and and we've put a Statement on Strong Naming on our Wiki - In short, we'll not sign it. 20 might sounds much, but we've had 100,000's of downloads so it's a drop in the ocean. Newtonsoft.Json - probably the most famous strong named open-source project has caused more devs assembly-binding-rediects nightmares than anything else know to the .new community even though they've taken the "lock the file version and bump the assembly version" (or the other way around, can't really remember right now) approach ... It's not going to be as easy as "if you sign it you help everyone, but if you don't then you screw over the guys that needs it to be signed" To the LibGit2Sharp-team... I urge you to gain some perspective of this.. how much work will it cause you down the road (evaluate it!).. how big portion of your user base actually require YOU to publish a strong-named version.. add it up and see if you find it a viable option. Then, and only then, move forward with this. |
Sorry, I prefer assembly rebindings issues to missing method exception runtime errors. But I should be an old school guy... |
@olivier-spinelli Cool. Automate the signing of your dependencies https://www.jetbrains.com/teamcity/ and pull the nugets straight from it. Problem solved. No? |
i'm with @thecodejunkie don't demand libs to be signed. do it yourself if you really need to (and then, i feel sorry for you), but don't demand it on the rest of the world. that just spreads that dissease. |
I just want my OS packages to be on nuget.org ecosystem not on yet-another-nuget-source. |
Nuget was never designed to be a single-repository design. There's even native support, for multiple repositories, in the visual studio package manager
I'm sorry but this is just another way of saying "I don't want the burden, better someone else has it". Having the LibGit2Sharp team sign it adds zero benefits, other than you not having to do it yourself. No heightened security nor trust. There'd, literally, be no binary difference between what you build and sign, and what someone else builds and signs, because you'd be building straight from the source code that you pull in from the repository |
Aaaaand this is why I am weary to get into these discussions and I say there's feels. Signing is not a disease, it's a basic requirement of versioning in .NET, and while I understand how annoying it is (because yes, it is stupid and the GAC is annoying and assembly redirects are annoying and the whole thing is badly thought out), it is what it is. It's not a disease or a curse or a conspiracy or evil or whatever, it's just a versioning architecture. sigh |
@shana No one (AFAIK) is recommending that any open source project use delay signing. Certainly not on this thread. The "private key" should be checked in unprotected so anyone can build the project as they can today. Shana says:
This is why it's not cool to just tell folks to sign packages themselves. It's not shifting the burden -- it's eliminating it. Its very hard to sign the packages ourselves as consumers. But it's trivially easy to sign the original. Also: while for this particular package, it's unlikely to be used for interop across assemblies. But for many other very useful packages on NuGet (we'll call one package X), it's very important that an application that uses several packages be able to share a common definition of X and talk to each other with types defined in X. That's impossible if all these other packages have their own copies of X, signed with their own keys. Flat out impossible. No buts about it. The only way to fix this is for X to sign itself and thus everyone shares a public key for it. Since that's the undebatable truth for many packages, by libgit2sharp signing itself, it becomes useful to package X. |
I don't understand why folks are so pushy against the idea. They have nothing to gain from resisting it. The folks who want it strong-name signed have much to gain if it happens, and yet the opposition has nothing to lose or gain either way. So what is it to them? Why make it so hard (and waste 9 days, @thecodejunkie) making a fight over what should be a simple decision? As was originally mentioned, the only possible downside to signing this package is the potential for wanting it to take a dependency on some other package that is not yet signed. That was said then, and it's still now the only downside mentioned on this whole thread. So please, let's end the debate and just let the project owners make a decision based on their roadmap and likelihood to take such a dependency. |
with even people from the asp.net team (amongst others) fighting against that dissease spreading any further, maybe, just maybe, there's a point in fighting signing, @shana. and yes, @AArnott we gain from not having a signed version. as a lot of people will have a harder life by having the signed version pulled in. as it happened times and times before. this is not the first time this topic exist. it, sadly, won't be the last time. don't sign. it's the only right thing to do. if you need it, do it YOURSELF. for YOUR needs. |
@davepermen Please tell us how it makes your life harder if this is signed. |
It's not an idea, it's an imposition that a minority of users are demanding of an external project to have their preference imposed on its entire user-base. This is a decision that's solely up to the project maintainers, you may request the change, but you shouldn't feel it's your right to demand it or expect project maintainers to action it. It's irrelevant what reasons .NET OSS projects have to not want to sign their builds, they have their own experience and can make their own judgement. It's likely their primary focus is not your use-case, that doesn't mean you should try force them to accommodate your use-case, but it's a good indication that it might be time to hit the [Fork] button and sign your own builds. Thanks to the easily reproducible nature of software, this effort only needs to be done by 1 volunteer who can then share their signed builds for everyone who wants it, to enjoy - whilst not affecting anyone who doesn't. |
@mythz I don't think anyone here is trying to force this project to sign. That would be fruitless. |
@AArnott: thanks for your comment (english not being not my mother tongue, it sometimes hard for me to debate).
Oups! One "minor" detail: the namespace! The name of the package is its name. Multiple sources with conflicting names "LibGit2Sharp.Strong" will be a mess. So I'll put "MyCompany.LibGit2Sharp.Strong" and so will do all the guys like me that needs one... and we'll end up with multiple packaging of the same version. And the Kittens will die. |
@davidebbo WebActivator has had 6 minor releases all of which has a signed version of 2.0.0. of course you've had no problems with strong name because your version never actually changed! Release a 2.1 or a 3.0 and then see what happens. Oh, strong naming is broken, lets use assembly binding redirect to bypass it! Paper over cracks? I'm willing to wager the majority of pro-signing advocates are commercial concerns. So here's an idea, pay the oss maintainers to produce a signed lib for you. Afaik @paulcbetts has received ZERO for his offer of said thus far. |
@AArnott two libs with a transitive dependency on the same signed lib = hell. Non deterministic assembly loading order. Random runtime exceptions. Lovely! |
@damianh If you've got a transitive dependency on two different versions, then what you probably want is to use the higher version. With strong names, you need binding redirects to do this, but as of VS 2013, MSBuild will do this for you automatically. With that in mind, how are transitive dependencies with different versions any worse with strong names than without them? I'd only expect you to run into problems if the newer version of the library broke compatibility with the old one, but you would have run into the same problem without strong names. |
Jesus christ can we stop signing stuff. It's so painful it makes me want to self immolation. of GOOD reasons to sign: 0Either IL Merge the unsigned assemblies into your project for use, or sign the assemblies yourself as a build step, or setup your own build to sign them. This thread should be closed and locked. |
The lack of unfounded fears and misunderstandings about strong naming has reached fever pitch in this thread :) Here is a simple challenge for you: name one negative thing about JSON.NET being strong named (with a fixed version as discussed above), compared to it not being strong named. I'm talking about a concrete tangible thing that makes it worse for consumers of that assembly. I have not seen one in this thread, so I'm curious if there is anything behind all the great passion ;) |
Wouldn't know, after all the pain I had with JSON.NET after it was signed with RavenDB/Nancy etc. I stopped using it. I haven't used it since V5 in my personal projects. We use it at work but we IL Merge it because we get version conflicts between our two applications and a shared assembly between them. By IL Merging and internalizing we effectively have 2 versions. What ever shitty version MVC or WebAPI is using, + the version our shared assembly is dependent on. |
The version conflict situation would happen equally if it was not strong named. So lots of passion, but no concrete argument against it being strong named. Anyone? |
RavenDB's issues were caused by it requiring the pre ISO dates version of Json.NET and Web API requiring the post ISO dates version of Json.NET. It had nothing to do with strong naming. I don't want to defend strong naming, it's caused a lot of problems, but if you're going to argue against it could you at least understand it? Also this is the only strong naming related Json.NET issue (I think) that I know of, and it's pretty specific to Json.NET's unbiqidious nature: https://connect.microsoft.com/VisualStudio/feedback/details/816725/visual-studio-referencing-dll-in-c-program-files-x86-microsoft-visual-studio-12-0-blend-directory-incorrectly |
The core team is discussing this in a more private forum (for reasons which should be apparent from this thread) and we will continue to discuss and think about it and what it would mean for taking on dependencies. Some good technical points were raised, but the discussion has veered off into what looks more like a shouting match. Thanks to all who have been clearing up misconceptions and remained civil. @phillip-haydon the form of rhetoric you are using is not conductive to discussion and is not welcome here; showing up to a thread on a public forum swearing is not acceptable behaviour. As it happens, different members of the team have been on holiday lately, so there hasn't been time to discuss the newer arguments and it's going to take a while for us to be able to reach a consensus. This is an issue where feels are plentiful, as has been pointed out. I'm locking this issue to avoid it careering off further before we're ready to look at the arguments. |
VSPackage (Visual Studio extensions) development requires usage of strongly-named assemblies.
As result, NuGet package version of the library cannot be used out of box in such scenarios.
It would be very helpful to add singing of the library on the build server and distribute the signed version.
As it would solve my problem, also it give ability to distinguish the "official" releases from custom built binaries by other members of community.
The process of signing can be made absolutely transparent: private key can be stored on a build server, as well as *.csproj files can be patched with necessary strong name properties directly during CI build.
I can provide all the necessary information how to implement this and help with modification of MSBuild script.
Thanks,
The text was updated successfully, but these errors were encountered: