6 * Copyright (C) 2008-2015 SIPE Project <http://sipe.sourceforge.net/>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 #include <glib/gprintf.h>
29 #include "sipe-digest.h"
33 * This assumes that the structure is correctly packed on all target
34 * platforms, i.e. sizeof(uuid_t) == 16
36 * See also the test added to "configure". On Windows platform we know
37 * that #pragma pack() exists and therefore can use it in the code.
46 guint16 time_hi_and_version
;
47 guint8 clock_seq_hi_and_reserved
;
55 static void printUUID(uuid_t
*uuid
, char *string
)
59 sprintf(string
, "%08x-%04x-%04x-%02x%02x-", uuid
->time_low
60 , uuid
->time_mid
, uuid
->time_hi_and_version
61 , uuid
->clock_seq_hi_and_reserved
67 pos
+= sprintf(&string
[pos
], "%02x", uuid
->node
[i
]);
71 static void createUUIDfromHash(uuid_t
*uuid
, const unsigned char *hash
)
73 memcpy(uuid
, hash
, sizeof(uuid_t
));
74 uuid
->time_hi_and_version
&= GUINT16_TO_LE(0x0FFF);
75 uuid
->time_hi_and_version
|= GUINT16_TO_LE(0x5000);
76 uuid
->clock_seq_hi_and_reserved
&= 0x3F;
77 uuid
->clock_seq_hi_and_reserved
|= 0x80;
80 char *generateUUIDfromEPID(const gchar
*epid
)
82 #define UUID_STRING_LENGTH 36
83 /* derived from "fcacfb03-8a73-46ef-91b1-e5ebeeaba4fe" */
89 { 0xe5, 0xeb, 0xee, 0xab, 0xa4, 0xfe }
92 guchar digest
[SIPE_DIGEST_SHA1_LENGTH
];
93 guint digest_length
= sizeof(uuid_t
) + strlen(epid
);
94 guint buf_length
= digest_length
;
96 result
.time_low
= GUINT32_FROM_LE(result
.time_low
);
97 result
.time_mid
= GUINT16_FROM_LE(result
.time_mid
);
98 result
.time_hi_and_version
= GUINT16_FROM_LE(result
.time_hi_and_version
);
100 /* buffer must be able to hold at least the UUID string */
101 if (buf_length
< UUID_STRING_LENGTH
)
102 buf_length
= UUID_STRING_LENGTH
;
103 buf
= g_malloc(buf_length
+ 1);
105 memcpy(buf
, &result
, sizeof(uuid_t
));
106 strcpy(buf
+ sizeof(uuid_t
), epid
);
108 sipe_digest_sha1((guchar
*)buf
, digest_length
, digest
);
109 createUUIDfromHash(&result
, digest
);
111 result
.time_low
= GUINT32_TO_LE(result
.time_low
);
112 result
.time_mid
= GUINT16_TO_LE(result
.time_mid
);
113 result
.time_hi_and_version
= GUINT16_TO_LE(result
.time_hi_and_version
);
115 printUUID(&result
, buf
);
120 * Generates epid from user SIP URI, hostname and IP address.
121 * Thus epid will be the same each start and
122 * not needed to be persistent.
124 * Using MAC address proved to be poorly portable solution.
128 char *sipe_get_epid(const char *self_sip_uri
,
129 const char *hostname
,
130 const char *ip_address
)
132 /* 6 last digits of hash */
133 #define SIPE_EPID_HASH_START 14
134 #define SIPE_EPID_HASH_END SIPE_DIGEST_SHA1_LENGTH
135 #define SIPE_EPID_LENGTH (2 * (SIPE_EPID_HASH_END - SIPE_EPID_HASH_START + 1))
138 char out
[SIPE_EPID_LENGTH
+ 1];
139 char *buf
= g_strdup_printf("%s:%s:%s", self_sip_uri
, hostname
, ip_address
);
140 guchar hash
[SIPE_DIGEST_SHA1_LENGTH
];
142 sipe_digest_sha1((guchar
*) buf
, strlen(buf
), hash
);
143 for (i
= SIPE_EPID_HASH_START
, j
= 0;
144 i
< SIPE_EPID_HASH_END
;
146 g_sprintf(&out
[j
], "%02x", hash
[i
]);
148 out
[SIPE_EPID_LENGTH
] = 0;
151 return g_strdup(out
);