2222#include "gettext.h"
2323//#include "config.h"
2424//#include "environment.h"
25+ #include "object-name.h"
2526
2627void globalinit (const char * dir , const char * url_arg );
2728int set_option (const char * name , size_t namelen , const char * value );
@@ -48,11 +49,15 @@ void initbare(const char* dir);
4849char * mktemplate (const char * name , const char * email , const char * date , const char * msg );
4950void fetchpattern (const char pattern );
5051void metainit (void );
52+ void readmeta (void );
5153char * writemeta (char * output );
5254int encrypt_buffer_gpg (struct strbuf * buffer , struct strbuf * output ,
5355 struct string_list * recipients );
56+ static int decrypt_buffer_gpg (struct strbuf * buffer , struct strbuf * output ,
57+ struct strvec * key_ids );
5458void myupdaterefs (const char * refname , const char * oid );
5559void encryptstrbuf2obj (struct strbuf * in , struct object_id * obj );
60+ void decryptobj2strbuf (struct object_id * obj , struct strbuf * out );
5661
5762/*static*/ const char * CRYPTREADME = "# 401 Unauthorized\n\n"
5863"This is an encrypted git repository. You can clone it, but you will not be\n"
@@ -71,7 +76,10 @@ static struct strbuf url = STRBUF_INIT;
7176static struct strbuf prefix = STRBUF_INIT ;
7277
7378void globalinit (const char * dir , const char * url_arg ) {
74- chdir (dir );
79+ //int nongit;
80+ if (chdir (dir ))
81+ die (_ ("Could not chdir to '%s'" ), dir );
82+ //setup_git_directory_gently(&nongit);
7583 options .verbosity = 1 ;
7684 options .progress = !!isatty (2 );
7785 options .atomic = 0 ;
@@ -345,6 +353,25 @@ void encryptstrbuf2obj(struct strbuf* in, struct object_id* obj) {
345353 free (encrypted );
346354}
347355
356+ void decryptobj2strbuf (struct object_id * obj , struct strbuf * out ) {
357+ char * data = NULL ;
358+ unsigned long datalen ;
359+ enum object_type type ;
360+ unsigned char * decrypted = NULL ;
361+ size_t decryptedlen = 0 ;
362+ char hash [GIT_SHA1_RAWSZ ];
363+ data = odb_read_object (the_repository -> objects , obj , & type , & datalen );
364+ decrypted = malloc (datalen + 16 );
365+ decryptdata ((const unsigned char * )data , datalen , decrypted , & decryptedlen );
366+ hashdata ((const unsigned char * )decrypted + GIT_SHA1_RAWSZ , decryptedlen - GIT_SHA1_RAWSZ ,
367+ (unsigned char * )hash );
368+ if (memcmp (decrypted , hash , GIT_SHA1_RAWSZ ))
369+ die ("Corrupted encryption data!\n" );
370+ strbuf_add (out , decrypted + GIT_SHA1_RAWSZ , decryptedlen - GIT_SHA1_RAWSZ );
371+ free (data );
372+ free (decrypted );
373+ }
374+
348375unsigned char * hashdata (const unsigned char * input , size_t inputlen ,
349376 unsigned char * output ) {
350377 struct git_hash_ctx c ;
@@ -377,6 +404,7 @@ void initbare(const char* dir) {
377404}
378405
379406struct strbuf template = STRBUF_INIT ;
407+ struct strbuf defaultbranch = STRBUF_INIT ;
380408
381409char * mktemplate (const char * name , const char * email , const char * date , const char * msg ) {
382410 if (!msg )
@@ -427,13 +455,14 @@ void metainit(void) {
427455 struct strbuf keybuf = STRBUF_INIT ;
428456 struct strbuf output_buf = STRBUF_INIT ;
429457 struct string_list recipients = STRING_LIST_INIT_NODUP ;
430- struct strbuf defaultbranch = STRBUF_INIT ;
431458 odb_write_object (the_repository -> objects , ver , strlen (ver ), OBJ_BLOB , & obj_ver );
432459 strbuf_add (& keybuf , keyver , 15 );
433- getrandom (key , 48 , 0 );
460+ if (!getrandom (key , 48 , 0 ))
461+ die ("getrandom failed" );
434462 strbuf_add (& keybuf , key , 48 );
435463 /* This hard coded value needs to be replaced later! */
436464 string_list_append (& recipients , "5A8A11E44AD2A1623B84E5AFC5C0C5C7218D18D7" );
465+ string_list_append (& recipients , "F2AE0B6CB4089F15A217F12D121F59FB963341A4" );
437466 if (encrypt_buffer_gpg (& keybuf , & output_buf , & recipients ) < 0 )
438467 die ("Encryption failed" );
439468 strbuf_release (& keybuf );
@@ -453,6 +482,60 @@ static void secretcommit(struct object_id* tid, struct object_id* oid) {
453482 strbuf_release (& commit );
454483}
455484
485+ void readmeta (void ) {
486+ struct strbuf name = STRBUF_INIT ;
487+ struct strbuf databuf = STRBUF_INIT ;
488+ struct strbuf output_buf = STRBUF_INIT ;
489+ struct strvec gpgkeys = STRVEC_INIT ;
490+ char * data = NULL ;
491+ unsigned long datalen ;
492+ enum object_type type ;
493+ size_t keyverlen = strlen (keyver );
494+ fprintf (stderr , "===== READ =====\n" );
495+ strbuf_addf (& name , "%s1/_:%s" , prefix .buf , "ver" );
496+ repo_get_oid (the_repository , name .buf , & obj_ver );
497+ fprintf (stderr , "ver: %s\n" , oid_to_hex (& obj_ver ));
498+ data = odb_read_object (the_repository -> objects , & obj_ver , & type , & datalen );
499+ if (strlen (ver ) != datalen || memcmp (data , ver , datalen ))
500+ die ("Version format is %s, expected %s\n" , data , ver );
501+ strbuf_release (& name );
502+ free (data );
503+ strbuf_addf (& name , "%s1/_:%s" , prefix .buf , "key" );
504+ repo_get_oid (the_repository , name .buf , & obj_key );
505+ fprintf (stderr , "key: %s\n" , oid_to_hex (& obj_key ));
506+ data = odb_read_object (the_repository -> objects , & obj_key , & type , & datalen );
507+ strbuf_add (& databuf , data , datalen );
508+ if (decrypt_buffer_gpg (& databuf , & output_buf , & gpgkeys ) < 0 )
509+ die ("Decryption of key failed" );
510+ if (strncmp (keyver , output_buf .buf , keyverlen ))
511+ die ("Key format is %s, expected %s\n" , output_buf .buf , keyver );
512+ memcpy (key , output_buf .buf + keyverlen + 1 , 48 );
513+ for (size_t i = 0 ; i < gpgkeys .nr ; i ++ ) {
514+ fprintf (stderr , "Message was encrypted to key: %s\n" , gpgkeys .v [i ]);
515+ }
516+ strbuf_release (& name );
517+ free (data );
518+ strbuf_addf (& name , "%s1/_:%s" , prefix .buf , "sig" );
519+ repo_get_oid (the_repository , name .buf , & obj_sig );
520+ fprintf (stderr , "sig: %s\n" , oid_to_hex (& obj_sig ));
521+ strbuf_release (& name );
522+ strbuf_addf (& name , "%s1/_:%s" , prefix .buf , "msg" );
523+ repo_get_oid (the_repository , name .buf , & obj_msg );
524+ fprintf (stderr , "msg: %s\n" , oid_to_hex (& obj_msg ));
525+ strbuf_release (& template );
526+ decryptobj2strbuf (& obj_msg , & template );
527+ fprintf (stderr , "template: %s\n" , template .buf );
528+ strbuf_release (& name );
529+ strbuf_addf (& name , "%s1/_:%s" , prefix .buf , "def" );
530+ repo_get_oid (the_repository , name .buf , & obj_def );
531+ fprintf (stderr , "def: %s\n" , oid_to_hex (& obj_def ));
532+ strbuf_release (& defaultbranch );
533+ decryptobj2strbuf (& obj_def , & defaultbranch );
534+ fprintf (stderr , "defaultbranch: %s\n" , defaultbranch .buf );
535+ strbuf_release (& name );
536+ fprintf (stderr , "================\n" );
537+ }
538+
456539char * writemeta (char * output ) {
457540 struct object_id oid ;
458541 struct object_id tid ;
@@ -482,7 +565,7 @@ char* writemeta(char* output) {
482565 secretcommit (& tid , & oid );
483566 strbuf_addbuf (& refname , & prefix );
484567 strbuf_addstr (& refname , "1/_" );
485- // refs_update_ref(get_main_ref_store(the_repository), NULL, refname.buf,
568+ //refs_update_ref(get_main_ref_store(the_repository), NULL, refname.buf,
486569 // &oid, NULL, 0, UPDATE_REFS_MSG_ON_ERR);
487570 myupdaterefs (refname .buf , oid_to_hex (& oid ));
488571 strbuf_release (& refname );
@@ -529,6 +612,56 @@ int encrypt_buffer_gpg(struct strbuf *buffer, struct strbuf *output,
529612 return 0 ;
530613}
531614
615+ static int decrypt_buffer_gpg (struct strbuf * buffer , struct strbuf * output ,
616+ struct strvec * key_ids )
617+ {
618+ struct child_process gpg = CHILD_PROCESS_INIT ;
619+ int ret ;
620+ const char * cp ;
621+ struct strbuf gpg_status = STRBUF_INIT ;
622+
623+ strvec_pushl (& gpg .args , "gpg" , "--decrypt" , "--status-fd=2" , "--quiet" , NULL );
624+
625+ sigchain_push (SIGPIPE , SIG_IGN );
626+ ret = pipe_command (& gpg , buffer -> buf , buffer -> len ,
627+ output , 1024 , & gpg_status , 0 );
628+ sigchain_pop (SIGPIPE );
629+
630+ for (cp = gpg_status .buf ;
631+ cp && (cp = strstr (cp , "[GNUPG:] DECRYPTION_OKAY" ));
632+ cp ++ ) {
633+ if (cp == gpg_status .buf || cp [-1 ] == '\n' )
634+ break ;
635+ }
636+
637+ ret |= !cp ;
638+ if (ret ) {
639+ error (_ ("gpg failed to decrypt the data:\n%s" ),
640+ gpg_status .len ? gpg_status .buf : "(no gpg output)" );
641+ strbuf_release (& gpg_status );
642+ return -1 ;
643+ }
644+
645+ for (cp = gpg_status .buf ; cp && * cp ; ) {
646+ const char * next_line = strchr (cp , '\n' );
647+ const char * found ;
648+
649+ if (skip_prefix (cp , "[GNUPG:] ENC_TO " , & found )) {
650+ size_t len = strcspn (found , " \n\r" );
651+ strvec_pushf (key_ids , "%.*s" , (int )len , found );
652+ }
653+
654+ if (next_line )
655+ cp = next_line + 1 ;
656+ else
657+ break ;
658+ }
659+
660+ strbuf_release (& gpg_status );
661+
662+ return 0 ;
663+ }
664+
532665int cmd_main (int argc , const char * * argv ) {
533666 (void )argv ;
534667 (void )argc ;
0 commit comments